我想用以下命令将文件卷曲POST到烧瓶应用程序中:
curl -X POST http://url_of_lambda_function.com -F 'file=@/path/to/file.pdf'
flask应用程序具有通过子流程运行的pdftotext可执行文件。通常,这需要几个参数…
result = subprocess.call([pdftotext, "-layout", file, "-"])
其中,pdftotext是可执行文件的路径,"-layout"是一个选项,file是pdf的路径("/path/to/file.pdf"),"-"是输出(在这种情况下,将其转储到屏幕)。
我的问题:
在我的flask应用程序中,我没有上述文件的文件路径。相反,我用这个来处理传入的文件:
data = request.files['file']
file = data.read()
数据是一个werkzeug文件对象,文件属于"字节"类。Pdftotext接受字符串、字节或os。类路径对象。
输入文件而不是"/path/to/file.pdf"会出现错误:
ValueError: embedded null byte
将文件转换为字符串并输入会出现另一个错误:
OSError: [Errno 7] Argument list too long: 'pdftotext'
我曾尝试将其包装为BytesIO对象、StringIO对象和IOTextWrapper,但遇到了错误:
TypeError: expected str, bytes or os.PathLike object
所以我有点困了!这让我只能给它一个文件路径,而通过curl发送文件时我没有这个路径!
想法:
- 我可以将文件下载到临时存储器并传入路径。这是有效的,但会减慢功能,所以如果可能的话,宁愿避免这种情况
- 有没有其他类型的包装器,我使用模仿操作系统。PathLike对象或转换生成临时路径
非常感谢您的帮助!
已解决
感谢Dan D.在对问题的评论中建议使用NamedTemporaryFile()。
tmpfile = tempfile.NamedTemporaryFile()
tmpfile.write(file)
result = subprocess.call([pdftotext, "-layout", tmpfile.name, "-"])
更改为subprocess.run也有一些用处,可以将输出保存在变量中,如下所示:
result = subprocess.run(['pdftotext',tmpfile.name,'-'],stdout=PIPE,stderr=PIPE)
text = result.stdout