To access many APIs you need to use OAuth2, sending a client id and secret to an endpoint to get a token back. Then send that token with future calls as authentication.
The particular API I was calling would also return a number of seconds the bearer token would be good for.
Hopefully this code will help jumpstart someone else along the way to using python and APIs.
#!/usr/bin/env python3
import requests
import json
import datetime
import os.path
from os import path
cache_file = "/var/tmp/oauth.json"
client_id = '**your client_id here**'
client_secret = '**your secret here**'
def getToken():
url = "https://api.wherever.com/oauth2/token"
data = {
'client_id': client_id,
'client_secret': client_secret,
'grant_type': 'client_credentials'
}
response = requests.post(url, data=data)
data = json.loads(response.text)
expiration_time = datetime.datetime.now() + datetime.timedelta(seconds=data['expires_in'])
data['expiration_date'] = int(expiration_time.utcnow().timestamp())
with open(cache_file, "w") as outfile:
json.dump(data, outfile)
return data
if path.exists(cache_file):
#Reading cache
with open(cache_file, "r") as infile:
access_token = json.load(infile)
if int(datetime.datetime.now().timestamp()) > access_token['expiration_date']:
#Token expired, get new
access_token = getToken()
else:
#No cached value, get and cache
access_token = getToken()
bearer_token = access_token["access_token"]
headers = {
'Authorization': f'bearer {bearer_token}'
}
#The rest of the requests go here and pass that header
4/24/2023: updated to fix typo!
Hello,
Thanks for the write up. Two things I’d thought I’d bring to your attention:
1) When adding the time delta given by the “expires_in” field when calculating the “expiration_time” variable, the data[“expires_in”], depending on the OAuth provider, returns a string, as opposed to an integer. Might be worth adding relevant type checks.
2) There is a typo in “acces_token” in your token expired conditional.
Cheers
LikeLike