Uso de solicitudes de Python para enviar archivos y JSON en una sola solicitud

Estoy tratando de POST a una API (Construir usando SlimPHP) que acepta una imagen junto con metadatos de imagen adicionales en forma de JSON.

He verificado que la API funciona correctamente con una herramienta de cliente REST y puedo enviar correctamente al servicio. Todos los datos se almacenan correctamente.

Ahora estoy intentando POST usando Python, sin embargo, parece que mis datos JSON no se están guardando.

Mi código:

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) 

He intentado establecer encabezados adicionales,

es decir:/

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

o

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

Esto resulta en un error 500.


ACTUALIZACIÓN 14/07/2014:

Al usar una extensión de Chrome (Advanced Rest Client) mi POST es exitosa, esto es lo que la consola muestra como la carga útil:

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

No estoy muy seguro de lo que esto significa …

Su problema es que está utilizando los metadatos de la imagen como la fuente de los pares clave / valor que se publicarán. En lugar de enviarlo como el valor de uno de esos pares clave / valor.

El siguiente código enviará una solicitud muy similar a la statement de curl que proporcionó:

 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)