Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Curl issue. JSON.loads() works fine with python-requests, but fails when using curl to the flask API. Changes all double quotes to single

TypeError: the JSON object must be str, bytes or bytearray, not ‘dict’

I have a flask server that is running:

@app.route('/getMyData', methods=['GET'])
def getMyData(): 
  data = json.loads(request.get_json())  # get JSON string and load to python dict
  # TYPE ERROR OCCURS HERE

I use a python script to send:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

PARAMS = {"files": ["file1", "file2", "file3", "file4"], "date": [["2000-06-01", "2001-08-01"], ["2005-11-01", "2006-01-01"]], "data": ["data1", "data2", "data3"]}

PARAMS_JSON = json.dumps(PARAMS)  # dict to JSON
r = requests.get(url=URL, json=PARAMS_JSON)

No issues. json.loads on the flask server parses it fine.

I try to create an example for those not using python with a simple curl command. I send:

curl http://127.0.0.1:5000/getMyData -X GET -d '{"files": ["file1", "file2", "file3", "file4"], "date": [["2000-06-01", "2001-08-01"], ["2005-11-01", "2006-01-01"]], "data": ["data1", "data2", "data3"]}' -H 'Content-Type:application/json'

This throws the type error.

Troubleshooting: I print request.get_json() on the flask server to see what is going on.

When I use the python script (That works) request.json() prints:

{"files": ["file1", "file2", "file3", "file4"], "date": [["2000-06-01", "2001-08-01"], ["2005-11-01", "2006-01-01"]], "data": ["data1", "data2", "data3"]}

When I use the curl command request.json() prints:

{'files': ['file1', 'file2', 'file3', 'file4'], 'date': [['2000-06-01', '2020-08-01'], ['2005-11-01', '2006-01-01']], 'data': ['data1', 'data2', 'data3']}

As you can see. Curl seems to be changing all my double quotes to single quotes, which isn’t a JSON string. Why? Why does curl torment me so?

>Solution :

PARAMS_JSON = json.dumps(PARAMS)  # dict to JSON
r = requests.get(url=URL, json=PARAMS_JSON)

json.dumps here produces a JSON string. The json= parameter of requests is meant to accept a value, which it will then encode to a JSON string, so you don’t have to do it yourself before. So your data gets double-encoded here, and you’re sending a JSON string containing a JSON string.

When you decode this server-side, what you get is a string containing JSON formatted data. That’s why it shows up in JSON format, with double quotes.

The way you’re sending it from curl sends proper once-encoded JSON, which is decoded exactly once to a Python dict, and then prints in Python format.

json.loads(request.get_json()) 

Same thing in reverse here. get_json already decodes from JSON, and you’re then JSON-decoding that result again.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading