I'm having a problem sending an authorization token with Bearer to an API via python requests.post:
token = "eyJhbGciOiJSUzI1NiIsImtpZCI6IjZjNGE5NDBjNWE5ODE5MGJlNzIwYjI0ZDY2MTMzZWVmIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1NzY4MjU0NzgsImV4cCI6MTU3NjgyOTA3OCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo0MDQwIiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDA0MC9yZXNvdXJjZXMiLCJwYXJjZWxfc3RvcmFnZSJdLCJjbGllbnRfaWQiOiJwcy5tLmNsaWVudCIsInN1YiI6ImI0ZjVmNmVjLWEyMDItNDhjZC1hZmVjLTA4ZDc3OGJmNzYzNyIsImF1dGhfdGltZSI6MTU3NjgyNTQ3OCwiaWRwIjoibG9jYWwiLCJ1c2VybmFtZSI6InZlc3RhIiwic2NvcGUiOlsib3BlbmlkIiwicHJvZmlsZSIsInBhcmNlbF9zdG9yYWdlIiwib2ZmbGluZV9hY2Nlc3MiXSwiYW1yIjpbInB3ZCJdfQ.araPfT_HS0iMXUWS0KcSq3fvowJpu9ONtNsENUtZuk7lV3vxSpyNhUULdZSFdQdZs5830afxRC9qapzYNzDI48ALDrlconKDwReaG9QQhJ61p9dTbSskJDTReGDYwRxEgmZBhjOFD_KeVklbKWevXTGQ2dW3nzGtJ26uMFrSpOww4yNBvJ9Daafson-tZNXeG6xZ09H5GHY43Qp9P25kNRBfeFyKzYuF7xoygk_TQSlMike2Fzjec9TBbudSsTP62qIAXkYckvGF5fI5buJWsw5tvrDtgKVSfVs_SD27-3MIjde27fG89sH-CUYryroy6YiHyTx6UOYTvC2dBNzm5A"
test_url = 'https://fpt.titec.ir/api/v1/parcel/getprecode'
header = {
"Authorization": "Bearer {}".format(token),
"Content-Type": "application/json",
}
data = {'serviceTypeId': '2'}
response = requests.post(test_url, data=data, headers=header)
But every time the response returned 401 status code.
In postman it works well but in python code it doesn't work. Is it a bug in requests.post?
By the way the token expires in 60 min.
Is there anyone who could help me please?
I can do this successfully with requests.get for another url that needs exactly the same token!!
Related
I was able to get the auth token from the login api but I am trying to use it to query the events api and I am getting a 401 Client Error: Unauthorized for url error message. Here is a snippet of my code:
def action():
data = {
'login': 'xxxxxxxxx',
'password': 'xxxxx',
}
urllib3.disable_warnings()
try:
timestamp = int(round(time.time() * 1000))
print(timestamp)
r = requests.post(
'https://host:port/www/core-service/rest/LoginService/login', data=data, verify=False)
login_request = untangle.parse(r.text)
user_session_id = login_request.ns3_loginResponse.ns3_return.cdata
print(user_session_id)
response = requests.post(
'https://host:port/detect-api/rest/v1/events/retrieve',
headers={
"Accept": "application/json",
"Authorization": user_session_id,
"Content-Type": "application/json"
},
data={
"ids": 79745681,
"startTime": timestamp,
"endTime": timestamp
},
verify=False)
print(response)
res = untangle.parse(response.text)
print(res)
Can somebody please point out what is wrong with my code?
You didn't add link to API so I only guess what can make problem.
If you set "Content-Type": "application/json" then it can means you want to send json data.
So you should use
post(..., json=...)
instead of
post(..., data=...).
Using data= you send it as form, not json. And header Content-Type can't change it.
And when you use json= then you don't have to add "Content-Type": "application/json" because requests will add it automatically.
EDIT:
In comment you said that you have working curl command (but you didn't said it in question, and you didn't show curl in question)
On page https://curl.trillworks.com you can convert curl to Python (and few other languages) and mostly it works correctly.
BTW:
If you use postman for tests then it has also function to generate code for curl, Python and many other languages.
You didn't show link to API documentation but often API documentation has examples for curl and sometimes even for Python.
I've been trying to post a payload to an endpoint, the endpoint requires bearer token.
using the python requests, I'm trying to post the bearer token in the header as
from requests import Session
http= Session()
accessToken = getToken(url=uri,data=payload)
authorization_header_string = 'bearer ' + accessToken
requestHeaders = {"Content-type": "text/plain", "Authorization":authorization_header_string}
headerData={"content-type":"text/plain","authorization":requestHeaders}
resp= http.post(url=uri,data=payload,headers=headerData)
but all I get is 401 error, while if I use the same token in postman it works fine.
I'm using requestbin to check wherein the authorization shows up only sometimes in the header.
Try the following:
token = "your token"
headerData={"content-type": "text/plain", "authorization": "Bearer " + token}
I am currently trying to build an integration between Quickbooks POS and squarespace. The official api documentation gives the following example:
curl "https://api.squarespace.com/1.0/commerce/products?cursor=abc" \
-i \
-H "Authorization: Bearer YOUR_API_KEY_OR_OAUTH_TOKEN" \
-H "User-Agent: YOUR_CUSTOM_APP_DESCRIPTION"
which returns with error 52 (no data) from. My attempts to do this with python also returns no data.
import requests
print("start")
headers = {
"Authorization": "API KEY",
"User-Agent": "QBPOS integration"
}
square_api = requests.Session()
data = square_api.get('https://api.squarespace.com/1.0/commerce/products', headers=headers)
print(data)
print(data.text)
and python-squarespace returns an error stating that squarespace thinks this request is bogus.
All of the response codes are <403>.
What could cause it to this, how can I fix this?
Add Bearer before the API KEY!!
import requests
headers = {
'Authorization': 'Bearer INSERT YOUR API KEY',
'User-Agent': 'QBOS INTEGERATION',
'Content-Type': 'application/json',
}
print("Hello World")
response = requests.get('https://api.squarespace.com/1.0/authorization/website', headers=headers)
print(response.text)
The above code is to check your squarespace api key is valid or not. In Authorization you forgot the Bearer, and replace API KEY with your api key which square space provided. I guess that QUBOS integration is the key name of the square space API key.
Squarespace uses some confusing terminology for it's apis. I had not enabled the api I needed.
Below bash script works and returns a token.
curl -X POST --user <id>:<key> 'https://<name>.auth.eu-west-1.amazoncognito.com/oauth2/token?grant_type=client_credentials' -H 'Content-Type: application/x-www-form-urlencoded'
I would now like to generate a token via a Python script. I currently struggle with using requests library, but without success. Below generates Response 400 (bad request).
import requests
parameters = {"user":"<id>:<key>", "Content-Type": "application/x-www-form-urlencoded"}
response = requests.get("https://<name>.auth.eu-west-1.amazoncognito.com/oauth2/token?grant_type=client_credentials", params=parameters)
print(response)
To fix your usage of requests:
Use post() instead of get().
Use an auth object to construct a basic auth header. (Or send credentials in the body)
Remove the content type header; requests will set this for you.
Take the grant_type out of the query string. This belongs in the request body.
While the documentation for the /oauth2/token endpoint says you need to send a basic auth header for client_credentials grant, it also works if you send the client id and secret in the request body (with no auth header).
As such, these python examples both work, and are essentially equivalent:
Credentials in request body:
import requests
url = 'https://<COGNITO_DOMAIN>.auth.<REGION>.amazoncognito.com/oauth2/token'
params = {
"client_secret": "1ixxxxxxxxxxxxxxxxc2b",
"grant_type": "client_credentials",
"client_id": "7xxxxxxxxxxxxxxxt"
}
response = requests.post(url, data=params)
print(response)
print(response.text)
Credentials in basic auth header:
import requests
url = 'https://<COGNITO_DOMAIN>.auth.<REGION>.amazoncognito.com/oauth2/token'
params = {
"grant_type": "client_credentials"
}
auth = ('7xxxxxxxxxxt', '1ixxxxxxxxxxxxxxxc2b')
r = requests.post(url, data=params, auth=auth)
print(r)
print(r.text)
I have a client id and client secret and am attempting to generate an auth token by following Sitescout's api docs. I'm using python module Requests and am getting a 400 status code back, aka malformed request, but I can't seem to figure out why.
My code:
import requests
url = "https://api.sitescout.com/oauth/token"
headers = {
"Host": "api.sitescout.com",
"Authorization": "Basic YmVldGhvdmVuOmxldG1laW4=",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",
"Content-Length": "41"
}
# Do the HTTP request
response = requests.post(url, headers=headers)
response.status_code
That is the fake base64 Authorization header provided in the docs so this snippet returns a 401 error, aka unauthorized (I have my own auth of course).
Can anyone tell me what's wrong with this?
It has been resolved. I did not put grant_type=client_credentials which, when added, returns a 200.
The docs say "Optionally, you can add form parameter scope to indicate which scopes you are requesting access to; the scope values must be space delimited (e.g., STATS AUDIENCES)." But it is the "&scope=STATS" param that is optional, not all params. The example confused me.
Now my code reads
...
params = { "grant_type" : "client_credentials" }
response = requests.post(url, headers=headers, params=params)
...
which works.