Home > front end >  Curl issue. JSON.loads() works fine with python-requests, but fails when using curl to the flask API
Curl issue. JSON.loads() works fine with python-requests, but fails when using curl to the flask API

Time:01-03

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:

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?

CodePudding user response:

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.

  • Related