FastAuth Logo

Secure, powerful, and easy-to-use authentication and authorization for your FastAPI applications.

Quick Example
from fastapi import FastAPI, Depends
from fastauth import FastAuth

# Initialize FastAuth
auth = FastAuth(
    secret_key="your-secret",
    user_model=User,
    engine=engine
)

# Add authentication routes
app.include_router(
    auth.get_auth_router(get_session)
)

# Protect your routes
@app.get("/protected")
def protected_route(
    user = Depends(auth.is_admin())
):
    return {"message": f"Hello {user.username}"}

Features

  • OAuth2 and JWT authentication built-in
  • Role-based authorization system
  • Cookie-based authentication option
  • Token refresh mechanism for extended sessions
  • SQLModel integration for easy database operations
  • CLI utilities for database initialization and management (new in v0.3.0)
  • Ready-to-use authentication routes with minimal setup
  • Password hashing with bcrypt
  • Modular architecture for better code organization and extensibility

Installation

pip install fastauth_iq

Or install from source:

git clone https://github.com/hu55ain3laa/fastauth.git
cd fastauth
pip install -e .

Quick Start

1. Create a User Model

FastAuth works with SQLModel's user model. You can use the built-in User model or create your own:

from sqlmodel import SQLModel, Field

class User(SQLModel, table=True):
    id: int = Field(primary_key=True)
    username: str = Field(unique=True)
    email: str = Field(unique=True)
    hashed_password: str
    disabled: bool = Field(default=False)

2. Initialize FastAuth in Your Application

from fastapi import FastAPI, Depends
from sqlmodel import create_engine, Session, SQLModel

from fastauth import FastAuth, User

# Create FastAPI app
app = FastAPI()

# Setup database
engine = create_engine("sqlite:///./app.db")

# Session dependency
def get_session():
    with Session(engine) as session:
        yield session

# Initialize FastAuth with your configuration
auth = FastAuth(
    secret_key="your-secure-secret-key",  # Use strong secret in production
    algorithm="HS256",
    user_model=User,
    engine=engine,
    use_cookie=True,  # Enable cookie-based auth (optional)
    token_url="/token",
    access_token_expires_in=30,  # minutes
    refresh_token_expires_in=7   # days
)

# Initialize database (choose ONE of these approaches):
# Option 1: Using the CLI tool before starting the application (new in v0.3.0)
#   fastauth app.py                   # Auto-detect settings from your app file
#   # Or use explicit parameters
#   fastauth --db-url="sqlite:///./app.db" --secret-key="your-secret-key"
#
# Option 2: Initializing during application startup
INIT_DB_ON_STARTUP = True  # Set to False to disable

@app.on_event("startup")
def on_startup():
    if INIT_DB_ON_STARTUP:
        auth.initialize_db(
            create_tables=True,         # Create database tables
            init_roles=True,            # Initialize standard roles
            create_admin=True,          # Create superadmin if needed
            admin_username="superadmin", # Default username
            admin_password="admin123"    # Default password
        )

# Add all authentication routes automatically
auth_router = auth.get_auth_router(get_session)
app.include_router(auth_router, tags=["authentication"])

# Add role management routes (new in v0.2.2)
role_router = auth.get_role_router()
app.include_router(role_router, tags=["roles"])

3. Protect Your Routes

# Require authentication only
@app.get("/protected")
def protected_route(current_user = Depends(auth.get_current_active_user_dependency())):
    return {"message": f"Hello, {current_user.username}!"}

# Require specific roles (any of the listed roles)
@app.get("/admin-or-moderator")
def admin_or_mod_route(current_user = Depends(auth.require_roles(["admin", "moderator"]))):
    return {"message": f"Hello privileged user, {current_user.username}!"}

# Require all listed roles
@app.get("/admin-and-verified")
def admin_and_verified_route(current_user = Depends(auth.require_all_roles(["admin", "verified"]))):
    return {"message": f"Hello admin with verification, {current_user.username}!"}

# Shortcut for admin-only routes
@app.get("/admin-only")
def admin_only_route(current_user = Depends(auth.is_admin())):
    return {"message": f"Hello admin, {current_user.username}!"}

Authentication

Login and Token Management

FastAuth implements JWT-based authentication with both access tokens and refresh tokens:

  • Access tokens are short-lived (default: 30 minutes) and used for regular API access
  • Refresh tokens are long-lived (default: 7 days) and used to obtain new access tokens

User authentication flow:

  1. User submits credentials to /token endpoint
  2. Server validates credentials and returns access + refresh tokens
  3. Client uses access token for API requests (via header or cookie)
  4. When access token expires, client uses refresh token to get a new one from /token/refresh

Protected Routes

To protect a route, use FastAuth's dependencies:

# Basic authentication - any valid user
@app.get("/protected")
def protected_route(user = Depends(auth.get_current_active_user_dependency())):
    return {"message": "Protected content", "user": user.username}

Database Initialization

FastAuth includes tools for initializing the database with tables, standard roles, and a superadmin user.

CLI Initialization (enhanced in v0.3.3)

Use the command-line interface for database setup with flexible configuration detection:

# Auto-detect settings from your app file
fastauth app.py

# Or use explicit parameters
fastauth --db-url="sqlite:///./app.db" --secret-key="your-secret-key"

# The CLI will automatically find settings from:
# - .env files
# - Environment variables
# - Imported modules
# - Database engine objects

Configuration Auto-Detection

FastAuth CLI can now detect database URLs and secret keys from multiple sources:

1. Environment Variables
# Set these environment variables before running FastAuth CLI
export DATABASE_URL="sqlite:///./app.db"
export SECRET_KEY="your-secret-key-here"
2. .env Files

Create a .env file in your project directory:

