Skip to content

mvish77/fastapi-basic-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

FastAPI Template API

⚠️ Note: This is a lightweight, startup-friendly template designed for small to mid-sized apps with a low userbase and authenticated users only. It intentionally keeps things simple β€” no Redis caching, no advanced queue systems, no heavy load-prevention infrastructure. If you're building an MVP, side project, or internal tool that needs to handle thousands of users, this is a clean and solid starting point. For larger scale, you'll want to layer on caching (Redis), a task queue (Celery/RQ), and a more advanced rate-limiter (e.g., API gateway or slowapi with Redis backend).

A passwordless authentication backend built with FastAPI, SQLAlchemy (async), and PostgreSQL. Supports OTP login via email, Google OAuth, and includes rate limiting with SlowAPI β€” no passwords, no password reset, just simple and secure authentication.

✨ Features

  • πŸ” Passwordless Auth β€” OTP via email + Google OAuth (no passwords needed)
  • πŸ“± Support Both Web/Mobile β€” One API use anywhere
  • πŸ“§ Email OTP β€” 6-digit codes sent via Resend
  • πŸ”‘ Google OAuth β€” One-click sign-in with Google
  • πŸͺ Dual Client Support β€” httpOnly cookies for web, tokens in body for mobile
  • πŸ›‘οΈ CSRF Protection β€” Middleware-based CSRF protection for cookie auth
  • πŸ”„ Refresh Tokens β€” Long-lived refresh tokens with database-backed revocation
  • 🐘 Async PostgreSQL β€” SQLAlchemy 2.0 async with asyncpg
  • ⚑ FastAPI β€” High-performance async Python API
  • 🐌 Rate Limiting β€” SlowAPI for API abuse prevention
  • πŸ—„οΈ Alembic Migrations β€” Production-ready database migrations
  • 🌍 CORS β€” Configurable cross-origin resource sharing
  • πŸ₯ Health Check β€” Database connectivity monitoring

πŸ—οΈ Tech Stack

Layer Technology
Framework FastAPI
Database PostgreSQL (async via asyncpg)
ORM SQLAlchemy 2.0 (async)
Migrations Alembic
Auth JWT (PyJWT) + Google OAuth
Email Resend
Rate Limiting SlowAPI
Validation Pydantic v2
Config pydantic-settings

πŸ“ Project Structure

.
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ main.py                  # FastAPI app entry point, SlowAPI setup
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   └── v1/
β”‚   β”‚       β”œβ”€β”€ __init__.py      # API router aggregation
β”‚   β”‚       β”œβ”€β”€ auth.py          # Authentication endpoints (rate-limited)
β”‚   β”‚       └── health.py        # Health check endpoint
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ config.py            # Pydantic settings (env vars)
β”‚   β”‚   └── database.py          # Async SQLAlchemy engine & session
β”‚   β”œβ”€β”€ deps/
β”‚   β”‚   └── auth.py              # Auth dependencies (get_current_user)
β”‚   β”œβ”€β”€ helpers/
β”‚   β”‚   β”œβ”€β”€ google_auth.py       # Google token verification
β”‚   β”‚   └── handle_cookies.py    # Cookie utilities (set/clear auth cookies)
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   └── auth.py              # CSRF protection middleware
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ app_users.py         # User model (OTP + Google)
β”‚   β”‚   β”œβ”€β”€ otp_code.py          # OTP codes model
β”‚   β”‚   └── refresh_token.py     # Refresh tokens model
β”‚   β”œβ”€β”€ schemas/
β”‚   β”‚   └── auth_schema.py       # Pydantic request/response schemas
β”‚   β”œβ”€β”€ templates/
β”‚   β”‚   β”œβ”€β”€ otp_email.html       # HTML email template
β”‚   β”‚   └── otp_email.txt        # Plain text email template
β”‚   └── utils/
β”‚       β”œβ”€β”€ auth_util.py         # JWT creation, hashing, CSRF token
β”‚       β”œβ”€β”€ device_check.py      # Mobile vs Web client detection
β”‚       β”œβ”€β”€ email_otp.py         # OTP email sending via Resend
β”‚       └── otp_generator.py     # OTP code generation & hashing
β”œβ”€β”€ alembic/                     # Alembic migration files
β”‚   β”œβ”€β”€ versions/
β”‚   β”œβ”€β”€ env.py
β”‚   └── script.py.mako
β”œβ”€β”€ templates/
β”‚   β”œβ”€β”€ otp_email.html           # HTML email template (legacy)
β”‚   └── otp_email.txt            # Plain text email template (legacy)
β”œβ”€β”€ .env.example                 # Environment variables template
β”œβ”€β”€ .gitignore
β”œβ”€β”€ alembic.ini                  # Alembic configuration
β”œβ”€β”€ requirements.txt
└── README.md

