Sending headers to post request - python-requests

I have this python code that does not work as expected.
import requests
import json
API_ENDPOINT = "https://lkokpdvhc4.execute-api.us-east-1.amazonaws.com/mycall"
data = {'mnumber':'9819838466'}
r = requests.post(url = API_ENDPOINT, data = json.dumps(data))
print (r.text)
This will return an error:
{"stackTrace": [["/var/task/index.py", 5, "handler", "return
mydic[code]"]], "errorType": "KeyError", "errorMessage": "''"}
When I test the API using Amazon console's gateway, I get the expected output (i.e. string like "mumbai"). It means this is client side issue. I have confirmed this by using "postman" as well that returns the same error as mentioned above. How do I send correct headers to post request?

You can create a dictionary with the headers such as
headers = {
"Authorization": "Bearer 12345",
"Content-Type": "application/json",
"key" : "value"
}
Then at the point of making the request pass it as a keyword argument to the request method i.e .post() or .get() or .put
This will be
response = requests.post(API_ENDPOINT, data=json.dumps(data), headers=headers)

Related

Microsoft Graph 'Unable to read JSON request payload' error when inviting users to Azure AD in Python with Requests

I'm trying to automate inviting users to an Azure AD using the MS Graph API but get an 'Unable to read JSON request payload' error.
I'm pulling data from a ticketing system, retrieving the current AAD users and diff-ing both. Then I'll be pushing the new ones into the AAD and updating them to include them in an Attendees AD Security group.
I created a Python Azure Function that calls the Graph API with Requests :
def insert_users(users_emails):
logging.info('Inserting new users in AAD')
token = generate_auth_token()
users_emails = users_emails[:2]
added_attendees = []
for email in users_emails:
req_body = {
"invitedUserEmailAddress" : email
, "inviteRedirectUrl" : "https://myapp.com"
}
body_length = sys.getsizeof(req_body)
req_headers = {
'Authorization' : 'Bearer {0}'.format(token)
, 'Content-Type' : 'application/json; charset=utf-8'
, 'Content-Length' : str(body_length)
}
response = requests.post(
'https://graph.microsoft.com/v1.0/invitations'
, headers = req_headers
, data = req_body
)
response = response.json()
logging.info(response)
added_attendees.append(email)
return added_attendees
The Graph API sends back the following error message :
{'error':
{'code': 'BadRequest',
'message': 'Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.',
'innerError':
{'request-id': '4ff5332d-d280-4b0d-9e04-a7359ab0e2fb', 'date': '2020-05-27T14:51:18'}
}
}
I tried adding the charset to the Content-Type header but it won't work. I read someplace the Content-Length could be useful so I added it too, to no avail.
Tests run ok in Postman and I'm already performing a POST request against the Azure AD API to get an Access Token so the Requests JSON body is parsed fine then. I also tried using single or double quotes in the JSON payload but it didn't work either.
My take is something is misinterpreted by the Graph API but I can't figure out what.
Thanks forward for your help !
i found a solution. Instead of passing a data argument to the request.post method, I passed a json= argument
response = requests.post(
'https://graph.microsoft.com/v1.0/invitations'
, json={'invitedUserEmailAddress':email,'inviteRedirectUrl':'https://myapp.com'}
, headers = req_headers
)

How to add a request body to an IBM BPM 8.6 script task BPMRESTRequest object in order to invoke a REST api?

I am trying to invoke a REST api (POST operation) from IBM BPM 8.6, I have to use a script task, I am able to call the api no problem just that the api expects a request body with a json object in it and I have not found a way yet to add that to the request object which I create in the script. I am able to add headers and parameters but not a http body to the request.
This is my code in the script tab of the the script task, the call is received by the api but it discards it with the message that the request is missing a request body which the api expects.
var request = new BPMRESTRequest();
request.externalServiceName = "api-docs";
request.operationName="extractReporterInfoUsingPOST";
request.httpHeaders = {"Content-Type": "application/json", "Accept":
"application/json"};
request.httpMethod = "POST";
// request.body = {"test":"dummy"}; <- does not work
// request.httpBody = {"test":"dummy"}; <- does not work
var response = tw.system.invokeREST(request);
I had the same problem. I was able to solve this issue by specifying the post body like so:
request.parameters = { "body": { "key1": "val1", "key2", "val2" }}
In parameters object add the key as the name of the body you gave or mentioned in swagger files request.parameters = { "nameOfBodyAsMenitionedInSwagger": { "key1": "val1", "key2", "val2" }}

Python Request Session JIRA REST post http 405

Using python requests session I can connect to JIRA and retrieve issue information ...
session = requests.Session()
headers = {"Authorization": "Basic %s" % bas64_val}
session.post(jira_rest_url, headers=headers)
jira = session.get(jira_srch_issue_url + select_fields)
# select_fields = the fields I want from the issue
Now I'm trying to post a payload via the JIRA API, using a fixed issue url e.g. "https://my_jira_server.com:1234/rest/api/latest/issue/KEY-9876"
Which should be a case of the following, given: https://developer.atlassian.com/jiradev/jira-apis/about-the-jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-edit-issues
payload = { "update": {
"fixVersions": [ {"set": "release-2.139.0"} ]
}}
posted = session.post(jira_task_url, data=payload)
# returns <Response [405]>
# jira_task_url = https://my_jira_server.com:1234/rest/api/latest/issue/KEY-9876
But this doesn't appear to work! Looking into the http 405 response, suggests that my payload is not properly formatted! Which notably, is the not easiest thing to diagnose.
What am I doing wrong here? Any help on this would be much appreciated.
Please note, I am not looking to use the python jira module, I am using requests.session to manage several sessions for different systems i.e. JIRA, TeamCity, etc..
Found the solution! I had two problems:
1) The actual syntax structure should have been:
fix_version = { "update": { "fixVersions": [ {"set" : [{ "name" : "release-2.139.0" }]}]
2) To ensure the payload is actually presented as JSON, use json.dumps() which takes an object and produces a string (see here) AND set 'content-type' to 'application/json':
payload = json.dumps(fix_version)
app_json = { 'content-type': 'application/json' }
session.put(https://.../rest/api/latest/issue/KEY-9876, headers=app_json, data=payload)
Rather than trying to define the JSON manually!

API authentication in R - unable to pass auth token as header

I am looking to do a simple GET request (from the Aplos API) in R using the httr package. I'm able to obtain a temporary token by authenticating with an API key, but then I get a 401 "Token could not be located" once trying to use the token to make an actual GET request. Would appreciate any help! Thank you in advance.
AplosURL <- "https://www.aplos.com/hermes/api/v1/auth/"
AplosAPIkey <- "XYZ"
AplosAuth <- GET(paste0(AplosURL,AplosAPIkey))
AplosAuthContent <- content(AplosAuth, "parsed")
AplosAuthToken <- AplosAuthContent$data$token
#This is where the error occurs
GET("https://www.aplos.com/hermes/api/v1/accounts",
add_headers(Authorization = paste("Bearer:", AplosAuthToken)))
This is a Python snippet provided by the API documentation:
def api_accounts_get(api_base_url, api_id, api_access_token):
# This should print a contact from Aplos.
# Lets show what we're doing.
headers = {'Authorization': 'Bearer: {}'.format(api_access_token)}
print 'geting URL: {}accounts'.format(api_base_url)
print 'With headers: {}'.format(headers)
# Actual request goes here.
r = requests.get('{}accounts'.format(api_base_url), headers=headers)
api_error_handling(r.status_code)
response = r.json()
print 'JSON response: {}'.format(response)
return (response)
In the python example, the return of the auth code block is the api_bearer_token which is base64 decoded and rsa decrypted (using your key) before it can be used.
...
api_token_encrypted = data['data']['token']
api_bearer_token = rsa.decrypt(base64.decodestring(api_token_encrypted), api_user_key)
return(api_bearer_token)
That decoded token is then used in the api call to get the accounts.
The second issue I see is that your Authorization header does not match the example's header. Specifically, you are missing the space after "Bearer:"
headers = {'Authorization': 'Bearer: {}'.format(api_access_token)}
vs
add_headers(Authorization = paste("Bearer:", AplosAuthToken)))
Likely after addressing both of these you should be able to proceed.

Uber API - requests endpoint cannot read read json

I am trying to generate a POST request for the requests endpoint in the following python code:
import requests
...
response = requests.post(
'https://sandbox-api.uber.com/v1/requests',
headers = {
'Authorization': 'Bearer %s' % access_token,
'Content-Type': 'application/json'
},
params={"start_latitude":"37.334381","start_longitude":"-121.89432","end_latitude":"37.77703","end_longitude":"-122.419571","product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d"})
data = response.json()
The access_token was obtained using request scope during authorization. The response json is :
{"message": "Unable to parse JSON in request body.", "code": "invalid_json"}
Need help in formatting the request properly. Thanks.
Figured out the problem - had to replace the params field with a data field and wrap the dict with json.dumps() before sending it off.

Resources