Reusable starting point for a FastAPI service with async SQLAlchemy, Alembic, Bearer token auth, Sentry, and pytest.
app/
main.py # AppFastAPI, AppState, lifespan
apps/
internal/ # healthcheck endpoint (reference app module)
core/
auth.py # Bearer API token verification
db/ # Base model, DatabaseManager, repository/service bases
exceptions.py # AppValueError, AppValidationError, model errors
exception_handlers.py
middlewares/ # access logging, error catcher
routing/ # AppMiddlewareBase
settings.py # Settings, PostgresSettings, SentrySettings
setups.py # setup_db
integrations/ # logging, Sentry
utils/
migrations/ # Alembic env (add versions as you introduce models)
tests/
apps/internal/ # healthcheck tests
core/db/ # ExampleModel + repository/service template tests
fixtures/ # app, db, settings fixtures
scripts/
rename_project.py # rename package / class prefix for a new service
# uv creates .venv with Python 3.12 and installs dependencies
uv sync
cp .env.template .envPostgreSQL 18+ is required (Base.id uses func.uuidv7()).
docker compose up -d db
uvicorn app.main:AppFastAPI --host 0.0.0.0 --port 8081 --reloaddocker compose up --buildAPI listens on http://localhost:8081. Healthcheck: GET /v1/healthcheck with header Authorization: Bearer <API_TOKEN>.
Generate a migration:
alembic revision --autogenerate -m "create Some Table" --rev-id=<migration number>Apply migrations:
alembic upgrade headImport new models in migrations/env.py (or anywhere that registers them on Base.metadata) before autogenerate.
pytest -vv --covtests/core/db/ contains a technical ExampleModel plus concrete repository/service tests that exercise SQLAlchemyRepository / SQLAlchemyService base classes. Template classes live in tests/core/db/repositories/template.py and tests/core/db/services/template.py — subclass them for your own models.
pre-commit install
pre-commit run --all-filesUse the helper script (dry-run first):
python scripts/rename_project.py --package myservice --prefix MyService --dry-run
python scripts/rename_project.py --package myservice --prefix MyServiceWhat it updates:
- renames the
app/package directory - rewrites
from app./import app.import paths (without touchingapp.stateor DockerfileWORKDIR /app) - updates anchors in
pyproject.toml,.coveragerc,Dockerfile, compose files, README - optionally renames
AppFastAPI,AppState,AppMiddlewareBase,AppValueError,AppValidationError, andapp_*_exception_handlerwhen--prefixis set
Manual checklist after rename:
- Set
APP_NAME/POSTGRES_DBin.envand.env.template - Run
uv syncandpytest -vv --cov - Update GitLab / Harbor project variables if needed
- Create
app/apps/<name>/withmodels/,repositories/,services/,schemas/,views/. - Subclass
SQLAlchemyRepositoryandSQLAlchemyServicefromapp.core.db. - Register the router in
app/core/routers.pyunder/v1(token auth is applied globally there). - Import models so Alembic sees them (e.g. from package
__init__.pyormigrations/env.py). - Add factories under
tests/...and subclassSQLAlchemyRepositoryTestTemplate/SQLAlchemyServiceTestTemplate. - Generate and apply an Alembic migration.