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.