DATABASE_URL=sqlite:///./app.db
SECRET_KEY=your-secret-key-here
3. Python Modules
# FastAuth will detect these patterns in your Python files
DATABASE_URL = "sqlite:///./app.db"
secret_key = "your-secret-key-here"
engine = create_engine("sqlite:///./app.db")
4. Imported Modules
# FastAuth will detect imported engines and variables
from database import engine  # Where database.py contains an engine definition
from config import DATABASE_URL, SECRET_KEY

The CLI will search common configuration files in your project, including config.py, settings.py, db.py, and more.

Programmatic Initialization

Initialize the database programmatically during application startup:

@app.on_event("startup")
def on_startup():
    auth.initialize_db(
        create_tables=True,         # Create database tables
        init_roles=True,            # Initialize standard roles
        create_admin=True,          # Create superadmin if needed
        admin_username="superadmin", # Default username
        admin_password="admin123"    # Default password
    )

Role-Based Authorization

FastAuth includes a comprehensive role-based authorization system.

Standard Roles

FastAuth comes with pre-defined standard roles:

  • superadmin: Highest level of access
  • admin: Administrative privileges
  • moderator: Content moderation
  • premium: Premium user features
  • verified: Verified user status
  • user: Basic user access

Role Requirements

Protect routes with role requirements:

# Any of these roles (OR condition)
@app.get("/admin-area")
def admin_route(user = Depends(auth.require_roles(["admin", "moderator"]))):
    return {"message": "Admin or moderator area"}

# Require all of these roles (AND condition)
@app.get("/premium-and-verified")
def premium_verified_route(user = Depends(auth.require_all_roles(["premium", "verified"]))):
    return {"message": "Premium and verified user area"}

Advanced Usage

Custom User Models

You can extend the default User model with additional fields:

class CustomUser(SQLModel, table=True):
    id: int = Field(primary_key=True)
    username: str = Field(unique=True)
    email: str = Field(unique=True)
    hashed_password: str
    disabled: bool = Field(default=False)
    first_name: str = Field(default="")
    last_name: str = Field(default="")
    created_at: datetime = Field(default_factory=datetime.now)

# Use custom model when initializing FastAuth
auth = FastAuth(
    # ... other parameters ...
    user_model=CustomUser
)

Security Best Practices

  • Always use a strong, randomly generated secret_key in production
  • Store sensitive configuration in environment variables, not in code
  • Use HTTPS in production to protect tokens in transit
  • Enable use_cookie=True and secure_cookies=True in production
  • Change default admin credentials immediately after setup
  • Regularly rotate refresh tokens
  • Implement rate limiting for authentication endpoints

API Reference

Authentication Endpoints

  • POST /token - Authenticate a user and return access and refresh tokens
  • POST /token/refresh - Refresh an access token using a valid refresh token
  • POST /register - Register a new user
  • GET /users/me - Get the current authenticated user's profile
  • POST /logout - (With cookie auth) Clear authentication cookies

Role Management Endpoints

  • GET /roles - List all roles
  • POST /roles - Create a new role
  • GET /roles/{role_id} - Get a specific role
  • PUT /roles/{role_id} - Update a role
  • DELETE /roles/{role_id} - Delete a role
  • POST /users/{user_id}/roles/{role_id} - Assign a role to a user
  • DELETE /users/{user_id}/roles/{role_id} - Remove a role from a user

Error Handling

FastAuth provides a comprehensive error handling system that delivers consistent, informative error responses across all endpoints (new in v0.3.4).

Custom Exceptions

The library includes specialized exception classes for different error scenarios:

from fastauth import (
    CredentialsException,    # Authentication failures
    TokenException,          # Token verification issues
    RefreshTokenException,   # Refresh token problems
    InactiveUserException,   # User account is disabled
    UserNotFoundException,   # User doesn't exist
    UserExistsException,     # Username already taken
    RoleNotFoundException,    # Role doesn't exist
    RoleExistsException,     # Role already exists
    PermissionDeniedException # Insufficient permissions
)

Standardized Error Responses

All FastAuth exceptions return a consistent JSON structure:

{
  "error": {
    "code": "FASTAUTH_ERROR_CODE",
    "message": "Human-readable error description",
    "status_code": 401  // HTTP status code
  }
}

Enabling error handling is simple:

app = FastAPI()
auth = FastAuth(...)

# Register exception handlers with your FastAPI app
auth.setup_exception_handlers(app)

This makes debugging easier and allows clients to handle errors in a consistent way. Each exception type has its own specific error code, making it straightforward to identify and respond to different error scenarios.

Project Structure

fastauth/
├── __init__.py           # Package initialization
├── cli.py                # Command-line interface utilities
├── core/                 # Core functionality
│   ├── __init__.py       # Core initialization
│   └── auth.py           # Authentication core functionality
├── dependencies/         # Dependency providers
│   ├── __init__.py       # Dependencies initialization
│   ├── auth.py           # Authentication dependencies
│   └── roles.py          # Role-based authorization dependencies
├── exceptions.py         # Custom exceptions and error handling
├── models/               # Database models
│   ├── __init__.py       # Models initialization
│   ├── user.py           # User model
│   ├── role.py           # Role model
│   └── tokens.py         # Token model
├── routers/              # API endpoints
│   ├── __init__.py       # Routers initialization
│   ├── auth.py           # Authentication endpoints
│   └── roles.py          # Role management endpoints
├── security/             # Security utilities
│   ├── __init__.py       # Security initialization
│   ├── password.py       # Password handling utilities
│   └── tokens.py         # Token handling utilities
└── utils/                # Utility functions
    ├── __init__.py       # Utils initialization
    └── session.py        # Session management utilities

The library is designed with a clean, modular architecture making it easy to extend or customize various components.