Here's the flask code:
from flask import Flask, request
import json
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def refresh():
params = {
'thing1': request.values.get('thing1'),
'thing2': request.values.get('thing2')
}
return json.dumps(params)
Here's the cURL
:
$ curl -XGET 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'
> {"thing1": "1", "thing2": null}
$ curl -XGET 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'
> {"thing1": "1", "thing2": null}
The docs seem VERY clear that this should be working:
form
A MultiDict with the parsed form data from POST or PUT requests. Please keep in mind that file uploads will not end up here, but instead in the files attribute.
args
A MultiDict with the parsed contents of the query string. (The part in the URL after the question mark).
values
A CombinedMultiDict with the contents of both form and args.
Any ideas what I'm doing wrong?
Update: Trying suggestions from one of the answers, swapping out the return
line:
Using return json.dumps(json.load(request.body.decode("utf-8") ))
generates the error AttributeError: 'Request' object has no attribute 'body'
Using return json.dumps(json.load(request.json))
generates the error AttributeError: 'NoneType' object has no attribute 'read'
Using POST
with the origin code appears to have no effect:
$ curl -XPOST 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'
{"thing1": "1", "thing2": null}
Setting the content type and using POST
with the original code also has no apparent effect:
$ curl -XPOST -H "Content-Type: application/json" 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'
{"thing1": "1", "thing2": null}
although I went and verified that the content-type was then correctly set:
...
print(request.headers)
...
Host: 127.0.0.1:5000
User-Agent: curl/7.54.0
Accept: */*
Content-Type: application/json
Content-Length: 12
You're inadvertently sending the wrong Content Type.
By default, curl
's -d
flag will send POST data with content-type application/x-www-form-urlencoded
. Since you're not sending data in the format that it's expecting (key=value), it's dropping the data altogether. For JSON data, you'll need to send the HTTP request with the content-type set to application/json
like so:
curl -XPOST -H "Content-Type: application/json" 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'
Also, flask's request.form
field only contains POST form data, not other content types. You can access the raw POST request body with request.data
or, more convenienty, the parsed JSON data using request.get_json
.
Below is a fixed version of your example:
from flask import Flask, request
import json
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def refresh():
params = {
'thing1': request.values.get('thing1'),
'thing2': request.get_json().get('thing2')
}
return json.dumps(params)
app.run()
UPDATE: I misspoke earlier - request.body
should actually be request.data
. Also as it turns out request.json
is deprecated and request.get_json
should be used now instead. The original post has been updated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With