【问题标题】:python requests: post and big contentpython请求:发布和大内容
【发布时间】:2014-04-07 14:27:21
【问题描述】:

我正在使用 POST 请求将 CSV 文件发送到服务器。

我正在使用requests.post 的类文件对象

如果 CSV 文件很大并且我的内存有限,或者我使用类似文件的对象永远不会将整个文件加载到内存中,是否会出现问题?我不确定。

我知道有流选项,但听起来它更多的是用于获取响应而不是发送数据。

headers = {
    'content-type': 'text/csv',
}
csvfile = '/path/file.csv'
with open(csvfile) as f:
    r = requests.post(url, data=f, headers=headers)

【问题讨论】:

    标签: python python-requests


    【解决方案1】:

    使用打开的文件对象作为data 参数可确保requests 将为您流式传输数据。

    如果可以确定文件大小(通过 OS 文件系统),则文件对象将使用 8kb 缓冲区进行流式传输。如果无法确定文件大小,则会发送Transfer-Encoding: chunked 请求,改为发送每行数据(该对象用作可迭代对象)。

    另一方面,如果您将 files= 参数用于多部分 POST,则文件将在发送之前加载到内存中。使用requests-toolbelt package 流式传输分段上传:

    import requests
    from requests_toolbelt.multipart.encoder import MultipartEncoder
    
    csvfile = '/path/file.csv'
    with open(csvfile) as f:
        m = MultipartEncoder(fields={'csv_field_name': ('file.csv', f, 'text/csv')})
        headers = {'Content-Type': m.content_type}
        r = requests.post(url, data=m, headers=headers)
    

    【讨论】:

    • 哦,好吧,所以我这样做的方式已经避免将整个文件加载到内存中。谢谢。
    • @jgstew 缓冲区大小由 urllib3 设置;您必须创建一个 custom HTTP adapter 来为池管理器提供不同的缓冲区大小。
    • @jgstew 我会覆盖 HTTPAdapter.init_poolmanager() 以将 blocksize=… 添加到关键字参数中。
    • @jgstew:是的,但是池管理器在创建连接时会传递blocksize 参数。
    • @jgstew:见Pool Manager docs附加参数用于创建新的urllib3.connectionpool.ConnectionPool实例)和Connection Pool docs附加参数用于创建新的urllib3.connection.HTTPConnectionurllib3.connection.HTTPSConnection 实例)
    【解决方案2】:

    这不会将整个文件加载到内存中,它会被分成块并一次传输一点。你可以在源代码here中看到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多