Uber API - requests endpoint cannot read read json - python-requests

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.

Related

NextJS, fetch, multipart/form-data, missing boundary

I've faced with issue while proxy http request with multipart form data by NextJS. I have to send file from a client fide to next js, after that - to FastApi service.
The problem was:
fetch("https://127.0.0.1:3000/api/newfile", {
method: "POST",
headers: { "Content-Type": "multipart/form-data" },
body: new FormData(form)
});
headers request: "Content-Type: multipart/form-data"
In order for NextJS API to parse the file, you need a header with boundary
Something like this:
multipart/form-data; boundary=----< generate boundary >
For a long time I could not figure out how to get it.
There is an exit. It is necessary not to fill in "Content-Type".
And then the browser itself will generate this header by passing the form-data.
For example:
fetch("https://127.0.0.1:3000/api/newfile", {
method: "POST",
headers: {},
body: new FormData(form)
});
I also noticed that the problem concerns fetch
When I used XMLHttpRequest I didn't face such problem.
Further, the header can easily be passed further to FastAPI
in API:
req.headers["content-type"]

How to send basic authorization header with Python3.6.9 urllib3

I am trying to send an API call to get the time from the Questrade platform. Here is the sample request from their guide
GET /v1/time HTTP/1.1
Host: https://api01.iq.questrade.com
Authorization: Bearer C3lTUKuNQrAAmSD/TPjuV/HI7aNrAwDp
I am able to get it working with the request module
headers = {'Authorization': f'{token_type} {access_token}'}
print(headers) -> {'Authorization': 'Bearer -xSoUNCLYCrFjxxxxx_wAQVpi4olWrQs0'}
qt_time_obj = requests.get(api_server + 'v1/time', headers=headers)
qt_time = qt_time_obj.json()['time']
print(qt_time) -> 2020-10-13T17:06:32.388000-04:00
Now I am trying to get urllib3 to work but without luck
headers = {'Authorization': f'{token_type} {access_token}'}
url = api_server + 'v1/time'
http = urllib3.PoolManager()
qt_time_obj = http.urlopen('GET', url, headers)
print(qt_time_obj.status) -> 401
print(qt_time_obj.data) -> b'{"code":1014,"message":"Missing authorization header"}'
I also tried with the make_headers method but it gives me the same error.
headers = urllib3.make_headers(basic_auth="Authorization: Bearer AdKt3YUl46_tGnZp7cRgTu4W2vtfBME50")
Could you point where I did wrong? Thank you!
So after some trying, I found that I need to use http.request instead of the http.open. I also need to do "headers=headers" instead of just the "headers" in the method.
qt_time_obj = http.request('GET', url, headers=headers)

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
)

Sending headers to post request

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)

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!

Resources