【问题标题】:How to stream a file in a request?如何在请求中流式传输文件?
【发布时间】:2020-07-08 23:28:50
【问题描述】:

我们有一个react 应用程序与 django 后端通信。每当react 应用程序想要将文件上传到后端时,我们都会发送一个表单请求,其中一个字段是正在上传的文件的句柄。该字段在 Django 端作为 InMemoryUploadedFile,这是一个带有一些chunks的对象,例如可以这样处理:

def save_uploaded_file(uploaded_file, handle):
    """
    Saves the uploaded file using the given file handle.
    We walk the chunks to avoid reading the whole file in memory
    """
    for chunk in uploaded_file.chunks():
        handle.write(chunk)
    handle.flush()
    logger.debug(f'Saved file {uploaded_file.name} with length {uploaded_file.size}')

现在,我正在使用 requests 创建一些测试框架来驱动我们的 API。我试图模拟这种机制,但奇怪的是,requests 坚持在发送请求之前从打开的句柄中读取。我在做:

requests.post(url, data, headers=headers, **kwargs)

与:

data = {'content': open('myfile', 'rb'), ...}

请注意,我不是从文件中读取,我只是在打开它。但是requests坚持要从中读取,并发送嵌入的数据,这有几个问题:

  • 可能很大
  • 由于是二进制数据,它会破坏请求
  • 这不是我的应用程序所期望的

我不希望这样:我希望requests 只是“流式传输”该文件,而不是读取它。有一个 files 参数,但这将创建一个包含嵌入在请求中的文件的多部分,这又不是我想要的。我希望数据中的所有字段都在请求中传递,并且内容字段要流式传输。我知道这是可能的,因为:

  • 浏览器会这样做
  • 邮递员做到了
  • django 测试客户端会这样做

如何强制请求流式传输数据中的特定文件?

【问题讨论】:

标签: python django stream python-requests


【解决方案1】:

可能,这不再相关,但我将分享我在documentation 中找到的一些信息。

默认情况下,如果上传的文件小于 2.5 兆字节,Django 将上传的全部内容保存在内存中。这意味着 保存文件只涉及从内存读取和写入磁盘 因此非常快。但是,如果上传的文件太大, Django 会将上传的文件写入存储在您的临时文件中 系统的临时目录。

这样,就不需要创建流式文件上传了。相反,解决方案可能是使用缓冲区处理(读取)加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    相关资源
    最近更新 更多