POST a Multipart-Encoded File

Requests makes it simple to upload Multipart-encoded files:

  1. >>> url = 'http://httpbin.org/post'
  2. >>> files = {'file': open('report.xls', 'rb')}
  3. >>> r = requests.post(url, files=files)
  4. >>> r.text
  5. {
  6. ...
  7. "files": {
  8. "file": "<censored...binary...data>"
  9. },
  10. ...
  11. }

You can set the filename, content_type and headers explicitly:

  1. >>> url = 'http://httpbin.org/post'
  2. >>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
  3. >>> r = requests.post(url, files=files)
  4. >>> r.text
  5. {
  6. ...
  7. "files": {
  8. "file": "<censored...binary...data>"
  9. },
  10. ...
  11. }

If you want, you can send strings to be received as files:

  1. >>> url = 'http://httpbin.org/post'
  2. >>> files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
  3. >>> r = requests.post(url, files=files)
  4. >>> r.text
  5. {
  6. ...
  7. "files": {
  8. "file": "some,data,to,send\\nanother,row,to,send\\n"
  9. },
  10. ...
  11. }

In the event you are posting a very large file as a multipart/form-data request, you may want to stream the request. By default, requests does not support this, but there is a separate package which does - requests-toolbelt. You should read the toolbelt’s documentation for more details about how to use it.

For sending multiple files in one request refer to the advanced section.

Warning

It is strongly recommended that you open files in binary mode. This is because Requests may attempt to provide the Content-Length header for you, and if it does this value will be set to the number of bytes in the file. Errors may occur if you open the file in text mode.