Python Request Post with Param Data

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



Leave a reply



Submit