πŸš€ Quick Start

Prerequisites

  • Python 3.14+
  • PostgreSQL (running locally or remote)
  • Google Cloud Console project (for OAuth)
  • Resend account (for sending OTP emails)

1. Clone the repository

git clone https://github.com/mvish77/fastapi-basic-template.git
cd fastapi-basic-template

2. Create a virtual environment

python -m venv venv
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activate

3. Install dependencies

pip install -r requirements.txt

4. Set up environment variables

cp .env.example .env

Edit .env with your values (see Environment Variables below).

5. Create the database

# Using psql
createdb your_database

# Or using any PostgreSQL client, create your database

6. Run database migrations

alembic upgrade head

7. Run the server

uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

The API will be available at:

  • API: http://localhost:8000
  • Swagger Docs: http://localhost:8000/docs
  • ReDoc: http://localhost:8000/redoc

🌐 API Endpoints

Authentication

Method Endpoint Description Rate Limit
POST /api/v1/auth/send-otp Send 6-digit OTP to email 5 / 5 min
POST /api/v1/auth/verify-otp Verify OTP & login/signup 5 / 5 min
POST /api/v1/auth/google Google OAuth login/signup 5 / 5 min
POST /api/v1/auth/refresh Refresh access token Default
POST /api/v1/auth/logout Logout & revoke refresh token Default
GET /api/v1/auth/csrf-token Get CSRF token (web only) Default
GET /api/v1/auth/me Get current user info Default

System

Method Endpoint Description
GET / Root endpoint (app info)
GET /api/v1/health Health check (API + DB status)

πŸ” Authentication Flow

OTP Login / Signup

1. Client sends email β†’ POST /api/v1/auth/send-otp
2. Server generates 6-digit OTP, sends via Resend email
3. User receives OTP in email (valid for 10 minutes)
4. Client submits email + OTP β†’ POST /api/v1/auth/verify-otp
5. Server verifies OTP (SHA-256 hash comparison):
   - New email β†’ Auto-creates account (signup)
   - Existing email β†’ Logs in (login)
6. Returns JWT tokens:
   - Web: httpOnly cookies (access_token + refresh_token)
   - Mobile: Tokens in response body

Google OAuth Login

1. Client initiates Google OAuth flow (frontend)
2. Google returns ID token to client
3. Client sends ID token β†’ POST /api/v1/auth/google
4. Server verifies token with Google
5. Returns JWT tokens (same as OTP flow)

Token Refresh

1. Access token expires (24 hours)
2. Client sends refresh token β†’ POST /api/v1/auth/refresh
3. Server validates refresh token against database
4. Returns new access token
5. Refresh tokens are long-lived (30 days) and can be revoked on logout

πŸ“§ Email (OTP) β€” Resend

This project uses Resend for sending OTP emails.

Development Mode

When RESEND_API_KEY is not set, OTP codes are logged to the console instead of being sent via email. This allows local development without an email service.

============================================================
πŸ“§ DEV MODE: OTP Email
============================================================
To: user@example.com
OTP Code: 482916
Valid for: 10 minutes
============================================================

Production Mode

Set these environment variables to enable email delivery:

RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxx
EMAIL_FROM=My App <noreply@your_domain.com>
APP_NAME=My App
APP_URL=https://your_domain.com

You'll need to verify your sending domain in Resend before sending emails in production.

πŸ”‘ Google OAuth Setup

  1. Go to Google Cloud Console
  2. Create a project (or select existing)
  3. Navigate to APIs & Services β†’ Credentials
  4. Create OAuth 2.0 Client ID (Web application type)
  5. Add authorized redirect URIs
  6. Copy the Client ID and Client Secret to your .env:
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret

🐌 Rate Limiting β€” SlowAPI

This project uses SlowAPI for request rate limiting.

Default Limits

  • Global: 100 requests/minute per IP
  • Auth endpoints (send-otp, verify-otp, google): 5 requests per 5 minutes per IP

How It Works

Rate limits are applied per IP address using SlowAPI's @limiter.limit() decorator. When a limit is exceeded, the API returns a 429 Too Many Requests response.

Scaling note: The default in-memory rate limiter works fine for single-server deployments. For distributed setups, configure SlowAPI with a Redis backend.

πŸ—„οΈ Database Migrations β€” Alembic

This project uses Alembic for database migrations.

Common Commands

# Apply all migrations
alembic upgrade head

