Python requests 上传文件, 并获取上传进度
最新在使用PyQt5开发时有个上传大文件的需求, 在查阅Requests 官网进阶手册 Advanced Usage — Requests 2.18.4 documentation 中只有上传文件的几种方法介绍, 并没有提到上传进度获取.
后来发现有个基于Requests的扩展库requests_toolbelt可以实现上传进度的获取 :
Uploading Data — requests_toolbelt 0.8.0 documentation
详细参见原文手册, 以下是我的使用总结:
上传数据
Streaming Multipart Data Encoder
Requests 本身是支持 multipart uploads的, 但是从API上看想要构造一个灵活的 multipart upload是非常困难或不可能的. 另外, 当使用Requests的multipart upload功能时会加载所有的数据到内存中, 这导致在极端情况下有可能只发送了一部分文件到服务器.
toolbelt 包含了一个可以建立完全自定义的multipart请求体, 并且避免了读取文件到内存当中, 如:
1 | import requests |
MultipartEncoder的方法.to_string()非常便捷, 它将multipar body转换成为string. 这个方法在开发的时候还是非常有用的, 它可以让你确切的看到你将要发送的数据格式.
MultipartEncoder 是最常用的接口, 它会为你创建一个 multipart/form-data请求体.
基础用法如下:
1 | import requests |
注意!: 此对象在httplib中结束. 而当前的httplib是使用硬编码来读取8192bytes. 这意味着这个操作将会一直循环读取, 上传将会消耗一部分时间.
监听你的分段流式上传
如果你是在使用一个分段的上传, 那说明你的任务将会需要执行一会, 这个时候我们需要监听上传的进度.
接下来讲一下监听上传进度.
toolbelt提供两个模块MultipartEncoder, MultipartEncoderMonitor, 有以下一些相关信息:
- Monitor接收一个回调参数
callback, 回调参数在requests每次调用read的时候调用, 并且传递当前monitor作为参数. - Monitor追踪上传过程中已经加载了多少bytes.
所以, 可以使用Monitor来实现上传进度的监听.
实例代码如下:
1 | import requests |
另外, MultipartEncoder 主要的责任应该只用于准备和流式化数据, 它不应被用于管理.