简体   繁体   中英

Python using Requests to cURL a file upload

I am trying to translate a specific curl method into Python's requests module to upload a file to to an api. My standard method that works for non-file requests looks like this:

import requests

requestObject = requests.Session()
standard_headers = {header1:headerValue1,header2:headerValue2}
payload = {key1:value1,key2:value2}
url = 'https://myUrl.com/apiCall'

requestObject.post(url,headers=standard_headers, json=payload)

This works for non-file requests that I need to make to the API. However for file uploads, the API documentation shows a method using curl:

curl -XPOST -H 'header1' -H 'header2 'https://myUrl.com/apiCall' \
  -F 'attachment=@/path/to/my/file' \
  -F '_json=<-;type=application/json' << _EOF_
  {
    "key1":"keyValue1",
    "key2":"keyValue2"
  }
_EOF_

I tested the curl command and it works successfully.

My question is how do I translate that curl method using the << _EOF_ method in Python requests. One idea I had was simply to use the 'files' option in the requests module:

requestObject = requests.Session()
standard_headers = {header1:headerValue1,header2:headerValue2}
payload = {key1:keyValue1,key2:keyValue2}
url = 'https://myUrl.com/apiCall'
file_to_upload = {'filename': open('/path/to/my/file', 'rb')}

requestObject.post(url,headers=standard_headers, files=file_to_upload, json=payload)

But that does not seem to work as the necessary json parameters (the values in payload ) do not appear to get passed to the file upload

I also tried specifying the json parameters directly into the file_to_upload variable:

requestObject = requests.Session()
standard_headers = {header1:headerValue1,header2:headerValue2}
url = 'https://myUrl.com/apiCall'
file_to_upload = {'attachment': open('/path/to/my/file', 'rb'),'{"key1":"keyValue1","key2":"keyValue2"}'}

requestObject.post(url,headers=standard_headers, files=file_to_upload)

Similar result, it seems as though I am not passing the necessary json values correctly. I tried a few other ways but I am overlooking something. Any insight into how I should structure my request is appreciated.

Ok I managed to get it to work and posting for anyone who might need help in the future.

The trick was to include the _json key in the data field. My code ended up looking like so:

import requests

requestObject = requests.Session()
standard_headers = {header1:headerValue1,header2:headerValue2}
json_fields = json.dumps({ 
                           "key1": "key1Value",
                           "key2": "key2Value"                                              
                         })
payload = {"_json":json_fields)
file = {"attachment": /path/to/my/file} 
url = 'https://myUrl.com/apiCall'

requestObject.post(url,headers=standard_headers, files=file, data=payload)

Hope that helps some future person.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM