Empty body error on post request in python script - python

I'm trying to make a post request to an API endpoint with python and requests.
The endpoint requires a token. I get the token from the endpoint just fine.
When making a post request to the second endpoint Validation Error stating that body is empty.
import requests
url = "https://authz.dinero.dk/dineroapi/oauth/token"
payload = 'grant_type=password&username=****&password=****'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ****'
}
response = requests.request("POST", url, headers=headers, data = payload)
r =response.json()
token = r['access_token']
url = "https://api.dinero.dk/v1/257403/contacts"
payload = {}
payload["Name"] = "Test Name"
payload["CountryKey"] = "DK"
payload["IsPerson"] = "true"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
}
response = requests.post(url, headers=headers, data = payload)
print(response.text)
This is the error I get:
{"code":42,"message":"Validation Error","validationErrors":{"Body":"The body was empty"},"languageSpecificMessages":[{"property":"message","message":"Der er fejl i de angivne data"},{"property":"Body","message":"The body was empty"}],"errorMessageList":[{"Code":"Body","Message":"The body was empty"}]}
Here is the same code taken from postman. It works fine.
import requests
url = "https://api.dinero.dk/v1/257403/contacts"
payload = "{\r\n \"Name\": \"Test Name\",\r\n \"CountryKey\": \"DK\",\r\n \"IsPerson\": true\r\n}"
print(payload)
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ****'
}
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
I hope someone can explain why my code isn't working.

Requests has a json= param you could use:
response = requests.post(url, headers=headers, json=payload)
Docs here.

In your second call, you want to json dump the payload:
import json
response = requests.post(url, headers=headers, data=json.dumps(payload))
Postman has already serialised the payload as a json formatted string. You can do the same with json.dumps().

Related

Signature doesn't match. ERROR 401 Unauthorized. OAuth1.0 POST API Call Signature generation with body with Python 3.9 AWS Lambda

From POSTMAN Code Snippet.
import requests
url = "https://www.XXXX.com/systems/num/config"
payload='{body}'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'OAuth realm="https%3A%2F%2Fwww.app-api.ing.XXXX.com%2Fsystems%2Fnum%2FXXX",oauth_consumer_key="XXXXXX",oauth_token="XXXXXX",oauth_signature_method="HMAC-SHA1",oauth_timestamp="TTTTTT",oauth_nonce="NNNNNN",oauth_version="1.0",oauth_signature="tick80j6BYSDMTw8eo%2Fp9EjoxBA%3D"'
}
response = requests.request("POST", url, headers=headers, data=payload)
Works fine in POSTMAN.
Unable to sign the XML Body and send POST Request along with realm to external API from Lambda.
My Code:
rn = nonce
client = oauthlib.oauth1.Client(consumer_key, consumer_secret, access_token, token_secret, nonce=str(rn))
uri, headers, body = client.sign(f'https://www.XXXX.com/systems/{num}/{category}')
client = oauthlib.oauth1.Client(consumer_key, client_secret=consumer_secret, resource_owner_key=access_token, resource_owner_secret=token_secret, verifier=str(rn))
uri, headers, body = client.sign(f'https://www.XXXX.com/systems/{num}/{category}',
realm=f'https%3A%2F%2FXXXX.com%2Fsystems%2F{num}%2F{category}')
payload = <XML BODY>
headers['Content-Type'] = 'application/x-www-form-urlencoded'
headers['Accept'] = 'application/x-www-form-urlencoded'
response = requests.post(uri, headers=headers, data=payload)
print(response.status_code)
Response from server:
401 Unauthorized
<error version="1.48">
<message>signature doesn't match</message>
</error>

How does Postman to generate this cookie?

