Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Python Requests to send file and JSON in single request

I'm trying to POST to an API (Build using SlimPHP) which accepts an image along with additional image meta data in the form of JSON.

I've verified the API works correctly using a REST client tool and can successfully POST to the service. All data is stored correctly.

I'm now trying to POST using Python - however my JSON data doesn't appear to be saving.

My code:

    data = {'key1': 'value1', 'key2': 'value2'}
    url = 'http://mydomain.com/api/endpoint'
    headers = {'Authorization': 'my-api-key'}
    files = {'file': (FILE, open(PATH, 'rb'), 'image/jpg', {'Expires': '0'})}
    r = requests.post(url, files=files, headers=headers, data=data)

--

I've attempted to set additional headers,

ie:/

headers = {'Authorization': 'unique-auth-key', 'Content-type': 'multipart/form-data'}

or

headers = {'Authorization': 'unique-auth-key', 'Content-type': 'application/json'}

These result in a 500 error.


UPDATE 14/07/2014:

Using a chrome extension (Advanced Rest Client) my POST is successful - here's what the console shows as the payload:

------WebKitFormBoundarysBpiwrA3hnGPUbMA
Content-Disposition: form-data; name="data"
test
------WebKitFormBoundarysBpiwrA3hnGPUbMA
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg
------WebKitFormBoundarysBpiwrA3hnGPUbMA--

I'm not quite sure what this signifies...

like image 920
Simon Avatar asked Jul 08 '14 21:07

Simon


1 Answers

Your problem is that you are using the image metadata as the source of key/value pairs to be posted. Instead of sending it as the value of one of those key/value pairs.

The following code will send a request much like the curl statement you provided:

url = 'my-url.com/api/endpoint'
headers = {'Authorization': 'my-api-key'}
image_metadata = {'key1': 'value1', 'key2': 'value2'}
data = {'name': 'image.jpg', 'data': json.dumps(image_metadata)}
files = {'file': (FILE, open(PATH, 'rb'), 'image/jpg', {'Expires': '0'})}
r = requests.post(url, files=files, headers=headers, data=data)
like image 106
Jeremy Allen Avatar answered Oct 14 '22 16:10

Jeremy Allen