在没有multipart / form-data的Flask中重新上传文件

时间:2016-04-27 22:08:50

标签: python rest flask multipartform-data

我尝试将二进制文件上传到Flask端点,而不使用任何类型的multipart/form-data。我只想将POSTPUT文件中的数据简单地发送到端点,并将其保存到服务器上的文件中。我能找到的唯一例子,以及其他问题中讨论的唯一方法,使用multipart/form-data

以下"工作",但SHA256哈希通常不匹配,而上传form-data则可以正常工作。

@application.route("/rupload/<filename>", methods=['POST', 'PUT'])
def rupload(filename):
    # Sanity checks and setup skipped.

    filename = secure_filename(filename)
    fileFullPath = os.path.join(UPLOAD_FOLDER, filename)

    with open(fileFullPath, 'wb') as f:
        f.write(request.get_data())

    return jsonify({
        'filename': filename,
        'size': os.path.getsize(fileFullPath)
    })

此外,上述内存效率非常低。有没有办法通过某种类型的缓冲流将其写入输出文件?谢谢!

编辑:这就是我测试它的方式:

curl -v -H 'Content-Type: application/octet-stream' -X POST --data @test.zip https://example.com/test/rupload/test.zip

修改: --data-binary没有任何区别。

2 个答案:

答案 0 :(得分:1)

问题可能是您正在使用的curl命令。手册页推荐--data-binary:“这完全按照指定发布数据,无需任何额外处理。” --data参数是--data-ascii的同义词。可能不需要-X参数,因为它应默认为POST。

curl -v -H 'Content-Type: application/octet-stream' -X POST --data-binary @test.zip https://example.com/test/rupload/test.zip

request.get_data调用还有其他选项可以帮助他们在某处被覆盖。但看起来应该在服务器端工作。禁用缓存功能可能会使您的用例受益。

f.write(request.get_data(cache=False, as_text=False, parse_form_data=False))

如果是服务器端,您可能需要深入了解Werkzeug get_input_stream,这是请求对象的主要内容。

curl命令使用内容类型标头作为'application / octet-stream'是件好事。在这种情况下,Flask似乎没有对此做任何事情,但它可以帮助更广泛地使用代理或其他情况下的数据。

关于有效处理大文件,您可能需要查看request stream property,这是get_data在内部用于从中读取数据的内容。

答案 1 :(得分:1)

您是否尝试过使用hashlib?

import hashlib
...
@application.route("/rupload/<filename>", methods=['POST', 'PUT'])
def rupload(filename):
    # Sanity checks and setup skipped.

    filename = secure_filename(filename)
    fileFullPath = os.path.join(UPLOAD_FOLDER, filename)
    file_hash = hashlib.sha256()
    with open(fileFullPath, 'wb+') as f:
        input = request.get_data()
        f.write(input)
        file_hash.update(input)
        ...
    fileDigest = file_hash.hexdigest()