FastAPI gives you speed (async), type safety (Pydantic), and built-in docs (Swagger UI) in a single framework. It’s the best “default” choice for Python APIs in 2025. Let’s build a realistic mini-project.
Project Setup
mkdir fastapi-app && cd fastapi-app
python -m venv .venv
source .venv/bin/activate
pip install fastapi uvicorn[standard] sqlalchemy pydantic python-jose[cryptography] passlib[bcrypt]
Recommended Structure
app/
main.py
db.py
models.py
schemas.py
auth.py
routes/
users.py
items.py
Database Setup (SQLAlchemy)
# app/db.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
DATABASE_URL = "sqlite:///./app.db"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Pydantic Schemas
# app/schemas.py
from pydantic import BaseModel, EmailStr
class UserCreate(BaseModel):
email: EmailStr
password: str
class UserOut(BaseModel):
id: int
email: EmailStr
class Config:
from_attributes = True
JWT Auth (High Level)
Use short-lived access tokens and hashed passwords.
# app/auth.py
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_password(pw: str) -> str:
return pwd_context.hash(pw)
def verify_password(pw: str, hashed: str) -> bool:
return pwd_context.verify(pw, hashed)
Routes and Docs
FastAPI automatically generates interactive docs at /docs and OpenAPI JSON at /openapi.json. That alone is a massive productivity boost for teams.
Production Notes
- Use Postgres, not SQLite, for real workloads
- Use Alembic for migrations
- Put secrets in environment variables
- Add rate limiting and request logging
This is a crash course, not a full book. But if you build this small API and deploy it, you’ll understand 80% of what you need to ship real FastAPI services.
