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
Urlencoded sending a JSON string
[Feature] Enhance Handling of x-www-form-urlencoded Data in HTTP Requests
Python : Trying to POST form using requests - Stack Overflow
PYTHON: requests.post() how to send request_body encoded as application/x-www-form-urlencoded - Stack Overflow
How do I send form data with Python Requests?
What is the difference between data and json in Python Requests POST?
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.
You can use the Session object
import requests
headers = {'User-Agent': 'Mozilla/5.0'}
payload = {'username':'niceusername','password':'123456'}
session = requests.Session()
session.post('https://admin.example.com/login.php',headers=headers,data=payload)
# the session instance holds the cookie. So use it to get/post later.
# e.g. session.get('https://example.com/profile')
Send a POST request with content type = 'form-data':
import requests
files = {
'username': (None, 'myusername'),
'password': (None, 'mypassword'),
}
response = requests.post('https://example.com/abc', files=files)
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
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)