Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python requests.post multipart/form-data [duplicate]

I have to use a REST API to upload files and information to a server. That API uses a multipart-form, but I cannot seem to be able to use it correctly.

Here is the information I use according to the API documentation.

Form Parameters:

  • description – A short description of the distribution.
  • release_notes_url – A url pointing to the release notes.
  • zip_file – The ZIP file containing the distribution files.

Example request:

POST /api/v1/distribution HTTP/1.1
Host: api.company.onbe
Authorization: t=...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryZayrf7leHxinyQsX


------WebKitFormBoundaryZayrf7leHxinyQsX
Content-Disposition: form-data; name="release_notes_url"
http://releases/3.0.0/release_notes_3_0_0.pdf
------WebKitFormBoundaryZayrf7leHxinyQsX
Content-Disposition: form-data; name="description"
This is the new distribution!
------WebKitFormBoundaryZayrf7leHxinyQsX
Content-Disposition: form-data; name="zip_file"; filename="BackEnd-3.0.0.zip"
Content-Type: application/x-zip-compressed
------WebKitFormBoundaryZayrf7leHxinyQsX--

I tried several things, like the following code for example, but I keep getting bad request errors from the server.

import requests

file= open('BackEnd-3.0.0.zip','r').read()

url = 'api.company.onbe/api/v1/distribution'

payload = {
  'description' :'Some desc',
  'release_notes_url':'Someurl.pdf',
  'zip_file': file
  }

response = requests.post(url, data=payload)
like image 647
Amaranth Avatar asked Oct 29 '15 02:10

Amaranth


Video Answer


1 Answers

The docs have an example http://requests.readthedocs.org/en/latest/user/quickstart/#post-a-multipart-encoded-file

You should really start there for simple use cases.

This answer also explains using files and data together.

https://stackoverflow.com/a/12385661/1182891

Here is a working example for people who want cut-n-paste code. httpbin returns a json data structure describing the request you made do it. In this case you can see that files contains the file data posted and form contains the form vars. headers shows that it was indeed a multipart/form-data request.

>>> import requests
>>> from pprint import pprint
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
>>> response = requests.post(url, data={
...   'description' :'Some desc',
...   'release_notes_url':'Someurl.pdf'
...   }, files=files)
>>> pprint(response.json())
{u'args': {},
 u'data': u'',
 u'files': {u'file': u'some,data,to,send\nanother,row,to,send\n'},
 u'form': {u'description': u'Some desc', u'release_notes_url': u'Someurl.pdf'},
 u'headers': {u'Accept': u'*/*',
              u'Accept-Encoding': u'gzip, deflate',
              u'Content-Length': u'394',
              u'Content-Type': u'multipart/form-data; boundary=ebf9f03029db4c2799ae16b5428b06bd',
              u'Host': u'httpbin.org',
              u'User-Agent': u'python-requests/2.10.0'},
 u'json': None,
 u'origin': u'73.0.41.38',
 u'url': u'http://httpbin.org/post'}

Enjoy!

like image 188
Josh J Avatar answered Sep 19 '22 01:09

Josh J