error 400 while running PUT request in python - python-3.x

I have a working curl command:
ip_address='<my ip address>'
sessionID='<got from post request metadata>'
curl --insecure --request PUT 'https://'$ip_address'/eds/api/context/records' -H 'Csrf-Token: nocheck' -H 'AuthToken:<token>' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"sessionId": "'$session_ID'", "replace":false}'
The python script looks like below:
headers_put = {
'Csrf-Token': 'nocheck',
'AuthToken': '<my token here>',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
url_put = "https://" + ip_address + "/eds/api/context/records"
data = {
"sessionId":"<session id got from POST request metadata>",
"replace":"false"
}
response = requests.put(url_put, headers=headers_put, data=data, verify=False)
print(response)
Error message I get is:
<Response [400]>
b'Bad Request: Invalid Json'
Any idea on what I am doing wrong here? Any help is appreciated!
EDIT:
Can this error cause because of data:
print(data)
{'sessionId': '<session id received from post metadata>', 'replace': 'false'}

Http status 400 means ‘bad request’ as outlined here. You have omitted 1 request header (Csrf-token) in pyScript that was contained in your curl statement. Consider including that and retry the script.
If you still receive an error - you could try and extract (in your script) the actual text or.body of the 4xx response. It may be accessible from the text property of the python response object (you can confirm content-type) using response.apparent_encoding. Best wishes.

I found the solution:
response = requests.put(url_put, headers=headers_put, json=data, verify=False)
instead of data= we have to use json=

Related

how to get response data from a python post request [duplicate]

This question already has answers here:
How to extract HTTP response body from a Python requests call?
(3 answers)
Closed 2 years ago.
I have an openapi3 server running that I'm trying to authenticate with.
I can do it with curl with no problems
curl -k -X POST "https://localhost:8787/api/login/user" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"username\":\"admin\",\"password\":\"admin\"}"
#and i get the token back
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjEyODY3NDU3LCJleHAiOjE2MTI4NzEwNTd9.9eFgomcpJbinN7L4X1VOHfZGvJeUvHiv6WPjslba1To
but when using python I only get the response code (200) with no data including the token
here is my python script
import requests
import os
url = str(os.environ.get('API_SERVER_URL'))+'login/user'
head = {'accept': 'application/json', 'Content-Type': 'application/json'}
data = {"username": "admin", "password": "admin"} }
response = requests.post(url, json=data, headers=head, verify=False)
print(response)
All I get with this is a 200 response
<Response [200]>
How about getting the content of the response?
For example:
print(response.text)
Or if you expect a JSON:
print(response.json())

python request equivalent of following curl put command

what is python request equivalent of following curl put command.
curl --location --request PUT 'https://xxxx/ejbca/ejbca-rest-api/v1/certificate/CN=CompanyName Issuing CA1 - PoC/69108C91844E53258C646444E0FF0FB797349753/revoke?reason=KEY_COMPROMISE' \
--header 'Content-Type: application/json' \
--data-raw ''
Try:
import requests
headers = {
'Content-Type': 'application/json',
}
params = (
('reason', 'KEY_COMPROMISE'),
)
response = requests.get('https://xxxx/ejbca/ejbca-rest-api/v1/certificate/CN=CompanyName%20Issuing%20CA1%20-%20PoC/69108C91844E53258C646444E0FF0FB797349753/revoke', headers=headers, params=params)
#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.get('https://xxxx/ejbca/ejbca-rest-api/v1/certificate/CN=CompanyName Issuing CA1 - PoC/69108C91844E53258C646444E0FF0FB797349753/revoke?reason=KEY_COMPROMISE', headers=headers)
There is a library which supports these convertion.
pip install uncurl
I was not using correct url pattern, now I am using that I am able to do the needful.
import requests
url = f'https://someserver.dv.local/ejbca/ejbca-rest-api/v1/certificate/CN=SomeCompany%20Name%20Issuing%20CA1%20-%20PoC/8188/revoke?reason=KEY_COMPROMISE'
response = requests.put(
headers={
'content-type': 'application/json'
},
verify=('cacertstruststore.pem'),
cert=('restapi-cert.pem', 'restapi-key.key')
)
json_resp = response.json()
print(json_resp)
Response
{'issuer_dn': 'CN=SomeCompany Name CA1 - PoC', 'serial_number': '8188', 'revocation_reason': 'KEY_COMPROMISE', 'revocation_date': '2020-04-14T18:06:33Z', 'message': 'Successfully revoked', 'revoked': True}

Python HTTP post with headers and XML data

