Requests-OAuthlib

raw JSON →
2.0.0 verified Tue May 12 auth: no python install: verified quickstart: stale

Requests-OAuthlib provides first-class OAuth 1.0 and OAuth 2.0 authentication support for the popular Python Requests HTTP library. It leverages the OAuthlib framework to offer an easy-to-use interface for building OAuth clients, simplifying the complexities of OAuth workflows. The library is actively maintained, with a typical release cadence driven by updates to the underlying OAuthlib library and security best practices.

pip install requests requests-oauthlib
breaking Version 2.0.0 dropped support for Python 2.x and Python versions older than 3.7. Users on older Python versions must remain on requests-oauthlib < 2.0.0 or upgrade their Python environment.
fix Upgrade Python to 3.7+ or use requests-oauthlib version 1.x.x.
breaking Requests-oauthlib 2.0.0 (and its underlying dependency oauthlib 3.x.x) strictly enforces HTTPS for all OAuth 2.0 authorization endpoints. Attempting to use HTTP will raise an `InsecureTransportError`.
fix Ensure all OAuth 2.0 endpoints (authorization_base_url, token_url, etc.) use `https://`. For local testing, set the environment variable `OAUTHLIB_INSECURE_TRANSPORT='1'` (never in production).
deprecated The Implicit Grant and Resource Owner Password Credentials (ROPC) flows are considered insecure and are formally deprecated in OAuth 2.1. While requests-oauthlib might still support them for OAuth 2.0, it's strongly recommended to migrate to the Authorization Code Flow, especially with PKCE for public clients (SPAs, mobile apps).
fix Adopt the Authorization Code Grant flow, preferably with PKCE, for new implementations and migrate existing flows away from Implicit and ROPC grants.
gotcha OAuth 2.1 (which modern implementations aim for) requires exact matching of `redirect_uri`. Using wildcard or partial matching for `redirect_uri` can lead to open redirect vulnerabilities.
fix Always register and use exact, specific `redirect_uri` values with your OAuth provider. Avoid patterns or wildcards in production environments.
gotcha Properly managing `expires_in` for access tokens is crucial for automatic token refreshing. If `expires_in` is not accurately provided by the OAuth provider, requests-oauthlib cannot reliably determine token expiration, impacting refresh logic.
fix Ensure your OAuth provider's token response includes an accurate `expires_in` parameter. If not, implement custom logic to manage token expiration and refreshing.
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.68s 22.8M
3.10 slim (glibc) - - 0.48s 23M
3.11 alpine (musl) - - 0.85s 25.0M
3.11 slim (glibc) - - 0.69s 25M
3.12 alpine (musl) - - 0.77s 16.7M
3.12 slim (glibc) - - 0.74s 17M
3.13 alpine (musl) - - 0.72s 16.4M
3.13 slim (glibc) - - 0.73s 17M
3.9 alpine (musl) - - 0.59s 22.1M
3.9 slim (glibc) - - 0.54s 23M

Demonstrates the OAuth 2.0 Authorization Code Grant flow using `OAuth2Session` to obtain an access token. This example simulates a web application flow, where the user is manually prompted to visit the authorization URL and paste the resulting redirect URL. In a real application, this would involve a web framework (like Flask or Django) handling the redirects automatically. Remember to set `OAUTH_CLIENT_ID` and `OAUTH_CLIENT_SECRET` as environment variables or replace placeholders.

import os
from requests_oauthlib import OAuth2Session

# Replace with your actual client ID and secret from your OAuth provider
CLIENT_ID = os.environ.get('OAUTH_CLIENT_ID', 'your_client_id')
CLIENT_SECRET = os.environ.get('OAUTH_CLIENT_SECRET', 'your_client_secret')

# These URLs are specific to your OAuth provider (e.g., GitHub, Google)
AUTHORIZATION_BASE_URL = 'https://github.com/login/oauth/authorize'
TOKEN_URL = 'https://github.com/login/oauth/access_token'
REDIRECT_URI = 'http://localhost:5000/callback'
SCOPE = ['user'] # Example scope for GitHub

def get_authorization_url():
    """Step 1: Get the authorization URL to redirect the user."""
    github = OAuth2Session(CLIENT_ID, redirect_uri=REDIRECT_URI, scope=SCOPE)
    authorization_url, state = github.authorization_url(AUTHORIZATION_BASE_URL)
    print(f"Please go to {authorization_url} and authorize access.")
    print(f"Store this state parameter for callback validation: {state}")
    return authorization_url, state

def fetch_token_from_callback(authorization_response_url, stored_state):
    """Step 2 & 3: Exchange the authorization code for an access token.
       In a real web app, authorization_response_url comes from the redirect callback.
    """
    github = OAuth2Session(CLIENT_ID, state=stored_state, redirect_uri=REDIRECT_URI)
    try:
        token = github.fetch_token(TOKEN_URL,
                                   client_secret=CLIENT_SECRET,
                                   authorization_response=authorization_response_url)
        print(f"Access Token obtained: {token}")
        # Now you can use the 'github' session to make API calls
        user_info = github.get('https://api.github.com/user').json()
        print(f"Authenticated user info: {user_info}")
        return token, user_info
    except Exception as e:
        print(f"Error fetching token: {e}")
        return None, None

if __name__ == "__main__":
    auth_url, initial_state = get_authorization_url()
    # In a real application, you would redirect the user to auth_url
    # and then capture the full redirect URL (authorization_response_url)
    # from their browser after they authorize your application.
    print("\n--- Manual Step Required ---")
    print("1. Open the URL printed above in your browser.")
    print("2. Authorize the application.")
    print("3. After authorization, copy the full URL from your browser's address bar.")
    print("   (It will likely be http://localhost:5000/callback?code=...&state=...)")
    authorization_response = input("\nEnter the full redirect URL here: ")

    # Simulate callback handling
    if authorization_response:
        fetch_token_from_callback(authorization_response, initial_state)
    else:
        print("No authorization response provided. Exiting.")