A clean architecture FastAPI project starter with authentication (WorkOS), PostgreSQL and Alembic migrations.
Create a new project from this template:
Install the package (globally or in a separate environment):
uv pip install fastapi-auth-starterInitialize a new project in a new directory:
fastapi-auth-starter init my-projectOr initialize in the current directory:
fastapi-auth-starter init .Note: The fastapi-auth-starter CLI tool is a scaffolding utility, not a runtime dependency. If you install it in your project's virtual environment and then run uv sync, it will be removed (this is expected behavior). Install it globally to avoid this.
fastapi_auth_starter/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI application entry point
│ ├── api/
│ │ └── v1/
│ │ ├── api.py # API router aggregation
│ │ └── routes/
│ │ └── health.py # Health check endpoint
│ ├── core/
│ │ ├── config.py # Application configuration
│ │ └── database.py # Database connection and session management
│ ├── models/ # SQLAlchemy database models
│ ├── services/ # Business logic services
│ └── db/ # Database utilities
├── alembic/ # Database migration scripts
├── alembic.ini # Alembic configuration
├── pyproject.toml # Project dependencies (uv)
└── README.md
- ✅ Clean architecture with separation of concerns
- ✅ FastAPI with async SQLAlchemy
- ✅ WorkOS authentication integration
- ✅ PostgreSQL database support
- ✅ Alembic for database migrations
- ✅ Health check endpoint
- ✅ Dependency injection with FastAPI
- ✅ Environment-based configuration
- Python 3.12+ (3.13 for local dev, 3.12 for Vercel deployment)
- uv package manager
- PostgreSQL database (local or remote)
Dependencies are managed with uv. They are automatically installed when you run commands with uv run.
Important: Copy the example environment file and configure your settings:
cp .env.example .envThen edit .env with your configuration:
# Database Configuration
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/fastapi_auth
# API Configuration (optional - defaults are fine)
API_V1_PREFIX=/api/v1
PROJECT_NAME=FastAPI Auth Starter
VERSION=0.1.0Note:
- The
.envfile is gitignored and should not be committed - The application uses
asyncpgfor async operations, but Alembic usespsycopg2for migrations (sync driver) - All sensitive configuration should be in
.envfile, not hardcoded
You can use PostgreSQL from any source - local, cloud providers (AWS RDS, Neon, Supabase, etc.), or managed services.
Option A: Local PostgreSQL
If using a local PostgreSQL instance, create the database:
createdb fastapi_authOr using PostgreSQL client:
CREATE DATABASE fastapi_auth;Option B: Cloud/Managed Database
If using a cloud provider (AWS RDS, Neon, Supabase, Railway, etc.):
- Create a PostgreSQL database through your provider's dashboard
- Copy the connection string provided by your provider
- Update the
DATABASE_URLin your.envfile with the connection string
Important:
- The
DATABASE_URLin your.envfile should point to your database (local or cloud) - Ensure the database is accessible from where you're running the application
- The connection string format should be:
postgresql+asyncpg://user:password@host:port/database
Create your initial migration:
# Create initial migration
uv run alembic revision --autogenerate -m "Initial migration"
# Apply migrations
uv run alembic upgrade headuv run uvicorn app.main:app --reloadThe API will be available at:
- API: http://localhost:8000
- Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Test the health endpoint:
curl http://localhost:8000/api/v1/healthExpected response:
{
"status": "healthy",
"message": "Service is running"
}For package maintainers: See DEV.md for detailed development workflow, including how to sync changes from the root project to the template using the
sync_to_template.pyscript.
- Create a new route file in
app/api/v1/routes/ - Import and include the router in
app/api/v1/api.py
Example:
# app/api/v1/routes/users.py
from fastapi import APIRouter
router = APIRouter(prefix="/users", tags=["users"])
@router.get("/")
async def get_users():
return {"users": []}Then add to app/api/v1/api.py:
from app.api.v1.routes import users
api_router.include_router(users.router)- Create model in
app/models/ - Import in
app/models/__init__.py - Import in
alembic/env.py(for autogenerate)
Example:
# app/models/user.py
from sqlalchemy import Column, Integer, String
from app.core.database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
email = Column(String, unique=True, index=True)# Auto-generate migration from model changes
uv run alembic revision --autogenerate -m "Description of changes"
# Create empty migration
uv run alembic revision -m "Description of changes"# Apply all pending migrations
uv run alembic upgrade head
# Rollback one migration
uv run alembic downgrade -1
# Rollback to specific revision
uv run alembic downgrade <revision>- API Layer (
app/api/): Route handlers, request/response models - Service Layer (
app/services/): Business logic, domain operations - Model Layer (
app/models/): SQLAlchemy database models - Core Layer (
app/core/): Configuration, database setup, utilities
FastAPI's dependency injection is used throughout:
- Database sessions via
get_db()dependency - Configuration via
settingsobject - Custom dependencies in
app/core/dependencies.py(create as needed)
-
Install Dev Dependencies Locally:
uv sync # Installs all dependencies including dev -
Set Environment Variables in Vercel:
- Go to your project settings in Vercel
- Add
DATABASE_URLenvironment variable with your PostgreSQL connection string - Format:
postgresql+asyncpg://user:password@host:port/database
-
Deploy:
vercel --prod
Note:
- Runtime dependencies don't include
psycopg2-binaryoralembic(only needed for local migrations) - Python 3.12 is used (Vercel doesn't support 3.13 yet)
- Make sure to run migrations on your database before deploying
- FastAPI Documentation
- SQLAlchemy Async Documentation
- Alembic Documentation
- uv Documentation
- Vercel Python Documentation
MIT