I need to retrieve a JWT (JSON Web Token) from a Microsoft API using Python (check this API documentation for Microsoft Graph)
The following Python code using the requests library does not work giving HTTP response code 400, however, the equivalent cURL command does work giving back the expected JSON containing the JWT.
Python / requests code:
tenant = "<MY_FOO_TENANT>"
token_url = "https://login.microsoftonline.com/{}/oauth2/v2.0/token".format(tenant)
http_headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
http_query_params = {
"client_id": "<MY_FOO_C_ID>",
"scope": "<MY_FOO_SCOPE>",
"client_secret": "<MY_FOO_C_SECRET>",
"grant_type": "client_credentials",
}
http_response = requests.post(token_url, params=http_query_params, headers=http_headers)
cURL command:
curl -v -X POST \
--data-urlencode 'client_id=<MY_FOO_C_ID>' \
--data-urlencode 'scope=<MY_FOO_SCOPE>' \
--data-urlencode 'client_secret=<MY_FOO_C_SECRET>' \
--data-urlencode 'grant_type=client_credentials' \
-H 'Content-Type: application/x-www-form-urlencoded' \
'https://login.microsoftonline.com/<MY_FOO_TENANT>/oauth2/v2.0/token'
From the verbose output of the requests library I can see that it is URL encoding all those HTTP query parameters, so I tend to think that should not be the problem.
what's wrong with the Python implementation?
how to make it work?
you should pass http_query_params as data instead of params. try the following code:
tenant = "<MY_FOO_TENANT>"
token_url = "https://login.microsoftonline.com/{}/oauth2/v2.0/token".format(tenant)
http_headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
http_body = {
"client_id": "<MY_FOO_C_ID>",
"scope": "<MY_FOO_SCOPE>",
"client_secret": "<MY_FOO_C_SECRET>",
"grant_type": "client_credentials",
}
http_response = requests.post(token_url, data=http_body, headers=http_headers)
hope this helps
Related
I want to create a pull request on github using the API. The following curl command does work
curl \
-X POST \
-H "Accept: application/vnd.github.v3+json" -H "Authorization: token ghp_abc...123" \
https://api.github.com/repos/alex4200/hello-world/pulls \
-d '{"head":"copyright_updater","base":"master","title":"Test PR curl"}'
but this python snippet does not work:
import requests
headers = {
"Accept": "application/vnd.github.v3+json",
"Authorization": "token ghp_abc...123"
}
data = {
"head": "copyright_updater",
"base": "master",
"title": "Test PR python"
}
response = requests.post(
"https://api.github.com/repos/alex4200/hello-world/pulls",
headers=headers,
data=data
)
print(response.text)
This command, with the exact same data as the curl, returns a 400 error with the message
{"message":"Problems parsing JSON","documentation_url":"https://docs.github.com/rest/reference/pulls#create-a-pull-request"}
What is the problem here?
For some reasons my requests to an API is failing. This is the code:
def create_alert(alert_dict)
url = host + '/api/alerts'
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer tokengen'
}
response = requests.request('POST', url, headers = headers, data=json.dumps(alert_dict))
return response
alert_dict = {
"priority": "1",
"to": to,
"from": from_
}
response = create_alert(alert_dict)
print(response)
The way I'm doing it is saving everything to a dictionary, then making the POST request with it. But for some reason im getting a 500 error.
This is the curl that is working
curl --location --request POST "http://newhost.com/api/alerts" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer tokengen" \
--data "{
\"to\": \"sample#email.com\",
\"from\": \"from#email.com\",
\"priority\": \"1\",
}"
How should I convert my dict in a way that it would work just like the curl --data when requested
I would like to make a python query with this data but I can not convert the 'data-urlencode' interpretable for the python query.
It's my curl request :
curl \
--compressed \
-H 'Accept-Encoding:gzip' \
-H 'Accept-Language:fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7' \
--get '**myurl**' \
--data-urlencode 'app_code=xxxxxx' \
--data-urlencode 'app_id=xxxxxx'
And this this my actual python request:
import requests
headers = {
'Accept-Encoding': 'gzip',
'Accept-Language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
}
data = {
'app_code': 'xxxxx',
'app_id': 'xxxxx'
}
response = requests.post('https://places.cit.api.here.com/places/v1/autosuggest', headers=headers, data=data)
I have trouble encoding the data to get the json.
Thanks
Isn't that curl command a GET request?
I'm not able to try your example but could you please try using the code below.
import requests
url = "https://places.cit.api.here.com/places/v1/autosuggest"
h = {
"Accept-Encoding":"gzip",
"Accept-Language":"fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"
}
params = {
"app_code":"xxxxx",
"app_id":"xxxxx"
}
r = request.get(url, headers=h, params=params).json()
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=535fb089-9ff3-47b6-9bfb-4f1264799865&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=qWgdYAmab0YSkuL1qKv5bPX&grant_type=client_credentials' 'https://login.microsoftonline.com/common/oauth2/v2.0/token'
Here is the command.
How about this sample script?
Sample script :
import json
import requests
url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
payload = {
"client_id": "535fb089-9ff3-47b6-9bfb-4f1264799865",
"client_secret": "qWgdYAmab0YSkuL1qKv5bPX",
"grant_type": "client_credentials",
"scope": "https://graph.microsoft.com/.default"
}
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
res = requests.post(url, headers=headers, data=json.dumps(payload))
print(res.text)
If I misunderstand your question, I'm sorry.
You could use os (though it's outdated)
import os
os.system("curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=535fb089-9ff3-47b6-9bfb-4f1264799865&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=qWgdYAmab0YSkuL1qKv5bPX&grant_type=client_credentials' 'https://login.microsoftonline.com/common/oauth2/v2.0/token'")
What's the alternative of doing this, in Python?
curl -X POST \
-H 'accept: application/json' \
-H 'content-type: application/x-www-form-urlencoded' \
'https://api.mercadolibre.com/oauth/token' \
-d 'grant_type=client_credentials' \
-d 'client_id=CLIENT_ID' \
-d 'client_secret=CLIENT_SECRET'
And the JSON response is something like this:
Status code: 200 OK
{
"access_token": "TU_ACCESS_TOKEN",
"token_type": "bearer",
"expires_in": 10800,
"scope": "...",
"refresh_token": "REFRESH_TOKEN"
}
Anyone knows how can I get the access_token? Not the entire JSON, I only need the access_token.
Thanks
There appears to be a Python library for MercadoLibre which wraps all that up for you.
Something like this should work for you:
import httplib
import urllib
conn = httplib.HTTPSConnection("api.mercadolibre.com")
conn.request("POST", "/oauth/token", urllib.urlencode({
"grant_type": "client_credentials",
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
}), {"accept": "application/json", "content-type": "application/x-www-form-urlencoded"})
conn.getresponse()
Look here http://docs.python-requests.org/en/latest/ requests library is good enough.