4

I'm creating a stupid endpoint which just logs the posted data.

@app.route("/add_foo", methods=['POST'])
def add_foo():
    logger.debug(request.data)
    print(request.args.get('foo'))
    return "Success"

I then attempt to post data to this endpoint:

>>> import requests
>>> r = requests.post("http://127.0.0.1:8080/add_foo", data={'foo': 'foobar'})

And I see the following output:

 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
2016-07-28 08:59:22,432 - __main__ - DEBUG - b''
None
127.0.0.1 - - [28/Jul/2016 08:59:22] "POST /add_foo HTTP/1.1" 200 -

Interestingly, when I post the data through curl, I see the same thing. Here's my curl command:

curl -XPOST -d "{'foo': 'foobar'}" "http://localhost:8080/add_foo"

What is wrong with the data being posted?

erip
  • 16,374
  • 11
  • 66
  • 121

1 Answers1

5

request.args accesses URL query parameters, parameters in the URL, after a ?. You are POSTing values into the body of the request, so use request.form instead.

From the Request Object section in the Flask Quickstart:

To access form data (data transmitted in a POST or PUT request) you can use the form attribute.

[...]

To access parameters submitted in the URL (?key=value) you can use the args attribute[.]

You could also use the request.values object, which combines the data from the request.args and request.form objects; args is searched before form.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Interesting. `request.data` only captures these query params, as well? – erip Jul 28 '16 at 13:06
  • 1
    @erip: `request.data` is the unparsed raw body. `request.form` is that data parsed out into a dictionary, provided you have a request with the right content-type (`application/x-www-form-urlencoded` or `multipart/form-data`). – Martijn Pieters Jul 28 '16 at 13:08
  • I might expect the raw body to be non-empty, especially if unparsed. I can confirm that using `request.form` worked, but I still find `request.data` to be a bit nebulous. – erip Jul 28 '16 at 13:09
  • 1
    @erip: from the [Werkzeug `BaseRequest` class documentation](http://werkzeug.pocoo.org/docs/0.11/wrappers/#werkzeug.wrappers.BaseRequest.get_data): *Note that if the form data was already parsed this method will not return anything as form data parsing does not cache the data like this method does.* – Martijn Pieters Jul 28 '16 at 13:11
  • 2
    @erip: for efficiency sake form data parsing doesn't keep the request body around because it could potentially be very large indeed (think file uploads). – Martijn Pieters Jul 28 '16 at 13:12
  • Ah, this makes sense. :) Excellent explanation. Will accept soon. – erip Jul 28 '16 at 13:13
  • Thank you, thank you, thank you! I am relatively new to working with requests and responses and it wouldn't have occurred to me to look for `form`. Now getting the data I expected (an hour ago). – allardbrain Feb 23 '18 at 01:47