The reason you're getting JSON is because you're explicitly calling json.dumps to generate a JSON string. Just don't do that, and you won't get a JSON string. In other words, change your first line to this:
data = {'param1': 'value1', 'param2': 'value2'}
As the docs explain, if you pass a dict as the data value, it will be form-encoded, while if you pass a string, it will be sent as-is.
For example, in one terminal window:
$ nc -kl 8765
In another:
$ python3
>>> import requests
>>> d = {'spam': 20, 'eggs': 3}
>>> requests.post("http://localhost:8765", data=d)
^C
>>> import json
>>> j = json.dumps(d)
>>> requests.post("http://localhost:8765", data=j)
^C
In the first terminal, you'll see that the first request body is this (and Content-Type application/x-www-form-urlencoded):
spam=20&eggs=3
… while the second is this (and has no Content-Type):
{"spam": 20, "eggs": 3}
Answer from abarnert on Stack OverflowThe reason you're getting JSON is because you're explicitly calling json.dumps to generate a JSON string. Just don't do that, and you won't get a JSON string. In other words, change your first line to this:
data = {'param1': 'value1', 'param2': 'value2'}
As the docs explain, if you pass a dict as the data value, it will be form-encoded, while if you pass a string, it will be sent as-is.
For example, in one terminal window:
$ nc -kl 8765
In another:
$ python3
>>> import requests
>>> d = {'spam': 20, 'eggs': 3}
>>> requests.post("http://localhost:8765", data=d)
^C
>>> import json
>>> j = json.dumps(d)
>>> requests.post("http://localhost:8765", data=j)
^C
In the first terminal, you'll see that the first request body is this (and Content-Type application/x-www-form-urlencoded):
spam=20&eggs=3
… while the second is this (and has no Content-Type):
{"spam": 20, "eggs": 3}
Short answer with example:
import requests
the_data = {"aaa": 1, "bbb": 2, "ccc": "yeah"}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
# Execute the post
requests.post("http://bla.bla.example.com", data=the_data, headers=headers)
# You have POSTed this HTTP body: aaa=1&bbb=2&ccc=yeah (note, although the content-type is called urlencoded the data is not in the URL but in the http body)
# to this url: "http://bla.bla.example.com"
Requests library does all the JSON to urlencoded string conversion for you
References:
MDN Web docs, Requests lib post url-encoded form
PYTHON: requests.post() how to send request_body encoded as application/x-www-form-urlencoded - Stack Overflow
[Feature] Enhance Handling of x-www-form-urlencoded Data in HTTP Requests
flask - How to send urlencoded parameters in POST request in python - Stack Overflow
"Content-Type header: application/x-www-form-urlencoded" won't be overridden
How do I send form data with Python Requests?
Can I use Python Requests POST with sessions and authentication?
What is the difference between data and json in Python Requests POST?
You don't need to explicitly encode it, simply pass your dict to data argument and it will be encoded automatically.
>>> r = requests.post(URL, data = {'key':'value'})
From the official documentation:
Typically, you want to send some form-encoded data — much like an HTML form. To do this, simply pass a dictionary to the data argument. Your dictionary of data will automatically be form-encoded when the request is made
Set the Content-Type header to application/x-www-form-urlencoded.
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post(URL, data=params, headers=headers)
I'm trying to access data from Yahoo's API and got setup with all the credentials. I'm following their official documentation and am on Step 4 here, but am confused.
This is what I have. I've tried putting together a full URL as well and just doing a requests.post('https://fullurl.com') but that didn't work either.
import requests
consumer_key = credentials.consumer_key
consumer_secret = credentials.consumer_secret
headers = {'content-type': 'application/x-www-form-urlencoded'}
data = {"client_id": consumer_key,
"client_secret": consumer_secret
}
response = requests.post(f"https://api.login.yahoo.com/oauth2/get_token",
headers=headers,
params=data
)
The error I'm getting is: b'{"error":"INVALID_INPUT","error_description":"client id cannot be empty"}' Should I be putting the data or headers as another parameter? Not sure what to try