This question pops up a lot on Stack Overflow, on GitHub, and in the IRC channel, so I thought I’d write a short post to address it. The question is, broadly, this:
How do I send data on a POST? I tried
params
, but that didn’t work!
The answer is that Requests has two different arguments for ‘sending’ data on
a HTTP request: params
and data
. Each one does something different, but in
their simplest form they both accept a dictionary of keys and values.
params
is all about the query string, and so is primarily used on GET
requests. To see it in action, take a look at this chunk of code:
>>> params = {'hi': 'there', 'what': 'ho'}
>>> r = requests.get('http://httpbin.org/get', params=params)
>>> print r.request.url
http://httpbin.org/get?hi=there&what=ho
The key take away here is that the data that was passed to params
ended up in
the URL query string. This is what it’s for. Any string data passed in there
will be correctly escaped and encoded, then added to the URL.
data
works differently: it’s all about the request body. Again:
>>> data = {'hi': 'there', 'what': 'ho'}
>>> r = requests.post('http://httpbin.org/post', data=data)
>>> print r.request.body
what=ho&hi=there
Why are two different parameters used? Why don’t we just have params
set the
request body on a POST, and the query string on anything else? The answer is
that you might want to use a query string and a request body at the same
time. There needs to be a different keyword.
So now you know: params
for query string, data
for request body. Simple.