Asynchronous FastAPI starter that combines SQLAlchemy 2.0, Alembic migrations, and Pydantic v2 schemas to deliver modular CRUD APIs for users and todos while enforcing bearer authentication and emitting structured JSON logs.
- Global HTTP bearer guard (Authorization: Bearer Nina) backed byHTTPBearerand reusable auth helpers.
- Modular domain packages in src/features/<domain>with alignedmodels,schemas,services, androutesmodules.
- SQLAlchemy 2.0 async stack with explicit async with db.begin()transaction boundaries.
- Structlog-powered request middleware that stamps each response with an X-Request-IDand logs duration, status, and endpoint.
- Shared pagination helpers that return a consistent {items,total,page,page_size}payload.
- Health and status probes (GET /andGET /health) for readiness checks.
- Python 3.11+
- SQLite (default), or any SQLAlchemy-supported database URL for settings.db_url
- Optional: uv for fast dependency management
- Clone the repository
git clone <your-fork-url> fastapi-template cd fastapi-template 
- Create a virtual environment
python -m venv .venv source .venv/bin/activate
- Install dependencies
Or, if you usepip install -e . # Install test tooling if you plan to run the suite pip install pytest pytest-asyncio uv:uv sync 
Create .env in the project root (the Settings object in src/settings.py loads it automatically). At minimum set a database URL; SQLite is convenient for local work:
db_url=sqlite+aiosqlite:///./data.db
log_level=DEBUG
cors_allow_origins=http://localhost:3000,http://localhost:5173Comma-separated values are expanded into lists for the CORS settings.
- Apply migrations (run from src/so Alembic can locateenv.py):cd src alembic upgrade head
- Start the API with auto-reload:
fastapi dev 
- Authenticate every request with Authorization: Bearer Nina(including the Swagger “Authorize” dialog) to avoid401responses.
- Visit http://localhost:8000/docsfor the interactive schema orhttp://localhost:8000/redocfor an alternative view.
Logs are JSON-formatted and include request metadata emitted by StructlogRequestMiddleware.
- Create a revision:
cd src alembic revision -m "add new table" 
- Apply the latest migration:
alembic upgrade head 
Alembic reads the SQLAlchemy URL from settings.db_url, so keep .env in sync with your target database.
- GET /– Lightweight status check that logs a debug entry.
- GET /health– Pings the database; returns- 500if the connection fails.
- POST /users/– Create a user (transactional)
- GET /users/{user_id}– Retrieve a single user
- GET /users/– List users with pagination
- PATCH /users/{user_id}– Partially update a user (transactional)
- DELETE /users/{user_id}– Remove a user (transactional)
- POST /todos/– Create a todo, verifying referenced users exist (transactional)
- GET /todos/{todo_id}– Retrieve a todo
- GET /todos/– List todos with pagination
- GET /todos/with-users– List todos and optionally eager-load related users
- PATCH /todos/{todo_id}– Update a todo (transactional)
- DELETE /todos/{todo_id}– Remove a todo (transactional)
Paginated responses return:
{
  "items": [...],
  "total": 42,
  "page": 1,
  "page_size": 20
}Use the page and page_size query parameters (max 100) to control pagination.
Run the async API suite (uses an in-memory SQLite database) after activating your virtual environment:
pytest -v --maxfail=1Fixtures in tests/conftest.py handle app bootstrapping, dependency overrides, and injecting the required bearer token so integration tests mirror real requests.
.
├── AGENTS.md
├── pyproject.toml
├── uv.lock
├── src
│   ├── main.py            # FastAPI app & router wiring
│   ├── middleware.py      # Structlog request middleware
│   ├── settings.py        # Pydantic settings (loads .env)
│   ├── database.py        # Async engine, session factory, DeclarativeBase
│   ├── logger.py          # Structlog configuration
│   ├── alembic            # Migration environment & versions
│   └── features
│       ├── auth           # HTTP bearer dependency
│       ├── common         # Pagination and shared utilities
│       ├── todos          # Todo domain models/routes/services/schemas
│       └── users          # User domain models/routes/services/schemas
└── tests
    ├── conftest.py        # Async test fixtures & client factory
    ├── test_todos.py
    └── test_users.py
- Add a new folder under src/features/<domain>and mirror the existingmodels,schemas,services, androutesstructure.
- Import new models in src/alembic/env.pyso Alembic picks them up, then generate migrations.
- Register the router in src/main.pyto expose endpoints.
- Cover new behaviors with tests in tests/using the provided fixtures.
- Wrap multi-operation writes in a shared async with db.begin()block and passflush=Falseinto services that participate in wider transactions.
- fastapi devwatches the project for code changes and reloads automatically.
- Structured logs bind request metadata (method, path, status, duration, request id) so collectors can index and search easily.
- Global CORS settings are read from .env; provide comma-separated lists for origins, headers, or methods when tightening access for different environments.