将HTTP PUT请求的数据存储到文件的有效且简短的方法是什么?

时间:2018-01-31 07:23:25

标签: python flask

在我的Flask应用程序中,路由通过HTTP PUT接受文件上传。由于这些文件将由外部工具处理,我需要将它们保存到磁盘。由于文件可能变得更大(几百MB),我避免使用request.get_data(),而是使用request.stream使用常量内存将传入数据写入磁盘:

现在我做

from tempfile import NamedTemporaryFile
from flask import send_file

# ...

@app.route('/<path>', methods=['PUT'])
def handle_upload(path):
    try:
        with NamedTemporaryFile(delete=False) as tmpFile:
            while True:
                chunk = request.stream.read(16384)
                if not chunk:
                    break
                tmpFile.write(chunk)
        processFile(tmpFile.name) # This calls out to an external tool
        return send_file(tmpFile.name)
    finally:
        os.remove(tmpFile.name)

然而,看到Flask提供了诸如send_file之类的便利方法,我想知道:Flask或Werkzeug是否可以提供现成的功能来将请求的数据流式传输到文件中,这比手工短 - 书面循环?我怀疑我可能会忽略API文档中的某些内容。

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,但是发现了一个更好的alternative:以与POST上传相同的方式进行处理,并将流转换为werkzeug.FileStorage

incoming = FileStorage(request.stream)
with NamedTemporaryFile(delete=False) as tmpFile:
    incoming.save(tmpFile)

请注意save的描述:

  

将文件保存到目标路径或文件对象。如果目标是文件对象,则必须在调用后自行关闭它。缓冲区大小是复制过程中保存在内存中的字节数。默认为16KB。

答案 1 :(得分:0)

在研究了更多人并与不同的人交谈之后,在我看来,在块中读取request.stream将PUT请求的数据保存到文件的最佳方式,即

for chunk in iter(lambda: request.stream.read(16384), bytes()):
    f.write(chunk)