I am trying to be able to remotely turn off my TV and the following curl call works like a charm:
curl -v -XPOST http://[your_TV's_IP_address]/sony/IRCC -d '<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:X_SendIRCC xmlns:u="urn:schemas-sony-com:service:IRCC:1"><IRCCCode>AAAAAQAAAAEAAAAVAw==</IRCCCode></u:X_SendIRCC></s:Body></s:Envelope>' -H 'Content-Type: text/xml; charset=UTF-8' -H 'SOAPACTION: "urn:schemas-sony-com:service:IRCC:1#X_SendIRCC"' -H 'X-Auth-PSK: [your_PSK]'
However, I can't port this into a python.requests.post call as I always get an
Error 500
in return.
I must be doing something wrong in passing the XML data or the headers to requests.
Here is my python code:
import requests
TurnOnOffcommandData = "<?xml version=&apos;1.0&apos;?><s:Envelope xmlns:s=&apos;http://schemas.xmlsoap.org/soap/envelope/&apos; s:encodingStyle=&apos;http://schemas.xmlsoap.org/soap/encoding/&apos;><s:Body><u:X_SendIRCC xmlns:u=&apos;urn:schemas-sony-com:service:IRCC:1&apos;><IRCCCode>AAAAAQAAAAEAAAAVAw==</IRCCCode></u:X_SendIRCC></s:Body></s:Envelope>"
TurnOnOffcommandHeaders = {'Content-Type': 'text/xml; charset=UTF-8', 'SOAPACTION': 'urn:schemas-sony-com:service:IRCC:1#X_SendIRCC', 'X-Auth-PSK': 'PASSWORD'}
requests.post('http://XX.XX.XX.XX/sony/IRCC', headers=TurnOnOffcommandHeaders, data=TurnOnOffcommandData)
Thank you for any help on this issue.
Assume you've solved this by now but it looks like you've missed the quotes in the SOAPACTION header.
It should be:
'SOAPACTION': '"urn:schemas-sony-com:service:IRCC:1#X_SendIRCC"'

python3 request body with variable

I stuck in my Python3 code when using requests to make HTTP POST requests. I need to put variable "PackageId" inside data and gets error:
{"meta":{"code":4015,"type":"Bad Request","message":"The value of `carrier_code` is invalid."},"data":[]}
My code is:
import requests
import json
PackageId = input("Package number:")
headers = {
'Content-Type': 'application/json',
'Trackingmore-Api-Key': 'MY-API-KEY',
}
data = {
'tracking_number': PackageId,
'carrier_code': 'dpd-poland'
}
request = requests.post('https://api.trackingmore.com/v2/trackings/post', headers=headers, data=data)
The HTTP POST method used is fine, becouse when I hardcode the PackageId in Body, request is successful.
data = '{ "tracking_number": "1234567890", "carrier_code": "dpd-poland" }'
What might be wrong? Please help, I stuck and spend many hours trying to find a problem.
Here is a CURL command I want to reproduce:
curl -XPOST -H 'Content-Type: application/json' -H 'Trackingmore-Api-Key: MY-API-KEY' -d '{ "tracking_number": "01234567890", "carrier_code": "dpd-polska" }' 'https://api.trackingmore.com/v2/trackings/post'
Thanks !!!
You need to convert the data dict to a json string when providing it to post(), it does not happen implicitly:
request = requests.post('https://api.trackingmore.com/v2/trackings/post', headers=headers, data=json.dumps(data))

Ecobee API: Documentation is for curl not sure how to translate to Python

The Ecobee API documentation shows this as a way to access their API:
#curl -s -H 'Content-Type: text/json' -H 'Authorization: Bearer AUTH_TOKEN' 'https://api.ecobee.com/1/thermostat?format=json&body=\{"selection":\{"selectionType":"registered","selectionMatch":"","includeRuntime":true\}\}'
I have used that code in curl and it seems to work.
However when I try what I think is the equivalent python code it doesn't work.
(I really don't know curl well at all. What I know I know from a few hours of internet research.)
the code I am using:
import requests
headers = {"Content-Type": "text/json", "Authorization": "Bearer AUTH_TOKEN"}
response = requests.get('https://api.ecobee.com/1/thermostat?format=json&body=\{"selection":\{"selectionType":"registered","selectionMatch":"","includeRuntime":"true"\}\}', headers=headers)
print(response.text)
When I send this I get:
{
"status": {
"code": 4,
"message": "Serialization error. Malformed json. Check your request and parameters are valid."
}
}
Not sure what could be wrong with my json formating. Any help is much appreciated.
You'll need to URL-escape the special characters in the parameters.
Doing this by hand can be messy and prone to mistakes. I'm not a Python expert but initial research suggests using the params option built into Python's request.get(). For example:
import requests
url = 'https://api.ecobee.com/1/thermostat'
TOKEN = 'ECOBEEAPIACCESSTOKEN'
header = {'Content-Type':'text/json', 'Authorization':'Bearer ' + TOKEN}
payload = {'json': '{"selection":{"selectionType":"registered","selectionMatch":"","includeRuntime":"true"}}'}
response = requests.get(url, params=payload, headers=header)
print(response.url)
print(response.text)

Resources