API Navigator Logo

Python API Token Refresh Example

Author: Newtum

This example illustrates a common pattern for automatically refreshing an expired access token (like an OAuth2 token) when an API request fails with an authentication error.

Token Refresh Logic

The logic is as follows: make a request with the current token. If it fails with a `401 Unauthorized` error, attempt to get a new token using a refresh token. If the refresh is successful, retry the original request with the new token.

import requests

# --- Store your tokens (in a real app, this would be more secure) ---
ACCESS_TOKEN = "expired_or_invalid_token"
REFRESH_TOKEN = "valid_refresh_token"
TOKEN_URL = "https://your-auth-server.com/oauth/token"

def refresh_access_token():
    """Simulates refreshing the access token."""
    print("Attempting to refresh the access token...")
    # In a real implementation:
    # payload = {'grant_type': 'refresh_token', 'refresh_token': REFRESH_TOKEN}
    # response = requests.post(TOKEN_URL, data=payload)
    # response.raise_for_status()
    # new_token = response.json()['access_token']
    # return new_token
    
    # For this example, we'll just return a new dummy token.
    new_token = "new_shiny_access_token"
    print("Token refreshed successfully.")
    return new_token

def get_protected_data():
    global ACCESS_TOKEN
    url = "https://my-api.com/data"
    headers = {'Authorization': f'Bearer {ACCESS_TOKEN}'}
    
    # --- This part would be a real API call ---
    # response = requests.get(url, headers=headers)
    
    # --- We simulate a 401 response initially ---
    print(f"Making request with token: {ACCESS_TOKEN}")
    response_status_code = 401 # Simulate failure
    
    if response_status_code == 401:
        print("Access token expired or invalid (401).")
        try:
            ACCESS_TOKEN = refresh_access_token()
            headers['Authorization'] = f'Bearer {ACCESS_TOKEN}'
            
            # --- Retry the request with the new token ---
            print(f"Retrying request with new token: {ACCESS_TOKEN}")
            # response = requests.get(url, headers=headers)
            # response.raise_for_status()
            
            # --- Simulate success on the retry ---
            print("Request successful on retry!")
            return {"data": "super secret data"}
        except Exception as e:
            print(f"Failed to refresh token or retry request: {e}")
            return None

get_protected_data()