Unclear on making an API call after authentication? - python

I am looking on how to use an APIs, more specifically Egnyte's API.
From their documentation, I must first get a oauth2 token, which I was able to get successfully.
Here are their documentation:
https://developers.egnyte.com/docs/read/Getting_Started
https://developers.egnyte.com/docs/User_Management_API_Documentation#Get-User-List
However, I am not sure what to do afterwards. I am trying to use their User management API, which I am suppose to make a call to:
https://{Egnyte Domain}.egnyte.com/pubapi/v2/users
However, how do i use their token for a requests.get call to their api?
Below is my python code, I am using the the Requests Module (http://docs.python-requests.org/en/latest/):
import requests
api_key = 'MY_API_KEY'
username = 'myUserName'
password = 'myPassword'
payload = {
'grant_type': 'password',
'client_id': api_key,
'username': username,
'password': password
}
token = requests.post("https://{Egnyte Domain}.egnyte.com/puboauth/token", params = payload)
print r.text
The response I get is:
{"access_token":"*MYToken","token_type":"bearer","expires_in":-1}
Thanks!

Ah, someone had showed me.
had to do minor adjustments to the script:
r = requests.post("https://{Egnyte Domain}.egnyte.com/puboauth/token", params=payload)
token = r.json()['access_token']
users = requests.get(url, headers={'Authorization': 'Bearer %s' % token})

You need to use the token in the authorization header of requests. The best thing would be to create a persistent connection.
r = requests.post("https://{Egnyte Domain}.egnyte.com/puboauth/token", params=payload)
if r.ok:
access_token = r.json()['access_token']
session = requests.Session()
session.headers['Authorization'] = "Bearer %s" % access_token
users = session.get('https://{Egnyte Domain}.egnyte.com/pubapi/v2/users')
OR
headers = {"Authorization":"Bearer %s" % access_token}
requests.get('https://{Egnyte Domain}.egnyte.com/pubapi/v2/users', headers=headers)

Related

How to read Outlook emails without using Graph API using the email ID and password in Python?

I cannot run my script locally using pywin32 - MAPI as it is to be hosted on a server/remote desktop without Outlook application installed on the machine.
Can you please help me with this?
Thanks in advance.
If you deal with Exchange accounts only you may also consider using EWS, see Explore the EWS Managed API, EWS, and web services in Exchange for more information.
Make sure you have Azure P2 subscription.
Look into the following link and get an app registered and assign permissions to the same. https://www.linkedin.com/pulse/reading-o365-emails-from-daemon-process-using-graph-bhattacharya/
Create "Creds.py" file and add the credentisl - base_path, client_id, client_secret, object_id, scope, url_access_token, tenant_id, url_attachments, url_messages to it as strings to it. (refer the link above to understand what each of it means and how to get the values of them).
The following code checks if a particular string "body_tag" is present in the body of an email and then downloads all the attachments of that particular email if it is present. Also, it only reads the "unread" emails.
CODE
import requests
import base64
from Creds import base_path, client_id, client_secret, object_id, scope, url_access_token, tenant_id, url_attachments, url_messages
# Access Token
url_access_token = url_access_token.format(tenant_id)
body_tag = ""
payload = {
'client_id': client_id,
'scope': scope,
'client_secret': client_secret,
'grant_type': 'client_credentials',
'Content-Type': 'application/x-www-form-urlencoded'
}
files=[]
headers = {}
response = requests.request("POST", url_access_token, headers=headers, data=payload, files=files)
access_token = response.json()['access_token']
# Get Emails
url_messages = url_messages.format(object_id)
payload={}
files={}
headers = {
"Authorization": "Bearer " + access_token
}
response = requests.request("GET", url_messages, headers=headers, data=payload, files=files)
emails = response.json()['value']
for email in emails:
body = email['body']
if(body_tag in str(body)):
message_id = ""
if(email['hasAttachments']):
message_id = email['id']
# Get the attachments
if(len(message_id) > 0):
# Attachments
url_attachments = url_attachments.format(object_id, message_id)
response = requests.request("GET", url_attachments, headers=headers, data=payload)
val = response.json()["value"]
for i in range(len(val)):
attachment_id = val[i]["id"]
attachment_name = val[i]["name"]
attachment_content_type = val[i]["contentType"]
content_bytes = val[i]["contentBytes"]
base64String = content_bytes
with open(base_path+attachment_name, 'wb') as theFile:
theFile.write(base64.b64decode(base64String))

Reddit API Authentication Issue (OAuth)

The following code throws a 401 error and the access_token does not get retrieved. It seems like https://www.reddit.com/api/v1/access_token is rejecting the username/password or clientID/Secretkey that I have provided. But all that info is correct, the username and password is absolutely same as the Reddit login details, and the client ID & Secret key are directly a copy-paste from a dev app created here: https://www.reddit.com/prefs/apps
Please suggest what could be wrong
import requests
auth = requests.auth.HTTPBasicAuth('<client_id>', '<client_secret>')
data = {'grant_type': 'password','username': 'username','password': 'password'}
headers = {'User-Agent': 'ApiTest/0.0.1'}
res = requests.post('https://www.reddit.com/api/v1/access_token',auth=auth, data=data, headers=headers)
if "Unauthorized" in res.text:
print('401 error occured')
TOKEN = res.json()['access_token']
headers = {**headers, **{'Authorization': f"bearer {TOKEN}"}}
requests.get('https://oauth.reddit.com/api/v1/me', headers=headers)
Try to change from bearer to Bearer in your headers. You can also remove the **.
Should be something like this:
headers = {'Authorization': f"Bearer {TOKEN}"}

Basic Authentication returns 401 Client Error but works in postman

I have gone through number of similar posts related to firing GET requests with Basic Auth (eg: Python, HTTPS GET with basic authentication), still can't figure out the problem. I keep getting the error requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url
With the same credentials, headers tried the same in postman it works as expected. Verified that base64encoded value for the api_key, password is exactly same as the value used in postman, so I don't think its encoding or resource access permission problem.
python -V
Python 3.6.4 :: Anaconda, Inc.
Approach 1
api_key = 'some_api_key'
password = 'some_password'
headers = {'accept': 'application/json'}
url = 'https://test.access.com/this/url'
api_key_password = "%s:%s" % (api_key, password)
b64_encoded = b64encode(bytes(api_key_password, 'utf-8')).decode("ascii")
headers['authorization'] = 'Basic %s' % b64_encoded
response = requests.get(url,
headers=headers)
if (response.ok):
json_data = json.loads(response.content)
print (json_data)
else:
print (response)
response.raise_for_status()
Approach 2
api_key = 'some_api_key'
password = 'some_password'
url = 'https://test.access.com/this/url'
headers = {
'accept': 'application/json',
}
response = requests.get(url, headers=headers, auth=(api_key, password))
print (response.ok)
if (response.ok):
json_data = json.loads(response.content)
print (json_data)
else:
print (response)
response.raise_for_status()
Can you please provide some pointers?
I had a similar issue (although in .NET Framework).
In my case the reason was that I was using the url without a forward slash in the end and the API apparently does not support that.
So https://test.access.com/this/url
Throws 401 error Unauthorized
but
https://test.access.com/this/url/
Returns 200 OK.
Older post but I had a similar issue. Postman will cache your JSESSIONID. Be sure you are clearing out that cookie while testing. If you are hitting an API that requires a login API call to establish a session before you can make subsequent API calls, this Postman behavior can produce a false sense of security.
In this situation with Python requests, it can be handled with code similar to what I've provided below:
import requests,json
loginAPI = "https://myapi.myco.comv/someuri/someuri/users/login"
someHTTPGetAPI = "https://myapi.myco.com/someuri/someuri/someservice"
username = "myuser"
password = "mypass"
headers = {
"Content-Type": "application/json",
"login": username,
"password": password
}
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
verify=False
session = requests.Session()
sessionResponse = session.get(url=loginURL,headers=headers, verify=verify)
if sessionResponse.status_code == 200:
getResponse = session.get(url=someHTTPGetAPI)
if getResponse.status_code == 200:
responseJSON = agentStatus.json()

Azure Access Token Request returning HTML

I am trying to request an authorization code as documented here.
I am using Python requests package to do this and have the following example code:
import requests
auth_endpoint = 'https://login.microsoftonline.com/%s/oauth2/authorize?api-version=1.0' % TENANT_ID
payload = {
'client_id': CLIENT_ID,
'response_type': 'code',
'resource': APP_ID_URI,
'redirect_uri': REPLY_URL
}
response = requests.get(url=auth_endpoint, data=payload)
However, when I run the code above, I get back HTML in the body and not the response I'm expecting. It seems like the HTML code is for a login page.
When I take the formatted endpoint URI and plug it into a browser, I am able to get the auth code from the redirect URI. But, is there a way to get this from the body of the response while still using the requests package?
Please use session class of requests module to implement your requirement. Please refer to the following code sample:
import requests
s = requests.Session()
USERNAME = '<username_email>'
PASSWORD = '<userpassword>'
s.auth = (USERNAME, PASSWORD)
TENANT_ID = '<tenant_id>'
# Authorize URL
authorize_url = 'https://login.microsoftonline.com/%s/oauth2/authorize' % TENANT_ID
# Token endpoint.
token_url = 'https://login.microsoftonline.com/%s/oauth2/token' % TENANT_ID
payload = { 'response_type': 'code',
'client_id': '<tenant_id>',
'redirect_uri': 'http://localhost',
'authority' :'authority'
}
response = s.get(authorize_url, params=payload ,allow_redirects=True)
print response
print response.url
Any further concern, please feel free to let me know.

"Error parsing JSON" when using Spotify API

I am learning Python and I am trying to create a playlist using the Spotify web api but get a http 400 error: Error parsing json. I guess it has to do with an incorrect variable type in the token but I am having a really hard time debugging it as I can't figure out a way to see the post request in raw format.
Posting through the API requires authorizing and this is the script I've created for that:
import requests
import base64
requests.packages.urllib3.disable_warnings()
client_id = 'ID'
client_secret = 'SECRET'
redirect_uri = 'http://spotify.com/'
scope = 'playlist-modify-private playlist-read-private'
def request_token():
# 1. Your application requests authorization
auth_url = 'https://accounts.spotify.com/authorize'
payload = {'client_id': client_id, 'response_type':'code','redirect_uri':redirect_uri}
auth = requests.get(auth_url,params = payload)
print '\nPlease go to this url to authorize ', auth.url
# 2. The user is asked to authorize access within the scopes
# 3. The user is redirected back to your specified URI
resp_url = raw_input('\nThen please copy-paste the url you where redirected to: ')
resp_code= resp_url.split("?code=")[1].split("&")[0]
# 4. Your application requests refresh and access tokens
token_url = 'https://accounts.spotify.com/api/token'
payload = {'redirect_uri': redirect_uri,'code': resp_code, 'grant_type': 'authorization_code','scope':scope}
auth_header = base64.b64encode(client_id + ':' + client_secret)
headers = {'Authorization': 'Basic %s' % auth_header}
req = requests.post(token_url, data=payload, headers=headers, verify=True)
response = req.json()
return response
This is the function actually trying to create the playlist using the authorization token (import authorizer is the function above):
import requests
import authorizer
def create_playlist(username, list_name):
token = authorizer.request_token()
access_token = token['access_token']
auth_header = {'Authorization': 'Bearer {token}'.format(token=access_token), 'Content-Type': 'application/json'}
api_url = 'https://api.spotify.com/v1/users/%s/playlists' % username
payload = {'name': list_name, 'public': 'false'}
r = requests.post(api_url, params=payload, headers=auth_header)
But whatever I try it only leads to a 400 error. Can anyone please point out my error here?
Solved by adding a json.dumps for the input: json.dumps(payload) and changing the payload to be 'data' and not 'params' in the request.
So the new functioning request equals:
r = requests.post(api_url, data=json.dumps(payload), headers=auth_header)

Categories

Resources