How to send basic authorization header with Python3.6.9 urllib3 - python-requests

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)

Related

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)

How to find header data and name? (Python-requests)

I want to use requests to web scrape on a login site. I already done the code using selenium but it is very inconvenient and slower to do it that way as I want to make it public(every user has to download chrome driver).
The problem is, there are multiple requests from the site and I don't have any experience processing that data and extracting the header data and name. Any help is great, thanks.
[Premise]
Using requests module you can send requests in these way:
import requests
url = "http://www.example.com" # request url
headers = { # headers dict to send in request
"header_name": "headers_value",
}
params = { # params to be encoded in the url
"param_name": "param_value",
}
data = { # data to send in the request body
"data_name": "data_value",
}
# Send GET request.
requests.get(url, params=params, headers=headers)
# Send POST request.
requests.post(url, params=params, headers=headers, data=data)
Once you perform a request, you can get much information from the response object:
>>> import requests
# We perform a request and get the response object.
>>> response = requests.get(url, params=params, headers=headers)
>>> response = requests.post(url, params=params, headers=headers, data=data)
>>> response.status_code # server response status code
>>> 200 # eg.
>>> response.request.method
>>> 'GET' # or eventually 'POST'
>>> response.request.headers # headers you sent with the request
>>> {'Accept-Encoding': 'gzip, deflate, br'} # eg.
>>> response.request.url # sent request url
>>> 'http://www.example.com'
>>> response.response.body
>>> 'name=value&name2=value2' # eg.
In conclusion, you can retrieve all the information that you can find in Dev Tools in the browser, from the response object. You need nothing else.
Dev Tools view
Dev Tool view 2
Once you send a GET or POST requests you can retrieve information from Dev Tools:
In General:
Request URL: the url you sent the request to. Corresponds to response.request.url
Request Method: corresponds to response.request.method
Status Code: corresponds to response.status_code
In Response Headers:
You find response headers which correspond to response.headers
eg. Connection: Keep-Alive,
Content-Length: 0,
Content-Type: text/html; charset=UTF-8...
In Requests Headers:
You find request headers which correspond to response.request.headers
In Form Data:
You can find the data you passed with data keyword in requests.post.
Corresponds to response.request.body

Angular2 post with mailchimp

My post works in postman but doesn't work inside my app. What am I doing wrong?
let data = obj;
let url = 'https://us123.api.mailchimp.com/3.0/lists/{somenumber}/members';
let username: string = 'user';
let password: string = 'mytokenhere';
let headers = new Headers();
headers.append("Authorization", "Basic " + btoa(username + ":" + password));
headers.append("Content-Type", "application/x-www-form-urlencoded");
return this._http.post(url, data, {headers: headers}).subscribe(
data => this.response(data),
error => this.response(error)
);
I'm getting a CORS error in app:
'XMLHttpRequest cannot load https://us123.api.mailchimp.com/3.0/lists/{{somenumber}}/members. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 501.'
Mailchimp doesn't support client side calls to their API. What you would need to do is setup a server that can proxy the requests from the browser to Mailchimp. There isn't much you can do client side to get it to work if the Mailchimp API doesn't provide the CORS response headers.
If your API that you create is on the same domain as the website, then the CORS issue would be eliminated (or you can also fix by setting the appropriate headers)
See the note under Authentication:
https://developer.mailchimp.com/documentation/mailchimp/guides/get-started-with-mailchimp-api-3/
More Info:
https://www.moesif.com/blog/technical/cors/Authoritative-Guide-to-CORS-Cross-Origin-Resource-Sharing-for-REST-APIs/

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.

API 1.1 requesting twitter bearer token using r

I have searched this forum and tried several things that seemed relevant, but with no success. If anyone can spot what I'm missing I would be very grateful.
I am trying to get a bearer token using application only authorization as explained at https://dev.twitter.com/docs/auth/application-only-auth so that I can GET follower s/ids.
I have constructed a request in r using rstudio with my consumer key & secret in Base64 encoded form.
library(httr)
POST(url="https://api.twitter.com/oauth2/token", config=add_headers(
c('Host="api.twitter.com"',
'User-Agent="NameOfMyApp"',
'Authorization="Basic MyKeyandSecretBase64Encoded"',
'Content-Type="application/x-www-form-urlencoded;charset=UTF-8"',
'Content-Length="29"',
'Accept-Encoding="gzip"')), body="grant_type=client_credentials")
In response I receive:
Response [https://api.twitter.com/oauth2/token]
Status: 403
Content-type: application/json; charset=utf-8
{"errors":[{"label":"authenticity_token_error","code":99,"message":"Unable to verify your credentials"}]}
I tried resetting my credentials but it made no difference.
I'm a few weeks late, but for anyone like me who stumbles across this page, here is some code that works for me, returning a bearer token:
POST(url="https://api.twitter.com/oauth2/token",
config=add_headers(c("Host: api.twitter.com",
"User-Agent: [app name]",
"Authorization: Basic [base64encoded]",
"Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
"Content-Length: 29",
"Accept-Encoding: gzip")),
body="grant_type=client_credentials")
Once you have a bearer token, you put it in the header of a GET like so:
GET("https://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=justinbieber&count=5000",
config=add_headers(c("Host: api.twitter.com",
"User-Agent: [app name]",
"Authorization: Bearer [bearer token]",
"Accept-Encoding: gzip")))
A late response, but the existing answer wasn't working for me. So here's a solution with a modification of the GET request.
add_headers() uses a named vector. This requires the hyphenated header names to be bracketed with backticks (``). So your POST() call should be:
response <- POST(url = "https://api.twitter.com/oauth2/token",
config = add_headers(.headers = c(Host = "api.twitter.com",
`User-Agent` = "NameOfMyApp",
Authorization = "Basic [base64encoded]",
`Content-Type` = "application/x-www-form-urlencoded;charset=UTF-8",
`Content-Length` = "29",
`Accept-Encoding` = "gzip")),
body = "grant_type=client_credentials")
Within a successful response the application access token can be accessed with:
bearer_token <- jsonlite::fromJSON(rawToChar(response$content))$access_token
You can then verify this with a GET request, such as:
GET("https://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=justinbieber&count=100",
config = add_headers(.headers = c(Host = "api.twitter.com",
`User-Agent` = "NameOfMyApp",
Authorization = paste("Bearer", bearer_token),
`Accept-Encoding` = "gzip")))

Resources