Short answer
This is because params sends the parameters as part of the http POST request, while data sends them as part of the body of the request. In your case: just call the api using params and you're fine. This is absolutely normal (and expected) behaviour.
Demonstration
Just start two commandlines. On the first, run netcat: nc -l 8888. On the other commandline, run python:
>>> import requests
>>> requests.post('http://localhost:8888',data={'a':1,'b':'2'})
At the netcat-side, we see the following request:
POST / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.18.1
Content-Length: 7
Content-Type: application/x-www-form-urlencoded
a=1&b=2
Next, try the params way:
>>> requests.post('http://localhost:8888',params={'a':1,'b':'2'})
Netcat reports:
POST /?a=1&b=2 HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.18.1
Content-Length: 0
Note the differences in the first and last line.
As you can read from the documentation (italic emphasis is mine):
Answer from agtoever on Stack Overflowparams -- (optional) Dictionary or bytes to be sent in the query string for the Request.
data -- (optional) Dictionary or list of tuples [(key, value)] (will be form-encoded), bytes, or file-like object to send in the body of the Request.
Making HTTP POST request using requests in Python - Stack Overflow
Python request (post)
Python Requests POST doing a GET? - Stack Overflow
Post request not work
Does the Python requests library support asynchronous POST requests?
Unfortunately, the requests library does not support asynchronous requests. However, the httpx library is an alternative that provides async capabilities, making it suitable for applications requiring concurrency. See our guide to Python httpx for details.
How can I include custom headers in using Python requests?
Pass headers as a dictionary using the headers parameter. Note that requests automatically generates some headers like User-Agent, Content-Length and Content-Type, so be cautious when overriding them.
What is the difference between data and json parameters in Python requests?
data is for form-encoded (default) or raw data (when Content-Type header is overriden). While json is specifically for JSON format data and automatically sets Content-Type to application/json.
Videos
How do you do post and pre requests in Python?
I think in Postman, Insomnia - the only language supported is Javascript.
And there should be support for more languages like Go, Java.
» pip install requests
To be clear, whenever requests receives a redirect (with a certain status code) we have to perform certain transformations on the request.
In cases like this, when you see something very unexpected the best debugging tips are to retry your request but with allow_redirects=False. This will immediately return the 30x response. Alternatively, you can also check r.history to see if there are any 30x responses that were followed. In this case you probably would have seen something like
Copy>>> r.request.method
'GET'
>>> r.history
[<Response [302]>,]
>>> r.history[0].request.method
'POST'
We know that doing this can cause unexpected behaviour for users (as it just did to you) but it's the only correct way to operate on the web.
I hope this helps you understand why this happened beyond the fact that it was a redirect, and hopefully it gives you and others tools to debug this in the future.
The problem was the RESTful API was redirecting me from http:// to https://, which caused the library to return the "second" request (GET)...