### Provider Quick Start Examples Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Provides setup and basic usage examples for integrating with various OAuth2 providers. Each snippet is tailored to a specific provider's requirements. ```Python # Example for GitHub OAuth2 from httpx_oauth.clients.github import GitHubOAuth2 client = GitHubOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python # Example for Facebook OAuth2 from httpx_oauth.clients.facebook import FacebookOAuth2 client = FacebookOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python # Example for Discord OAuth2 from httpx_oauth.clients.discord import DiscordOAuth2 client = DiscordOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python # Example for Slack OAuth2 from httpx_oauth.clients.slack import SlackOAuth2 client = SlackOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python # Example for Microsoft Live OAuth2 from httpx_oauth.clients.microsoft import MicrosoftLiveOAuth2 client = MicrosoftLiveOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python # Example for Dropbox OAuth2 from httpx_oauth.clients.dropbox import DropboxOAuth2 client = DropboxOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python # Example for Reddit OAuth2 from httpx_oauth.clients.reddit import RedditOAuth2 client = RedditOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python # Example for Okta OAuth2 from httpx_oauth.clients.okta import OktaOAuth2 client = OktaOAuth2("YOUR_ORG_URL", "YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` -------------------------------- ### Install httpx-oauth Source: https://github.com/frankie567/httpx-oauth/blob/master/README.md Install the httpx-oauth package using pip. This is the primary method for adding the library to your project. ```bash pip install httpx-oauth ``` -------------------------------- ### FastAPI Integration Examples Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Demonstrates how to integrate httpx-oauth with FastAPI applications. These examples show setting up authentication endpoints and handling callbacks. ```Python from fastapi import FastAPI from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback from httpx_oauth.clients.google import GoogleOAuth2 app = FastAPI() client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # Define the callback endpoint callback_endpoint = OAuth2AuthorizeCallback(app, client, "http://localhost:8000/callback") @app.get("/login/google") async def login_google(): return await callback_endpoint.login( redirect_uri="http://localhost:8000/callback", scope=["email", "profile"], ) ``` ```Python from fastapi import FastAPI from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback from httpx_oauth.clients.google import GoogleOAuth2 app = FastAPI() client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # Define the callback endpoint callback_endpoint = OAuth2AuthorizeCallback(app, client, "http://localhost:8000/callback") @app.get("/callback") async def callback_google(request: Request): token = await callback_endpoint.callback(request) return {"access_token": token["access_token"]} ``` ```Python from fastapi import FastAPI, Request from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback from httpx_oauth.clients.google import GoogleOAuth2 app = FastAPI() client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # Define the callback endpoint callback_endpoint = OAuth2AuthorizeCallback(app, client, "http://localhost:8000/callback") @app.get("/login/google") async def login_google(): return await callback_endpoint.login( redirect_uri="http://localhost:8000/callback", scope=["email", "profile"], ) @app.get("/callback") async def callback_google(request: Request): token = await callback_endpoint.callback(request) # Use token to fetch user info or perform other actions user_id, user_email = await client.get_id_email(token["access_token"]) return {"user_id": user_id, "user_email": user_email} ``` ```Python from fastapi import FastAPI, Request from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback from httpx_oauth.clients.github import GitHubOAuth2 app = FastAPI() client = GitHubOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") callback_endpoint = OAuth2AuthorizeCallback(app, client, "http://localhost:8000/callback") @app.get("/login/github") async def login_github(): return await callback_endpoint.login( redirect_uri="http://localhost:8000/callback", scope=["read:user", "user:email"], ) @app.get("/callback") async def callback_github(request: Request): token = await callback_endpoint.callback(request) user_data = await client.get_profile(token["access_token"]) return {"username": user_data["login"]} ``` ```Python from fastapi import FastAPI, Request from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback from httpx_oauth.clients.google import GoogleOAuth2 app = FastAPI() client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") callback_endpoint = OAuth2AuthorizeCallback(app, client, "http://localhost:8000/callback") @app.get("/login/google") async def login_google(): return await callback_endpoint.login( redirect_uri="http://localhost:8000/callback", scope=["email", "profile"], extras_params={"access_type": "offline"} ) @app.get("/callback") async def callback_google(request: Request): token = await callback_endpoint.callback(request) # The token might contain a refresh token if requested return {"token": token} ``` ```Python from fastapi import FastAPI, Request from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback from httpx_oauth.clients.google import GoogleOAuth2 app = FastAPI() client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") callback_endpoint = OAuth2AuthorizeCallback(app, client, "http://localhost:8000/callback") @app.get("/login/google") async def login_google(): return await callback_endpoint.login( redirect_uri="http://localhost:8000/callback", scope=["email", "profile"], state="some-random-string-or-uuid" ) @app.get("/callback") async def callback_google(request: Request): token = await callback_endpoint.callback(request) # Validate the state parameter if it was used return {"token": token} ``` ```Python from fastapi import FastAPI, Request from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback from httpx_oauth.clients.google import GoogleOAuth2 app = FastAPI() client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") callback_endpoint = OAuth2AuthorizeCallback(app, client, "http://localhost:8000/callback") @app.get("/login/google") async def login_google(): return await callback_endpoint.login( redirect_uri="http://localhost:8000/callback", scope=["email", "profile"], prompt="select_account" ) @app.get("/callback") async def callback_google(request: Request): token = await callback_endpoint.callback(request) return {"token": token} ``` ```Python from fastapi import FastAPI, Request from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback from httpx_oauth.clients.google import GoogleOAuth2 app = FastAPI() client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") callback_endpoint = OAuth2AuthorizeCallback(app, client, "http://localhost:8000/callback") @app.get("/login/google") async def login_google(): return await callback_endpoint.login( redirect_uri="http://localhost:8000/callback", scope=["email", "profile"], # Example of passing additional parameters extras_params={"hd": "example.com"} ) @app.get("/callback") async def callback_google(request: Request): token = await callback_endpoint.callback(request) return {"token": token} ``` -------------------------------- ### Instantiate BaseOAuth2 Client Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/api-reference/oauth2.md Example of creating an instance of the BaseOAuth2 client with specific provider details. ```python from httpx_oauth.oauth2 import BaseOAuth2 client = BaseOAuth2( client_id="your_client_id", client_secret="your_client_secret", authorize_endpoint="https://example.com/authorize", access_token_endpoint="https://example.com/token", refresh_token_endpoint="https://example.com/refresh", revoke_token_endpoint="https://example.com/revoke", base_scopes=["profile", "email"], ) ``` -------------------------------- ### Full FastAPI OAuth2 Integration Example Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/api-reference/fastapi-integration.md A complete example demonstrating how to set up a FastAPI application with httpx-oauth for Google OAuth2, including login and callback routes. ```python from fastapi import FastAPI, Depends, HTTPException from httpx_oauth.oauth2 import OAuth2 from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback app = FastAPI() google_client = OAuth2( client_id="google_client_id", client_secret="google_client_secret", authorize_endpoint="https://accounts.google.com/o/oauth2/v2/auth", access_token_endpoint="https://oauth2.googleapis.com/token", ) oauth_callback = OAuth2AuthorizeCallback( google_client, redirect_url="https://myapp.com/oauth-callback", ) @app.get("/login") async def login(): # Redirect user to Google authorization auth_url = await google_client.get_authorization_url( redirect_uri="https://myapp.com/oauth-callback", state="random_state_value", scope=["openid", "profile", "email"], ) return {"auth_url": auth_url} @app.get("/oauth-callback") async def handle_callback( access_token_state=Depends(oauth_callback), ): token, state = access_token_state # Token is now available access_token = token["access_token"] # You can now use the token to fetch user info # or store it in a session return {"status": "authenticated"} ``` -------------------------------- ### Step 5: Use Token to Get User Info Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/api-reference/fastapi-integration.md After obtaining an access token, use it to fetch user information from the provider's API. This example shows how to get the user's ID and email from Google. ```python @app.get("/user") async def get_user(access_token: str): user_id, user_email = await google_client.get_id_email(access_token) return {"id": user_id, "email": user_email} ``` -------------------------------- ### Generic OAuth2 Client Setup Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/quick-reference.md Initialize a generic OAuth2 client with necessary endpoints and credentials. ```python from httpx_oauth.oauth2 import OAuth2 client = OAuth2( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", authorize_endpoint="https://provider.com/authorize", access_token_endpoint="https://provider.com/token", ) ``` -------------------------------- ### OpenID Connect Client Setup Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/quick-reference.md Initialize a generic OpenID Connect client using its configuration endpoint. ```python from httpx_oauth.clients.openid import OpenID client = OpenID( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", openid_configuration_endpoint="https://example.com/.well-known/openid-configuration", ) ``` -------------------------------- ### Basic OAuth2 Flow Examples Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Illustrates the fundamental OAuth2 authorization code flow. These examples demonstrate the core usage patterns for integrating OAuth2 authentication. ```Python from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") authorization_url = await client.get_authorization_url( "http://localhost:8000/callback", scope=["email", "profile"], extras_params={ "prompt": "consent" }, ) print(f"Please go to this URL: {authorization_url}") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") token = await client.get_access_token("http://localhost:8000/callback?code=CODE") print(f"Access token: {token['access_token']}") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") user_id, user_email = await client.get_id_email("ACCESS_TOKEN") print(f"User ID: {user_id}, Email: {user_email}") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") profile = await client.get_profile("ACCESS_TOKEN") print(f"User profile: {profile}") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") refresh_token = await client.refresh_token("REFRESH_TOKEN") print(f"New access token: {refresh_token['access_token']}") ``` -------------------------------- ### Type Hints Examples Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Showcases the use of type hints in httpx-oauth for improved code clarity and maintainability. These examples leverage Python's typing system. ```Python from typing import List, Dict, Any from httpx_oauth.clients.google import GoogleOAuth2 client: GoogleOAuth2 = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") async def get_user_info(access_token: str) -> Dict[str, Any]: user_id, user_email = await client.get_id_email(access_token) profile_data = await client.get_profile(access_token) return { "user_id": user_id, "email": user_email, "profile": profile_data } ``` ```Python from typing import List, Dict, Any from httpx_oauth.oauth2 import OAuth2Token async def process_token(token: OAuth2Token) -> None: access_token: str = token["access_token"] expires_in: int = token["expires_in"] print(f"Access token: {access_token[:10]}...\nExpires in: {expires_in} seconds") # Further processing of the token ``` ```Python from typing import List, Dict, Any from httpx_oauth.clients.github import GitHubOAuth2 client: GitHubOAuth2 = GitHubOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") async def get_github_profile(access_token: str) -> Dict[str, Any]: profile: Dict[str, Any] = await client.get_profile(access_token) return profile ``` ```Python from typing import List, Dict, Any, Optional from httpx_oauth.clients.google import GoogleOAuth2 client: GoogleOAuth2 = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") async def get_token_with_refresh(code: str, redirect_uri: str) -> Optional[Dict[str, Any]]: try: token: Dict[str, Any] = await client.get_access_token(redirect_uri, code) return token except Exception as e: print(f"Error getting token: {e}") return None ``` -------------------------------- ### GitHub OAuth2 Client Setup Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/quick-reference.md Initialize the GitHub OAuth2 client with your application ID and secret. ```python from httpx_oauth.clients.github import GitHubOAuth2 client = GitHubOAuth2( client_id="YOUR_GITHUB_APP_ID", client_secret="YOUR_GITHUB_APP_SECRET", ) ``` -------------------------------- ### Configuration Examples Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Illustrates various ways to configure httpx-oauth clients, including setting client IDs, secrets, scopes, and provider-specific parameters. ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Basic configuration with client ID and secret client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Configuration with specific scopes client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") scopes = ["email", "profile", "openid"] authorization_url = await client.get_authorization_url("http://localhost:8000/callback", scope=scopes) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Configuration with extra parameters for authorization URL client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") extras = {"prompt": "consent", "access_type": "offline"} authorization_url = await client.get_authorization_url("http://localhost:8000/callback", extras_params=extras) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Configuration for Okta provider requires organization URL client = GoogleOAuth2("YOUR_ORG_URL", "YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # Note: This is an example, Okta client is separate # Correct Okta client usage would be: # from httpx_oauth.clients.okta import OktaOAuth2 # client = OktaOAuth2("YOUR_ORG_URL", "YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Using environment variables for configuration import os client_id = os.environ.get("GOOGLE_CLIENT_ID") client_secret = os.environ.get("GOOGLE_CLIENT_SECRET") client = GoogleOAuth2(client_id, client_secret) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Customizing token endpoint URL (rarely needed) client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") client.token_endpoint = "https://custom.token.endpoint/oauth2/token" ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Configuring for a specific domain (e.g., Google Workspace) client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") authorization_url = await client.get_authorization_url( "http://localhost:8000/callback", scope=["email", "profile"], extras_params={"hd": "yourdomain.com"} ) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Using a custom httpx.AsyncClient instance import httpx custom_client = httpx.AsyncClient(timeout=30.0) client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", client=custom_client) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Configuration for refresh token request parameters client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # The refresh_token method accepts additional parameters if needed by the provider # For example, if a specific scope is required for refresh # new_token = await client.refresh_token("REFRESH_TOKEN", scope="offline") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Setting a custom redirect URI for the callback client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") redirect_uri = "https://myapp.com/auth/callback" authorization_url = await client.get_authorization_url(redirect_uri) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Specifying authorization parameters for specific scopes client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") authorization_url = await client.get_authorization_url( "http://localhost:8000/callback", scope=["email", "profile"], extras_params={"prompt": "select_account"} ) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Configuring client for different grant types (e.g., client credentials) # Note: httpx-oauth primarily focuses on authorization code flow. # Client credentials flow would typically use a different method or client. # Example for Google's client credentials (if supported and configured): # client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # token = await client.get_client_credentials_token() # This method might not be directly available or applicable for all providers. ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Setting a custom user agent for HTTP requests import httpx custom_headers = {"User-Agent": "MyOAuthApp/1.0"} custom_client = httpx.AsyncClient(headers=custom_headers) client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", client=custom_client) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Configuring parameters for the token exchange request client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # The get_access_token method can accept additional parameters # For example, if the provider requires a specific parameter during token exchange # token = await client.get_access_token("CODE", "http://localhost:8000/callback", additional_param="value") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Using a different base URL for the OAuth2 provider (e.g., self-hosted) client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") client.base_url = "https://my.oauth.provider.com/oauth2/" ``` -------------------------------- ### Google OAuth2 Client Setup Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/quick-reference.md Initialize the Google OAuth2 client with your client ID and secret. ```python from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2( client_id="YOUR_CLIENT_ID.apps.googleusercontent.com", client_secret="YOUR_CLIENT_SECRET", ) ``` -------------------------------- ### Okta OAuth2 Client Setup Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/quick-reference.md Initialize the Okta OAuth2 client with your client ID, secret, and Okta domain. ```python from httpx_oauth.clients.okta import OktaOAuth2 client = OktaOAuth2( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", okta_domain="example.okta.com", ) ``` -------------------------------- ### Discord OAuth2 Client Setup Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/quick-reference.md Initialize the Discord OAuth2 client with your client ID and secret. ```python from httpx_oauth.clients.discord import DiscordOAuth2 client = DiscordOAuth2( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", ) ``` -------------------------------- ### Shopify OAuth2 Client Setup Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/quick-reference.md Initialize the Shopify OAuth2 client with your client ID, secret, and shop name. ```python from httpx_oauth.clients.shopify import ShopifyOAuth2 client = ShopifyOAuth2( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", shop="myshop", # Your shop name ) ``` -------------------------------- ### OAuth2ClientAuthMethod Usage Example Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/types.md Shows how to configure a BaseOAuth2 client with a specific token endpoint authentication method. ```python from httpx_oauth.oauth2 import OAuth2ClientAuthMethod, BaseOAuth2 client = BaseOAuth2( client_id="id", client_secret="secret", authorize_endpoint="https://example.com/authorize", access_token_endpoint="https://example.com/token", token_endpoint_auth_method="client_secret_post", # Must be one of the allowed values ) ``` -------------------------------- ### FastAPI OAuth2 Callback Usage Example Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/modules.md Example demonstrating how to use OAuth2AuthorizeCallback as a FastAPI dependency to handle OAuth2 callbacks. ```python from fastapi import FastAPI, Depends from httpx_oauth.clients.google import GoogleOAuth2 from httpx_oauth.integrations.fastapi import OAuth2AuthorizeCallback app = FastAPI() google = GoogleOAuth2(client_id="...", client_secret="...") oauth_callback = OAuth2AuthorizeCallback(google, route_name="oauth-callback") @app.get("/oauth-callback", name="oauth-callback") async def oauth_callback( token_state=Depends(oauth_callback), ): token, state = token_state return {"status": "success"} ``` -------------------------------- ### Generate Authorization URL with PKCE Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/configuration.md Example demonstrating the generation of an authorization URL using the Proof Key for Code Exchange (PKCE) flow. This involves generating a code verifier and challenge. ```python import secrets import base64 import hashlib # Generate PKCE challenge code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).decode('utf-8').rstrip('=') code_challenge = base64.urlsafe_b64encode( hashlib.sha256(code_verifier.encode()).digest() ).decode('utf-8').rstrip('=') auth_url = await client.get_authorization_url( redirect_uri="https://myapp.com/oauth-callback", code_challenge=code_challenge, code_challenge_method="S256", ) ``` -------------------------------- ### OAuth2Token Usage Example Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/types.md Demonstrates how to access token data and check for expiration using an OAuth2Token object. ```python token = await client.get_access_token(code, redirect_uri) # Access token data like a dictionary access_token_str = token["access_token"] # Check if token is expired if token.is_expired(): token = await client.refresh_token(token["refresh_token"]) ``` -------------------------------- ### ShopifyOAuth2AuthorizeParams Usage Example Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/types.md Demonstrates generating a Shopify authorization URL with the access_mode parameter. ```python from httpx_oauth.clients.shopify import ShopifyOAuth2 shopify_client = ShopifyOAuth2( client_id="id", client_secret="secret", shop="myshop", ) auth_url = await shopify_client.get_authorization_url( redirect_uri="https://example.com/callback", extras_params={"access_mode": "per-user"}, ) ``` -------------------------------- ### Common Patterns Examples Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Illustrates reusable patterns and best practices when using httpx-oauth, such as abstracting client logic or handling token storage. ```Python from httpx_oauth.clients.google import GoogleOAuth2 from typing import Dict, Any # Abstracting client creation and token management class OAuthManager: def __init__(self, client_id: str, client_secret: str): self.client = GoogleOAuth2(client_id, client_secret) self.token: Dict[str, Any] | None = None async def get_user_token(self, code: str, redirect_uri: str) -> Dict[str, Any]: if not self.token or self.is_token_expired(self.token): self.token = await self.client.get_access_token(redirect_uri, code) return self.token def is_token_expired(self, token: Dict[str, Any]) -> bool: # Basic expiration check logic import time if "expires_in" in token and "issued_at" in token: return time.time() > (token["issued_at"] + token["expires_in"]) return True # Usage: # manager = OAuthManager("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # token = await manager.get_user_token("AUTH_CODE", "http://localhost:8000/callback") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 from typing import Dict, Any # Centralized token storage and retrieval TOKEN_STORAGE: Dict[str, Dict[str, Any]] = {} async def get_stored_token(user_id: str, client: GoogleOAuth2) -> Dict[str, Any]: token_data = TOKEN_STORAGE.get(user_id) if token_data and not is_token_expired(token_data): return token_data else: # Handle token refresh or re-authentication # This is a simplified example; actual logic depends on refresh tokens raise Exception("Token expired or not found") def is_token_expired(token: Dict[str, Any]) -> bool: import time if "expires_in" in token and "issued_at" in token: return time.time() > (token["issued_at"] + token["expires_in"]) return True # Usage: # client = GoogleOAuth2(...) # token = await get_stored_token("user123", client) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Creating a client factory function def create_oauth_client(provider: str, client_id: str, client_secret: str) -> GoogleOAuth2: # Simplified return type if provider == "google": return GoogleOAuth2(client_id, client_secret) # Add other providers here else: raise ValueError(f"Unsupported provider: {provider}") # Usage: # google_client = create_oauth_client("google", "YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Handling token refresh automatically before use class AutoRefreshingClient: def __init__(self, client_id: str, client_secret: str): self.client = GoogleOAuth2(client_id, client_secret) self.token: Dict[str, Any] | None = None async def get_token(self) -> Dict[str, Any]: if self.token is None or self.is_token_expired(self.token): # Attempt to refresh if refresh token exists, otherwise re-authenticate if self.token and "refresh_token" in self.token: self.token = await self.client.refresh_token(self.token["refresh_token"]) else: # This part would involve initiating the authorization flow raise Exception("Token expired and no refresh token available. Re-authenticate.") return self.token def is_token_expired(self, token: Dict[str, Any]) -> bool: import time if "expires_in" in token and "issued_at" in token: return time.time() > (token["issued_at"] + token["expires_in"]) return True # Usage: # auto_client = AutoRefreshingClient("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # current_token = await auto_client.get_token() ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Using a context manager for httpx client lifecycle import httpx async def get_user_profile(access_token: str): async with httpx.AsyncClient() as http_client: client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", client=http_client) profile = await client.get_profile(access_token) return profile # Usage: # profile = await get_user_profile("ACCESS_TOKEN") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Implementing a simple token refresh mechanism within a wrapper class GoogleClientWrapper: def __init__(self, client_id: str, client_secret: str): self.client = GoogleOAuth2(client_id, client_secret) self.token: Dict[str, Any] | None = None async def get_access_token(self, code: str, redirect_uri: str) -> Dict[str, Any]: self.token = await self.client.get_access_token(redirect_uri, code) return self.token async def get_refreshed_token(self) -> Dict[str, Any]: if not self.token or "refresh_token" not in self.token: raise Exception("No refresh token available") self.token = await self.client.refresh_token(self.token["refresh_token"]) return self.token # Usage: # wrapper = GoogleClientWrapper("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") # token = await wrapper.get_access_token("CODE", "http://localhost:8000/callback") # if needs_refresh(token): # refreshed_token = await wrapper.get_refreshed_token() ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Storing token data including expiration timestamp import time async def get_and_store_token(client: GoogleOAuth2, code: str, redirect_uri: str): token_data = await client.get_access_token(redirect_uri, code) token_data["issued_at"] = time.time() # Store when the token was issued # Store token_data in your persistent storage (e.g., database) print(f"Token stored with issue time: {token_data}") return token_data # Usage: # client = GoogleOAuth2(...) # stored_token = await get_and_store_token(client, "AUTH_CODE", "http://localhost:8000/callback") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Dynamically selecting a client based on provider name def get_client(provider_name: str, client_id: str, client_secret: str): if provider_name == "google": return GoogleOAuth2(client_id, client_secret) # elif provider_name == "github": # from httpx_oauth.clients.github import GitHubOAuth2 # return GitHubOAuth2(client_id, client_secret) else: raise ValueError(f"Unknown provider: {provider_name}") # Usage: # client = get_client("google", "YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Handling different scopes based on user role or application needs async def get_authorization_url_for_role(client: GoogleOAuth2, redirect_uri: str, role: str): if role == "admin": scopes = ["email", "profile", "admin.google.com"] else: scopes = ["email", "profile"] return await client.get_authorization_url(redirect_uri, scope=scopes) # Usage: # client = GoogleOAuth2(...) # url = await get_authorization_url_for_role(client, "http://localhost:8000/callback", "admin") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Using a default client configuration DEFAULT_CLIENT_ID = "DEFAULT_CLIENT_ID" DEFAULT_CLIENT_SECRET = "DEFAULT_CLIENT_SECRET" def get_default_google_client() -> GoogleOAuth2: return GoogleOAuth2(DEFAULT_CLIENT_ID, DEFAULT_CLIENT_SECRET) # Usage: # client = get_default_google_client() ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Managing multiple client instances for different providers class MultiClientApp: def __init__(self): self.google_client = GoogleOAuth2("GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET") # self.github_client = GitHubOAuth2("GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET") async def login_with_google(self, redirect_uri: str): return await self.google_client.get_authorization_url(redirect_uri) # Usage: # app = MultiClientApp() # url = await app.login_with_google("http://localhost:8000/callback") ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Refreshing token and updating stored data async def refresh_and_update_token(client: GoogleOAuth2, stored_token: Dict[str, Any]) -> Dict[str, Any]: if "refresh_token" in stored_token: new_token_data = await client.refresh_token(stored_token["refresh_token"]) # Update the stored token with new data, including issued_at import time new_token_data["issued_at"] = time.time() # Persist new_token_data return new_token_data else: raise Exception("Cannot refresh token: no refresh token available.") # Usage: # client = GoogleOAuth2(...) # stored_token = {...} # updated_token = await refresh_and_update_token(client, stored_token) ``` ```Python from httpx_oauth.clients.google import GoogleOAuth2 # Handling token expiration gracefully async def get_user_data(client: GoogleOAuth2, token: Dict[str, Any]): import time if "expires_in" in token and "issued_at" in token: if time.time() > (token["issued_at"] + token["expires_in"]): print("Token expired, attempting refresh...") try: token = await client.refresh_token(token["refresh_token"]) # Update stored token except Exception as e: print(f"Failed to refresh token: {e}") return None # Indicate failure # Use the valid or refreshed token return await client.get_id_email(token["access_token"]) # Usage: # client = GoogleOAuth2(...) # token = {...} # retrieved token # user_info = await get_user_data(client, token) ``` -------------------------------- ### GoogleOAuth2AuthorizeParams Usage Example Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/types.md Shows how to generate a Google authorization URL with parameters like access_type, prompt, and login_hint. ```python from httpx_oauth.clients.google import GoogleOAuth2 google_client = GoogleOAuth2(client_id="id", client_secret="secret") auth_url = await google_client.get_authorization_url( redirect_uri="https://example.com/callback", extras_params={ "access_type": "offline", "prompt": "consent", "login_hint": "user@example.com", }, ) ``` -------------------------------- ### PKCE Flow Examples Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Demonstrates the Proof Key for Code Exchange (PKCE) flow, which enhances security for public clients like mobile apps and single-page applications. ```Python import asyncio from httpx_oauth.clients.google import GoogleOAuth2 async def pkce_flow(): client = GoogleOAuth2("YOUR_CLIENT_ID") # Client secret is not needed for PKCE with public clients redirect_uri = "http://localhost:8000/callback" # Generate code verifier and challenge code_verifier = client.generate_code_verifier() code_challenge = client.generate_code_challenge(code_verifier) authorization_url = await client.get_authorization_url( redirect_uri, scope=["email", "profile"], code_challenge=code_challenge, code_challenge_method="S256", # or "plain" ) print(f"Please go to this URL: {authorization_url}") # In a real app, you would redirect the user here and then handle the callback # For demonstration, we'll simulate the callback authorization_code = "AUTHORIZATION_CODE_FROM_CALLBACK" token = await client.get_access_token( redirect_uri, authorization_code, code_verifier=code_verifier # Pass the verifier to exchange the code ) print(f"Access token: {token['access_token']}") # asyncio.run(pkce_flow()) ``` ```Python import asyncio from httpx_oauth.clients.github import GitHubOAuth2 async def github_pkce_flow(): client = GitHubOAuth2("YOUR_CLIENT_ID") # Client secret not needed for PKCE redirect_uri = "http://localhost:8000/callback" code_verifier = client.generate_code_verifier() code_challenge = client.generate_code_challenge(code_verifier) authorization_url = await client.get_authorization_url( redirect_uri, scope=["read:user"], code_challenge=code_challenge, code_challenge_method="S256", ) print(f"Please go to this URL: {authorization_url}") # Simulate callback authorization_code = "GITHUB_AUTH_CODE" token = await client.get_access_token( redirect_uri, authorization_code, code_verifier=code_verifier ) print(f"Access token: {token['access_token']}") # asyncio.run(github_pkce_flow()) ``` ```Python import asyncio from httpx_oauth.clients.google import GoogleOAuth2 async def pkce_refresh_token(): client = GoogleOAuth2("YOUR_CLIENT_ID") redirect_uri = "http://localhost:8000/callback" code_verifier = client.generate_code_verifier() code_challenge = client.generate_code_challenge(code_verifier) authorization_url = await client.get_authorization_url(redirect_uri, code_challenge=code_challenge) print(f"Please go to this URL: {authorization_url}") # Simulate callback and token exchange authorization_code = "AUTH_CODE" token = await client.get_access_token(redirect_uri, authorization_code, code_verifier=code_verifier) # If the token response includes a refresh token (and it's a public client flow) refresh_token = token.get("refresh_token") if refresh_token: print("Received refresh token. Refreshing token...") # Note: Refreshing tokens in PKCE flow might have specific provider requirements # This example assumes the client can handle it directly if the provider allows new_token = await client.refresh_token(refresh_token) print(f"New access token: {new_token['access_token']}") else: print("No refresh token received.") # asyncio.run(pkce_refresh_token()) ``` -------------------------------- ### Generate Authorization URL Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/configuration.md Basic example of generating an authorization URL with specified redirect URI, state, and scopes. ```python auth_url = await client.get_authorization_url( redirect_uri="https://myapp.com/oauth-callback", state="random_state_string", scope=["profile", "email"], ) ``` -------------------------------- ### LinkedIn OAuth2 Client Setup Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/quick-reference.md Initialize the LinkedIn OAuth2 client with your client ID and secret. ```python from httpx_oauth.clients.linkedin import LinkedInOAuth2 client = LinkedInOAuth2( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", ) ``` -------------------------------- ### FastAPI Integration Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Examples and documentation for integrating httpx-oauth with FastAPI applications, including setting up endpoints for authorization and token callbacks. ```APIDOC ## FastAPI Integration ### Description Guides and examples for integrating httpx-oauth with FastAPI applications, enabling seamless OAuth2 authentication within web services. ### Key Components - **OAuth2AuthorizeCallback**: Used to handle the callback endpoint after user authorization. - **Client Setup**: Demonstrates how to instantiate and use provider-specific clients within FastAPI routes. ### Examples - 8 examples showcasing various integration patterns, including setting up authorization URLs, handling callbacks, and managing user sessions. - Refer to 'api-reference/fastapi-integration.md' for comprehensive details and code examples. ``` -------------------------------- ### Error Handling Examples Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/MANIFEST.txt Demonstrates how to handle various errors that can occur during the OAuth2 process. This includes catching specific exceptions and understanding their causes. ```Python from httpx_oauth.oauth2 import OAuth2Error try: # ... perform OAuth2 operation ... pass except OAuth2Error as e: print(f"OAuth2 error occurred: {e}") # Handle the error appropriately ``` ```Python from httpx_oauth.oauth2 import OAuth2Error from httpx_oauth.exceptions import OAuth2Exception try: # ... perform OAuth2 operation ... pass except OAuth2Exception as e: print(f"An OAuth2 related exception occurred: {e}") # Handle specific exceptions like InvalidGrantError, InvalidClientIdError etc. ``` ```Python from httpx_oauth.oauth2 import OAuth2Error from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") try: token = await client.get_access_token("invalid_code") except OAuth2Error as e: print(f"Failed to get access token: {e.message} (Error code: {e.error})") ``` ```Python from httpx_oauth.oauth2 import OAuth2Error from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") try: user_id, user_email = await client.get_id_email("invalid_access_token") except OAuth2Error as e: print(f"Failed to get user info: {e.message} (Error code: {e.error})") ``` ```Python from httpx_oauth.oauth2 import OAuth2Error from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") try: # Simulate an error during token refresh refresh_token = await client.refresh_token("invalid_refresh_token") except OAuth2Error as e: print(f"Failed to refresh token: {e.message} (Error code: {e.error})") ``` ```Python from httpx_oauth.oauth2 import OAuth2Error from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("INVALID_CLIENT_ID", "YOUR_CLIENT_SECRET") try: await client.get_authorization_url("http://localhost:8000/callback") except OAuth2Error as e: print(f"Configuration error: {e.message} (Error code: {e.error})") ``` ```Python from httpx_oauth.oauth2 import OAuth2Error from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") try: # Simulate a network error or server issue # This might raise httpx.HTTPStatusError or similar token = await client.get_access_token("CODE_THAT_FAILS") except OAuth2Error as e: print(f"An OAuth2 error occurred: {e}") except Exception as e: print(f"A general exception occurred: {e}") ``` ```Python from httpx_oauth.oauth2 import OAuth2Error from httpx_oauth.clients.google import GoogleOAuth2 client = GoogleOAuth2("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") try: # Example of handling a specific error response from the provider # This requires inspecting the error details returned by the provider token = await client.get_access_token("CODE_WITH_PROVIDER_ERROR") except OAuth2Error as e: if e.error == "invalid_grant": print("The provided authorization code is invalid or has expired.") else: print(f"An OAuth2 error occurred: {e}") ``` -------------------------------- ### GitHubOAuth2AuthorizeParams Usage Example Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/types.md Demonstrates generating an authorization URL for GitHub with specific extra parameters like login and allow_signup. ```python from httpx_oauth.clients.github import GitHubOAuth2 github_client = GitHubOAuth2(client_id="id", client_secret="secret") auth_url = await github_client.get_authorization_url( redirect_uri="https://example.com/callback", extras_params={"login": "octocat", "allow_signup": False}, ) ``` -------------------------------- ### Access Package Version Source: https://github.com/frankie567/httpx-oauth/blob/master/_autodocs/modules.md Access the package version string. This is useful for checking the installed version of the library. ```python from httpx_oauth import __version__ print(__version__) # "0.17.0" ```