Python Requests Multipart HTTP POST

前端 未结 3 391
抹茶落季
抹茶落季 2021-01-03 05:32

I was wondering how do you translate something like this using Python Requests? In urllib2, you can manually manipulate the data that is being sent over the wire to the API

相关标签:
3条回答
  • 2021-01-03 06:09

    with requests, I believe that you don't have to be so manual, simply:

    import requests
    
    # ...
    url = self._resolve_url('/a/creative/uploadcreative')
    files = {'file': ('userfile', open(filepath, 'rb'))}
    data = {'account_id': account_id}
    headers = {'content-type': 'multipart/form-data'}
    res = requests.post(url, files=files, data=data, headers=headers)
    return res.json
    

    I suppose your concern lies with your:

    parts.append('Content-Type: %s' % mimetypes.guess_type(file_path)[0] or 'application/octet-stream')
    

    I haven't proven it to myself beyond the shadow of a doubt. But, I think that is built in to requests here.

    Edit: It looks like you can have the normal fields in the files dict, as you propose:

    files = {'file': open('image.jpg', 'rb'), 'account_id': 12345}
    

    and could name the filename as you want:

    files = {'file': ('userfile', open('image.jpg', 'rb')), 'account_id': 12345}
    

    but, you would get a body.write(b'Content-Type: text/plain\r\n\r\n') on the account_id field which is probably not what you want and have no way to customize the Content-Disposition for each field (still not sure why you would need to); for both the file and the field you will get: Content-Disposition: form-data - which is what you show for both.

    I'm not sure that you can do exactly what you want with requests, maybe you should try a feature request.

    0 讨论(0)
  • 2021-01-03 06:15

    I found out that in the python-requests library (v.0.13.3), your data will get wiped if you include the "data" field before the "files" field in the request call itself.

    For example,

    requests.post(url, headers=headers, data=data, files=files) 
    

    will yield empty form-data. However, the following will send the data dictionary as form-data

    requests.post(url, headers=headers, files=files, data=data)
    

    Thanks everyone for their answers

    0 讨论(0)
  • 2021-01-03 06:18
     import requests
    
     import urllib
    
     def upload_creative(self, account_id, file_path):
    
        files = [('userfile', (file_path, open(file_path, 'rb'), "image/jpeg" ))]
    
        url = self._resolve_url('/a/creative/uploadcreative')
    
        url =  url + "?"  +  urlib.urlencode(account_id=account_id)
    
        reuests.post(url, files=files)
    
    0 讨论(0)
提交回复
热议问题