Welcome to PAuth, a modern Python library that takes the complexity out of OAuth 2.0 authentication. Whether you're building a small Flask application or a large Django project, PAuth provides a clean, consistent, and secure way to handle authentication with popular OAuth providers.
OAuth 2.0 implementation can be tricky. You need to manage authorization flows, handle tokens securely, validate states, and deal with different provider quirks. PAuth handles all of this for you while providing:
- π Complete OAuth 2.0 Implementation: All the standard flows, with modern security features built in
- π Multiple Provider Support: One consistent interface for all major OAuth providers
- π οΈ Framework Integration: Seamless integration with Flask and Django
- π Security First: Built-in PKCE support, state validation, and secure token handling
- π‘ Developer-Friendly: Clear APIs, comprehensive error handling, and TypeScript-style hints
Let's get you authenticating in minutes:
# Basic installation pip install pauth # With framework support pip install pauth[flask] # For Flask applications pip install pauth[django] # For Django applicationsHere's a simple example using Google OAuth:
from pauth import OAuth2Client, Providers # Initialize the client client = OAuth2Client( provider=Providers.GOOGLE, client_id="your_client_id", client_secret="your_client_secret", redirect_uri="https://your-app.com/callback" ) # Get the authorization URL auth_url = client.get_authorization_url( scope=["openid", "email", "profile"], state="your_secure_state" # PAuth can generate this for you ) # Later, in your callback handler... tokens = client.exchange_code( code="authorization_code_from_callback", state="your_secure_state" # Validate the state ) # Access user information user_info = client.get_user_info(tokens.access_token)PAuth makes Flask integration smooth and simple:
from flask import Flask, redirect, request from pauth.integrations.flask import FlaskOAuth app = Flask(__name__) oauth = FlaskOAuth( client_id="your_client_id", client_secret="your_client_secret", redirect_uri="http://localhost:5000/callback" ) @app.route('/login') def login(): return redirect(oauth.get_authorization_url()) @app.route('/callback') def callback(): tokens = oauth.handle_callback(request) user = oauth.get_user_info(tokens.access_token) # Handle user login in your application return f"Welcome, {user.name}!"For Django applications, PAuth provides a seamless experience:
# settings.py INSTALLED_APPS = [ ... 'pauth.integrations.django', ] PAUTH_CONFIG = { 'PROVIDERS': { 'google': { 'client_id': 'your_client_id', 'client_secret': 'your_client_secret', 'redirect_uri': 'http://localhost:8000/oauth/callback', } } } # urls.py from django.urls import path, include urlpatterns = [ path('oauth/', include('pauth.integrations.django.urls')), ] # views.py from pauth.integrations.django import oauth def login(request): return oauth.redirect_to_provider('google') def callback(request): user_info = oauth.handle_callback(request) # Handle user login in your applicationPAuth implements PKCE (Proof Key for Code Exchange) for enhanced security:
client = OAuth2Client( provider=Providers.GITHUB, client_id="your_client_id", use_pkce=True # Enable PKCE ) # PAuth handles code verifier generation and challenge creation auth_url = client.get_authorization_url(scope=["user"])Implement custom token storage for your specific needs:
from pauth.storage import BaseTokenStorage class RedisTokenStorage(BaseTokenStorage): def __init__(self, redis_client): self.redis = redis_client def save_token(self, user_id: str, tokens: dict): self.redis.hmset(f"user:{user_id}:tokens", tokens) def get_token(self, user_id: str) -> dict: return self.redis.hgetall(f"user:{user_id}:tokens") def delete_token(self, user_id: str): self.redis.delete(f"user:{user_id}:tokens") # Use your custom storage client = OAuth2Client( provider=Providers.GOOGLE, client_id="your_client_id", token_storage=RedisTokenStorage(redis_client) )PAuth provides comprehensive error handling:
from pauth.exceptions import ( AuthorizationError, TokenError, InvalidStateError, ProviderError ) try: tokens = client.exchange_code(code, state) except AuthorizationError as e: # Handle authorization errors (e.g., invalid code) print(f"Authorization failed: {e}") except TokenError as e: # Handle token-related errors print(f"Token error: {e}") except InvalidStateError as e: # Handle state validation errors print(f"State validation failed: {e}") except ProviderError as e: # Handle provider-specific errors print(f"Provider error: {e}")PAuth is actively developing new features:
- Microsoft OAuth integration
- LinkedIn authentication
- Discord OAuth support
- Apple Sign-In
- FastAPI integration
- aiohttp support
- Starlette compatibility
- Automatic token refresh
- Rate limiting support
- More storage backends
- Enhanced token encryption
PAuth is licensed under the Apache License 2.0. See the LICENSE file for details.
PAuth is created and maintained by Utkarsh Priyadarshi (utkarshpriyadarshi5026@gmail.com), a passionate developer focused on making authentication simpler and more secure for Python applications.
Need help or have questions? Feel free to:
- Open an issue on GitHub
- Send me an email
- Join our Discord community
Your feedback and contributions help make PAuth better for everyone!