Using the refresh token in Python

Jump to solution
bbennett2
Community Champion

I'm having trouble using the refresh token in a Python script to get a new access token for a user after the hour expires. I'm using the `requests_oauthlib` library to handle token calls.

I'm able to get the initial token and store it for a user along with the refresh token. Has anyone done this and, if so, would you be willing to share a working code sample?

Here's my Flask route:

from requests_oauthlib import OAuth2Session

@app.route('/')
@app.route('/index')
def index():

# check that the user exists. If so, log in.
if not current_user.is_anonymous:

# Update the session if a refresh is needed
def token_updater(token):
session['oauth_token'] = token
current_user.token = session['oauth_token']

# Check the user's refresh token
if current_user.expiration < time.time():

extra = {
'grant_type': 'refresh_token'
}

token = OAuth2Session(app.config['OAUTH_CREDENTIALS']['canvas']['id'],
token=current_user.refresh_token,
auto_refresh_kwargs=extra,
auto_refresh_url=app.config['OAUTH_CREDENTIALS']['canvas']['token_url'],
token_updater=token_updater)

return redirect(url_for('dashboard'))

else:
# Start the OAuth2 login flow if the user does not exist.
# This part works fine.
return render_template('login.html')‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Labels (1)
0 Likes
1 Solution
bbennett2
Community Champion

All it takes is posting the question to find the answer.

I needed to scope a new OAuth2Session with the client ID and current token rather than the callback URL from the global instance.

Here's my final working logic (in case anyone else is in the same boat):

from requests_oauthlib import OAuth2Session
import requests
import time
... other imports ...

@app.route('/')
@app.route('/index')
def index():

# The user exists, try a login
if not current_user.is_anonymous:

# get the current token expiration
expire = session['oauth_token']['expires_at']

# Oh no! The token has expired. Get a new one.
if time.time() > expire:

# get a the old access token
token = session['oauth_token']
client_id = '123456'
refresh_url = 'https://yourcanvas.instructure.com/login/oauth2/token'

# the library uses `extra` as **kwargs in the refresh method
extra = {
'client_id': client_id,
'client_secret': 'your_big_secret',
'refresh_token': token['refresh_token'],
}

# Instantiate a new session.
# This is important because you need to pass the existing token instead
# of the token URL to the refresh method rather than the callback URI.
oauth_refresh = OAuth2Session(client_id, token=token)

# request a new access token with the refresh token
session['oauth_token'] = oauth_refresh.refresh_token(refresh_url, **extra)

# If the token isn't expired OR
# once you have a new access token, redirect to the app dashboard
return redirect(url_for('dashboard'))
else:
# This user isn't logged in. Start OAuth2 fresh.
return render_template('login.html')

View solution in original post