我想使用Python Requests库从url获取一个文件,并在post请求中将其用作mulitpart编码的文件。问题是文件可能非常大(50MB-2GB),我不想在内存中加载它。(上下文here。)
在文档(multipart、stream down和stream up)中,我想出了这样的例子:
with requests.get(big_file_url, stream=True) as f:
requests.post(upload_url, files={'file': ('filename', f.content)})
但我不确定我做得对。事实上,它抛出的是从回溯中修正的错误:
^{pr2}$有什么建议吗?在
肯尼斯·瑞兹的GitHub repo实际上有一个问题。 我遇到了同样的问题(尽管我只是上传一个本地文件),我添加了一个包装器类,它是与请求的不同部分相对应的流的列表,具有一个read()属性,该属性遍历列表并读取每个部分,还获取头的必要值(边界和内容长度):
因此,不是传递'files'关键字arg,而是将此对象作为'data'属性传递给请求。请求对象
编辑
我已经清理了密码
正如其他答案已经指出的:^{} doesn't support POSTing multipart-encoded files without loading them into memory 。在
要上载大文件而不使用多部分/表单数据将其加载到内存中,可以使用^{} :
它可以调整为允许使用GET response对象而不是本地文件:
^{pr2}$此解决方案要求GET响应中有一个有效的
Content-Length
头(已知文件大小)。如果文件大小未知,则分块传输编码可用于上载多部分/表单数据内容。类似的解决方案可以使用urllib3.filepost
实现,该方案与requests
库一起提供,例如,基于@AdrienF's answer,而不使用poster
。在在python中,您不能将任何需要的内容转换为上下文管理器。它需要非常具体的属性。使用当前代码,可以执行以下操作:
使用
iter_content
将确保文件永远不在内存中。将使用迭代器,否则通过使用content
属性,文件将加载到内存中。在编辑唯一合理的方法是使用chunk-encoded uploads,例如
^{pr2}$如果您绝对需要进行多部分/表单数据编码,那么您必须创建一个抽象层,它将在构造函数中使用生成器,以及来自
response
的Content-Length
报头(为len(file)
提供答案)将具有从生成器读取的read属性。问题再次是,我很确定在上传之前,整个东西都会被读入内存。在编辑2
您可以自己制作一个生成器,自己生成}头。我没有时间画一个例子,但应该不会太难。在
multipart/form-data
编码的数据。您可以通过与分块编码请求相同的方式传递它,但必须确保您设置了自己的Content-Type
和{相关问题 更多 >
编程相关推荐