import requests
url = "https://apiexample.com/load/v1/action/aaaaaaaaaaaaa"
payload={}
headers = {
'Authorization': 'OAuth oauth_consumer_key="aaaaaa",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1664837015",oauth_nonce="mKyTFn7OtsV",oauth_version="1.0",oauth_signature="aaaaaaaaaaaa"',
'Cookie': 'JSESSIONID=M7n-S-aGe8asRnTjNOUGowak5i5avsRBx6A4H8au.madsedepre'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
I am trying to retrieve information from an api, and I am using postman...
How can I know what postman is doing to generate that cookie??
and how can I generate it using python requests?

Error posting comments using Facebook Graph API

My aim is to post a comment to a particular post id using Facebook graph API.
This is the code snippet for the same:
url = 'https://graph.facebook.com/v2.11/<post_id>/comments'
parameters = {'access_token': <FACEBOOK_ACCESS_TOKEN>, 'message': 'test comment'}
headers = {"content-type": "application/json"}
parameters = json.dumps(parameters)
response = requests.post(url, data=parameters, headers=headers, timeout=10)
I am calling this API inside my DJANGO POST API.
For Some Reason, Calling the Facebook API through this code doesnt work. The API call gets timeout after 10 seconds.
If I call the Facebook API through Postman / YARC , the comment gets posted successfully.
Can any one tell me where I am going wrong?
Python Requests example:
import requests
url = "https://graph.facebook.com/v2.11/yourPostId/comments"
querystring = {"access_token":"yourtoken"}
payload = "message=test%20comment"
headers = {
'content-type': "application/x-www-form-urlencoded",
'cache-control': "no-cache"
}
response = requests.request("POST", url, data=payload, headers=headers, params=querystring)
print(response.text)
Python http.client example:
import http.client
conn = http.client.HTTPSConnection("graph.facebook.com")
payload = "message=test%20comment"
headers = {
'content-type': "application/x-www-form-urlencoded",
'cache-control': "no-cache"
}
conn.request("POST", "/v2.11/yourPostId/comments?access_token=yourtoken", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

Not able to upload the data on thingworx with api

Tried many ways to upload the data(postman, httpie etc as given on their site) on thingworx but not able to do that.
Please have a look on the following code to upload the data on thingworx:
import requests
import json
app_key = 'xxxx'
url = 'http://pp-1804040542ze.devportal.ptc.io/Thingworx/Things/lmtech_thing/Properties/humidity'
prms = {'appKey': app_key}
hdrs = {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
data = {'humidiy': '20'}
text = json.dumps(data)
print 'data: ' + text
r = requests.put(url, params=prms, headers=hdrs, data=text)
print r.status_code
Have created thing and key successfully. but it always return 404 error.
Tried with postman too. Here are the screenshots as shown below:
The following code worked for me :-)
import requests # Import requests library to send requests to Thingworx
url = 'http://52.199.28.120:8080/Thingworx/Things/work_thing/Properties/temp'
# temp is one of my property name
value = 12 # Upload 12 on Thingworx
headers = {
'Content-Type': 'application/json',
'appkey': 'xxxxxxxxxxxxxxxxxxxxxx',
'Accept': 'application/json',
'x-thingworx-session': 'true',
'Cache-Control': 'no-cache',
}
data = {"temp": value} # JSON data to upload on Thingworx
response = requests.put(url, headers=headers, json=data)
# Note that we have to send put request
print 'Response Code:', response.status_code
# If 200 then data has been uploaded successfully
print 'Response Content:', response.content

Why does Bearer not work in requests authorization header?

I'm having a problem sending an authorization token with Bearer to NEST API via python requests:
curl https://developer-api.nest.com -H "Authorization: Bearer c.123"
-H "Content-Type: application/json"
works fine, however:
nest_url = "https://developer-api.nest.com"
headers = {'Authorization': str('Bearer ' + token), 'Content-type': 'application/json'}
print(headers)
nest_data_req = requests.get(nest_url, headers=headers)
which prints as:
{'Content-type': 'application/json', 'Authorization': 'Bearer c.123'}
fails with a 401 unauthorized, as far as I can tell they are trying to make the same request so why does curl work (and postman for that matter) and python requests fail?
The following image shows the same working in postman:
Update:
So this code works 1 in 10 times (the other 9+ give me 401 unauthorized):
url = "https://developer-api.nest.com/"
auth_t = token.encode("ascii", "ignore")
headers = {
'authorization': "Bearer " + auth_t,
'content-type': "application/json",
'cache-control': "no-cache",
}
response = requests.request("GET", url, headers=headers)
print(response.text)
if I press submit in postman it works everytime without fail.
Turns this is a result of nest's API redirecting so you could consider this either a bug - as headers are removed from the redirected request, and headers should be on the session. Or a 'feature' as they were trying to resolve a CVE.
So here is a prototyped way to handle this:
def get_nest_data(token):
url = "https://developer-api.nest.com/"
auth_t = token.encode("ascii", "ignore")
headers = {
'authorization': "Bearer " + auth_t,
'content-type': "application/json",
}
try:
init_res = requests.get('https://developer-api.nest.com', headers=headers, allow_redirects=False)
if init_res.status_code == 307:
api_response = requests.get(init_res.headers['Location'], headers=headers, allow_redirects=False)
if api_response.status_code == 200:
return api_response.json()
elif init_res.status_code == 200:
return init_res.json()
except Exception as ce:
print(ce)

Categories