Python Requests Microsoft Graph API Authentication - python

I'm having issues receiving the bearer token using Python for the Microsoft Graph API. Here is what I have so far:
import requests
import json
headers = {
'Content-Type': 'x-www-form-urlencoded',
'Authorization': 'Basic'
}
data = {
"grant_type": "client_credentials",
"client_id" :"<client_id>",
"client_secret": "<client_secret>",
"resource": "https://graph.microsoft.com"
}
r = requests.post('<token_address>', headers=headers, data=data)
print(r.text)
I have it worked in Postman, through x-www-form-urlencoded, but can't seem to get it working in Python. It returns The request body must contain the following parameter: 'grant_type'. I realize the problem probably has to do with needed the data converted, but I am not sure where to start.

You're sending some invalid headers in your request:
The Content-Type should be application/x-www-form-urlencoded not x-www-form-urlencoded.
You shouldn't be sending an Authorization header at all.
Technically, since requests.post sends data as form encoded by default, you can safely remove your headers from the request:
payload = {
'grant_type': 'client_credentials',
'client_id': '<client_id>',
'client_secret': '<client_secret>',
'resource': 'https://graph.microsoft.com',
}
r = requests.post('https://login.microsoftonline.com/common/oauth2/token', data=payload)
print(r.text)

I believe that OAuth expects the body to be URL-encoded, like this:
data = "grant_type=client_credentials"
+ "&client_id=<client_id>"
+ "&client_secret=<client_secret>"
+ "&resource=https://graph.microsoft.com"

Related

I need help from anyone with experience using the ArcSight esm rest API

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.

Python API Error - 'faultstring': 'JSONThreatProtection

First time trying to extract data via an API. I'm getting stuck with how to pass the raw data. I have been able to get it to work in postman but I can't quite figure it out with Python.
I've been getting this error:
{'fault': {'faultstring': 'JSONThreatProtection[JSON-Threat-Protection-1]: Execution failed. reason: Expecting { or [ at line 1', 'detail': {'errorcode': 'steps.jsonthreatprotection.ExecutionFailed'}}}
I'm pretty sure its the data portion that is wrong but I haven't been able to figure out if it's just a syntax error or something bigger that I'm missing.
My code as follows:
import requests
import json
url = "https://url/customers/shipmentstatus"
headers = {
"Authorization": "Bearer TOKEN",
"Content-Type": "application/json"
}
data = {
"Id": [
"AZ1234"
]
}
response = requests.post(url, headers=headers, data=data)
print(response.json())
Your code posts the data as form encoded data, not as JSON. That's because you use the data parameter to supply the payload. To fix, encode the data as JSON using json.dumps():
response = requests.post(url, headers=headers, data=json.dumps(data))
But a better way is to pass the data to requests using the json parameter:
response = requests.post(url, headers=headers, json=data)
Using the json parameter is easier and it will also add the Content-Type: application/json header for you.

How to gain an Access Token

I am lost, I have no idea what should I do to get the access token. This is the code that I have tried, please help, please!
This is for Oauth2.0 token, and the API is Ocotoparse.
from octoparse import Octoparse as oct
import requests
host='https://advancedapi.octoparse.com/token'
url=host+'username={onlyfiii}&password={19970909huy}&grant_type=password'
r=requests.post(url)
username='onlyfiii'
password='19970909huy'
{
"access_token": "ABCD1234",
"token_type": "bearer",
"expires_in": 86399,
"refresh_token": "refresh_token"
}
I hope that's not your real password, if it is, change it immediately.
You need to send the request parameter as a form encoded POST request body, not as url parameters.
import requests
import json
url = 'https://advancedapi.octoparse.com/token'
payload = {
'username': 'onlyfiii',
'password': '19970909huy',
'grant_type': 'password',
}
r = requests.post(url, data=payload)
json_response = json.loads(r.text)
access_token = json_response['access_token']
See the API docs:
Request Content Type
application/x-www-form-urlencoded

Tomtom webfleet order api gives 40 general error

I am trying to insert a destination order using action=insertDestinationOrder
I am using POST method with all required parameters, but keep getting
{
"errorCode": 40,
"errorMsg": "general error"
}
I have checked using postman too. But still same.
Below is the request using python requests package.
import requests
url = "https://csv.telematics.tomtom.com/extern"
payload = "orderid=TO0049&country=DE&city=Cologne&latitude=50974519&ordertype=delivery%20order&zip=50735&longitude=6977319&street=Am%20Niehler%20Hafen%20%26%20Stapelkai%2C%2050735%20Cologne%20(Niehl)&account=XXXX&username=XXXX&password=XXXX&apikey=XXXX&lang=en&action=insertDestinationOrder&ordertext=Am%20Niehler%20Hafen%20%26%20Stapelkai%2C%2050735%20Cologne%20(Niehl)&useUTF8=true&outputformat=json"
headers = {
'content-type': "application/x-www-form-urlencoded"
}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
Need some help.
Try adding a ? to the end of the url, or to the start of the payload:
url = "https://csv.telematics.tomtom.com/extern?"
or
payload = "?orderid=TO0049&country=DE&city=Cologne&latitude=50974519&ordertype=delivery%20order&zip=50735&longitude=6977319&street=Am%20Niehler%20Hafen%20%26%20Stapelkai%2C%2050735%20Cologne%20(Niehl)&account=XXXX&username=XXXX&password=XXXX&apikey=XXXX&lang=en&action=insertDestinationOrder&ordertext=Am%20Niehler%20Hafen%20%26%20Stapelkai%2C%2050735%20Cologne%20(Niehl)&useUTF8=true&outputformat=json"

Response status code 400 when using python module Requests with Sitescout API

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.

Categories