user2646237
user2646237

Reputation: 21

Making HTTP POST request using requests in Python

I am trying to make a HTTP request to an API using the POST method. The API that I am using is meant to take in three parameters (key1, key2, key3) and return a json file. Unfortunately, my POST request does not seem to return anything when I am using the data method to pass my dictionary to the API. This seems to be very strange because it seems to work when I am using the params method. I cannot try to understand this as this process seems to be very opaque (e.g. I cannot a URL to see how the payload are passed onto the API).

My question: What am I doing wrong here?

POST request where the parameters are sent over to the API using data method:

import requests

url = 'http://example.com/API.php'
payload =  {
            'key1': '<<Contains very long json string>>', 
            'key2': 5, 
            'key3': 0
           }

print len(str(payload)) # Prints 6717
r = requests.post(url, data=payload) << Note data is used here
print r.status_code # Prints 200
print r.text # Prints empty string

POST request code where the parameters are sent over to the API using the params method:

import requests

url = 'http://example.com/API.php'
payload =  {
            'key1': '<<Contains very long json string>>', 
            'key2': 5, 
            'key3': 0
           }

print len(str(payload)) # Prints 6717
r = requests.post(url, params=payload) << Note here params is used here
print r.status_code # Prints 200
print r.text # Prints expected JSON results

If you are wondering why I would like to use the data method over params... I am trying to pass other dictionaries containing longer strings and the params method does not seem to do it because I am getting ERROR 414. I was hoping that the error could be resolved by using data.

The API that I am using was written in PHP.

Upvotes: 1

Views: 16660

Answers (1)

agtoever
agtoever

Reputation: 1699

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):

params -- (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.

Upvotes: 1

Related Questions