# Rollback one migration
alembic downgrade -1

# Generate a new migration after model changes
alembic revision --autogenerate -m "description of changes"

# View migration history
alembic history

βš™οΈ Environment Variables

Copy .env.example to .env and configure:

# ─── JWT Authentication ─────────────────────────────────
JWT_SECRET_KEY=your-256-bit-secret     # Generate a secure random key
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=1440   # 24 hours
JWT_REFRESH_TOKEN_EXPIRE_DAYS=30       # 30 days

# ─── CSRF Protection ────────────────────────────────────
CSRF_SECRET_KEY=your-csrf-secret       # Generate a secure random key
CSRF_TOKEN_EXPIRE_MINUTES=60

# ─── Google OAuth ───────────────────────────────────────
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret

# ─── Resend Email Service ───────────────────────────────
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxx
EMAIL_FROM=My App <noreply@your_domain.com>
APP_NAME=My App
APP_URL=https://your_domain.com

# ─── OTP Settings ───────────────────────────────────────
OTP_EXPIRY_MINUTES=10

# ─── Cookie Domain ──────────────────────────────────────
MY_DOMAIN=localhost               # e.g., .your_domain.com for all subdomains

⚠️ Never commit .env to version control. Always use .env.example as a template.

πŸ›‘οΈ Security Features

Feature Description
Passwordless No passwords to store, leak, or reset
OTP Expiry Codes expire after 10 minutes
OTP Rate Limiting 5 requests per 5 min per IP on auth endpoints
Global Rate Limiting 100 requests/minute per IP (configurable)
OTP Hash Verification OTPs stored and verified using SHA-256 hashing
Previous OTP Invalidation New OTP deletes unused old ones
CSRF Middleware Automatic CSRF protection for cookie-based auth
httpOnly Cookies Tokens stored in httpOnly cookies for web (XSS-safe)
Token Revocation Refresh tokens revoked on logout, stored hashed in DB
Secure Cookies Secure + SameSite flags in production
Docs Disabled Swagger/ReDoc disabled in production

πŸ—„οΈ Database Models

AppUser

Column Type Description
user_id UUID (PK) Auto-generated user ID
email String(150) Unique, indexed email
display_name String(100) User's display name
avatar_url Text Profile picture URL
auth_provider Enum email_otp or google
google_id String(255) Google OAuth ID (nullable)
status Enum active, suspended, deleted
role Enum user, admin, super_admin
email_verified Boolean Auto-verified via OTP/Google
last_login_at Timestamp Last login time
created_at Timestamp Account creation time
updated_at Timestamp Last update time

OTPCode

Column Type Description
email String Email address
otp_code String 6-digit OTP (plaintext for dev)
otp_hash String SHA-256 hash of OTP
is_verified Boolean Whether OTP was used
attempts Integer Failed verification attempts
expires_at Timestamp OTP expiration time

RefreshToken

Column Type Description
token_hash String SHA-256 hash of refresh token
user_id UUID (FK) Associated user
expires_at Timestamp Token expiration
device_info String User-Agent string
revoked_at Timestamp When token was revoked

πŸ“‚ Client Type Detection

The API automatically detects whether the client is a web browser or mobile app and responds accordingly:

Web Browser Mobile App
Auth method httpOnly cookies Authorization: Bearer header
Token storage Response cookies Response body
Refresh flow Cookie-based Request body
CSRF Required (middleware-protected) Not required

πŸ§ͺ Development

Running in Development

uvicorn app.main:app --reload
  • Swagger docs available at /docs
  • OTP codes logged to console (no email required)
  • Rate limits still apply

Production Build

ENV=production uvicorn app.main:app --host 0.0.0.0 --port 8000
  • Swagger/ReDoc/OpenAPI are disabled
  • Secure cookie flags are enabled
  • Use Alembic for database migrations

πŸ“‹ Checklist: Before Going Live

  • Generate secure JWT_SECRET_KEY and CSRF_SECRET_KEY
  • Set up Resend account and verify sending domain
  • Configure Google OAuth credentials
  • Set ENV=production
  • Configure MY_DOMAIN for your production domain
  • Update CORS_ALLOWED_ORIGINS for your frontend URL
  • Run alembic upgrade head on production database
  • Remove any debug/logging of OTP codes in production

πŸ“„ License

This project is open source and available under the MIT License.


Built with ❀️ using FastAPI

About

A production-ready passwordless authentication backend built with FastAPI, SQLAlchemy (async), and PostgreSQL. Supports OTP login via email and Google OAuth - no passwords, no password reset, just simple and secure authentication.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors