Python Request Post with param data
params
is for GET-style URL parameters, data
is for POST-style body information. It is perfectly legal to provide both types of information in a request, and your request does so too, but you encoded the URL parameters into the URL already.
Your raw post contains JSON data though. requests
can handle JSON encoding for you, and it'll set the correct Content-Type
header too; all you need to do is pass in the Python object to be encoded as JSON into the json
keyword argument.
You could split out the URL parameters as well:
params = {'sessionKey': '9ebbd0b25760557393a43064a92bae539d962103', 'format': 'xml', 'platformId': 1}
then post your data with:
import requests
url = 'http://192.168.3.45:8080/api/v2/event/log'
data = {"eventType": "AAS_PORTAL_START", "data": {"uid": "hfe3hf45huf33545", "aid": "1", "vid": "1"}}
params = {'sessionKey': '9ebbd0b25760557393a43064a92bae539d962103', 'format': 'xml', 'platformId': 1}
requests.post(url, params=params, json=data)
The json
keyword is new in requests
version 2.4.2; if you still have to use an older version, encode the JSON manually using the json
module and post the encoded result as the data
key; you will have to explicitly set the Content-Type header in that case:
import requests
import json
headers = {'content-type': 'application/json'}
url = 'http://192.168.3.45:8080/api/v2/event/log'
data = {"eventType": "AAS_PORTAL_START", "data": {"uid": "hfe3hf45huf33545", "aid": "1", "vid": "1"}}
params = {'sessionKey': '9ebbd0b25760557393a43064a92bae539d962103', 'format': 'xml', 'platformId': 1}
requests.post(url, params=params, data=json.dumps(data), headers=headers)
How to pass variable into post request in Python
If you want to pass json data to your API, you can directly use the json attribute of the request.post()
function with a dictionary variable.
Example:
# importing the requests library
import requests
headers = {
'PRIVATE-TOKEN': 'XXXXXXXXXXXXX',
'Content-Type': 'application/json',
}
deployment_status = "failed"
data = { "ref": "cd-pipeline", "variables": [ {"key": "STAGE", "value": "CD"}, {"key": "DEPLOYMENT_STATUS", "value": deployment_status} ] }
response = requests.post('https://gitlab.kazan.atosworldline.com/api/v4/projects/28427/pipeline', headers=headers, json=data)
print(response)
Sending post request with both data and JSON parameters
requests.post(url, json=payload)
is just a shortcut for requests.post(url, data=json.dumps(payload))
Note, the json parameter is ignored if either data or files is passed.
docs
So, no, it is not possible to pass both data
and json
parameters.
How can I find the data parameters required for a requests.post function with a specific URL?
That's because the way you post is wrong, try this:
import requests
headers = {
"Content-type": "application/x-www-form-urlencoded",
}
data = {
"auth": {
"user": "guest",
"password": "guest"
},
"latex": "a^3",
"resolution": 600,
"color": "969696"
}
r = requests.post('http://latex2png.com/api/convert', headers=headers, json=data) # the right way to send POST requests
print(r.json()) # print the json
image_url = "http://latex2png.com" + r.json()['url']
r = requests.get(image_url)
with open("download.png", "wb+") as f: # download it.
f.write(r.content)
what is the difference between data and params in requests?
According to the requests documentation:
- A
requests.post(url, data=data)
will make an HTTP POST request, and - A
requests.get(url, params=params)
will make an HTTP GET request
To understand the difference between the two, see this answer.
Here's how params can be used in a GET:
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=payload)
print(r.text)
Which outputs
{
"args": {
"key1": "value1",
"key2": "value2"
},
[...]
"url": "http://httpbin.org/get?key1=value1&key2=value2"
}
Notice that the payload ended up in the query string of the URL. Since they ended up there, they are viewable by anyone who has access to the URL, which is why you shouldn't use query strings for sensitive data like passwords.
Here's how data can be used in a POST:
payload = 'foobar'
r = requests.post('http://httpbin.org/post', data=payload)
print(r.text)
Which outputs
{
"args": {},
"data": "foobar",
[...]
"url": "http://httpbin.org/post"
}
Notice how the POST data does not show up in the query strings, as they are transmitted through the body of the request instead.
Critique of this answer has pointed out that there are more options. I never denied such a thing in my original answer, but let's take a closer look.
The documentation examples always show:
- The params keyword used for GET, and
- The data keyword used for POST
But that doesn't mean they are mutually exclusive.
In theory you could mix the two together in a POST:
data = 'foobar'
params = {'key1': 'value1', 'key2': 'value2'}
r = requests.post('http://httpbin.org/post', params=params, data=data)
print(r.text)
Which outputs
{
"args": {
"key1": "value1",
"key2": "value2"
},
"data": "foobar",
[...]
"url": "http://httpbin.org/post?key1=value1&key2=value2"
}
But you cannot mix data into a GET:
data = 'foobar'
params = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=params, data=data)
print(r.text)
Outputs:
{
"args": {
"key1": "value1",
"key2": "value2"
},
[...]
"url": "http://httpbin.org/get?key1=value1&key2=value2"
}
Notice how the data field is gone.
How to use variable's value as HTTP POST parameter?
You can use an f-string (as long as you are using Python 3.7+).
url1 = "https://example.com/api/req"
headers = CaseInsensitiveDict()
headers["Content-Type"] = "application/json"
Variable_1 = "Direction"
data = f"""
{{
"type": "{Variable_1}",
"station": "Dept",
"status": "check",
"values": {{
"Par1": "5",
"Par2" : "2",
"Par3": "3",
"Par4": "1",
"Par5": "4"
}}
}}
"""
resp1 = requests.post(url1, headers=headers, data=data)
POST request to FastAPI using Python Requests with a file and query parameters
To pass query parameters in Python requests, you should use params
key instead. Hence:
response = requests.post(url='<your_url_here>', params=payload)
Additionally, there is no need to set the Content-type
in the headers, as it will automatically be added, based on the parameters you pass to requests.post()
. Doing so, the request will fail, as, in addition to multipart/form-data
,"Content-type
must include the boundary
value used to delineate the parts in the post body. Not setting the Content-Type
header ensures that requests sets it to the correct value" (ref). Have a look at this and this. Also, make sure that in files
you use the same key
name you gave in your endpoint, i.e., file
. Thus, in Python requests it should look something like the below:
files = {('file', open('my_file.txt', 'rb'))}
response = requests.post(url='<your_url_here>', files=files, params=payload)
You could also find more options as to how to send additional data along with files at this answer.
Related Topics
How to Check If Directory Exists in Python
What Is :: (Double Colon) in Python When Subscripting Sequences
Why Is Tensorflow 2 Much Slower Than Tensorflow 1
Setting an Environment Variable in Virtualenv
How to Dynamically Load a Python Class
Is There Any Simple Way to Benchmark Python Script
Dropping Infinite Values from Dataframes in Pandas
Python: Change the Scripts Working Directory to the Script's Own Directory
Differencebetween Using Loc and Using Just Square Brackets to Filter for Columns in Pandas/Python
How to Add a New Column to a Spark Dataframe (Using Pyspark)
Python Request Post with Param Data
Pip or Pip3 to Install Packages for Python 3
Deep-Learning Nan Loss Reasons
Integrating MySQL with Python in Windows
How to Filter a Date of a Datetimefield in Django
How to Set the Text/Value/Content of an 'Entry' Widget Using a Button in Tkinter