4

I'm trying to upload a picture to a python-eve server using the requests library. In order to do that, I send a multipart/form-data request. This seems to be a problem for my schema, which looks like this:

schema = {
    'name': {
        'type': 'string',
        'required': True
    },
    'description': {
        'type': 'string'
    },
    'picture': {
        'type': 'media'
    },
     'properties': {
         'type' : 'dict'
     }
}

The request looks like this:

import requests

file = open('/home/user/Desktop/1500x500.jpeg', 'rb')
payload = {'name': 'hello', 'properties': {'status': 'on_hold'}}
r = requests.post("http://localhost:5001/node", data=payload, files={'picture': file})

What I get is a ResourceInvalid exception:

ResourceInvalid: Failed. Response status: 422. Response message: UNPROCESSABLE ENTITY. Error message: {"_status": "ERR", "_issues": {"properties": "must be of dict type"}, "_error": {"message": "Insertion failure: 1 document(s) contain(s) error(s)", "code": 422}}

Is there any solution for this? Am I missing something about the request format?

fsiddi
  • 101
  • 6

2 Answers2

4

Something like this should work just fine:

import requests

file = open('/home/user/Desktop/1500x500.jpeg', 'rb')
payload = {'name': 'hello'}

r = requests.post("http://localhost:5001/node", data=payload, files={'picture': file})
Nicola Iarocci
  • 6,606
  • 1
  • 20
  • 33
  • That works, but what is failing is: payload = {'name': 'hello', 'properties': {'prop1': 'value', 'prop2': 'other'}} r = requests.post("http://localhost:5001/node", data=payload, files={'picture': file}) Values that are dictionaries. – fsiddi Apr 13 '15 at 12:45
  • What is the definition for the `properties` field? – Nicola Iarocci Apr 13 '15 at 12:50
  • In the schema is simply a type 'dict'. I'm not enforcing any content/validation at the moment. – fsiddi Apr 13 '15 at 12:53
  • hmm make sure that you set `allow_unknown` property for the endpoint then. If you are using Cerberus 0.8.2 you can optionally set `allow_unknown` just for the field. HTH. – Nicola Iarocci Apr 13 '15 at 13:47
3

I have just had a similar issue. I suggest you try to change your code this way: dump your dictionary into a json object, and add an header to describe the content you are sending.

import requests
import json

file = open('/home/user/Desktop/1500x500.jpeg', 'rb')
payload = {'name': 'hello', 'properties': {'status': 'on_hold'}}
headers = {'Content-type': 'application/json; charset=utf-8'}
r = requests.post("http://localhost:5001/node", data=json.dumps(payload), files={'picture': file}, headers=headers)
  • Yes that's most likely the issue. Thanks. – Nicola Iarocci Apr 14 '15 at 08:49
  • Thanks for the suggestion! Does this code work for you? From what I've been reading, you can't send file objects (binary data) when doing a request with application/json Content-type. The only way would be to base64 encode the file and send it that way, but this confuses Eve. Please let me know if you managed to get that code run, because for me it fails. – fsiddi Apr 14 '15 at 09:56