100nm /
clean-architecture-template
An opinionated Web API template with Python, built around Domain-Driven Design (DDD), CQRS, and Clean Architecture.
50/100 healthLoading repository data…
Subhransu-De / repository
An opinionated FastAPI template with async SQLAlchemy 2.0, Alembic migrations, Pydantic v2, uv package manager, Docker, pytest, and pre-configured CI/CD. Python 3.13+ boilerplate for building REST APIs.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
A production-minded FastAPI starter that gives you a clean async API, a real database path, authentication, observability, CI checks, and multiple test layers from day one.
| Area | Included |
|---|---|
| API | FastAPI application with health endpoints and protected CRUD routes for entities. |
| Database | PostgreSQL, SQLAlchemy async sessions, Psycopg, and Alembic migrations run as a one-shot startup task before the API starts. |
| Authentication | OAuth2 authorization-code flow, JWT bearer validation, and a Keycloak-backed Docker setup. |
Selected from shared topics, language and repository description—not editorial ratings.
100nm /
An opinionated Web API template with Python, built around Domain-Driven Design (DDD), CQRS, and Clean Architecture.
50/100 health| Validation and settings | Pydantic v2 schemas and pydantic-settings based application, database, and auth configuration. |
| Observability | Structured logging plus Logfire/OpenTelemetry instrumentation for FastAPI and SQLAlchemy. |
| Local runtime | Docker Compose stack for the API, PostgreSQL, and Keycloak. |
| Quality gates | Ruff linting, Ty type checks, import-linter architecture checks, coverage enforcement, SonarCloud analysis, and Snyk security status. |
| Dependency upkeep | Dependabot is configured for Python, Docker, Docker Compose, and GitHub Actions updates. |
This template keeps tests split by purpose so each feedback loop stays clear:
scenario-tests and use Behave plus HTTPX against the running Docker Compose stack.pytest-cov; CI currently enforces at least 80% coverage.At a glance, the template wires requests, authentication, business behavior, persistence, migrations, and scenario tests like this:
flowchart LR
client["Client / API consumer"] -->|"HTTP"| routes["app/routes<br/>FastAPI routers"]
scenario["scenario-tests<br/>Behave + HTTPX"] -->|"HTTP against running stack"| routes
routes -->|"Depends"| auth["app/auth<br/>OAuth2 + JWT validation"]
keycloak["Keycloak<br/>OIDC issuer"] -->|"Tokens + JWKS"| auth
routes -->|"Pydantic input/output"| io["app/io<br/>Request and response schemas"]
routes -->|"Depends"| service["app/service<br/>Business behavior"]
service --> repository["app/repository<br/>Async data access"]
repository --> database["app/database<br/>Engine and sessions"]
model["app/model<br/>SQLAlchemy models"] --> repository
database --> postgres[("PostgreSQL")]
compose["Docker Compose<br/>startup order"] --> alembic["migrate service<br/>Alembic upgrade head"]
alembic --> postgres
alembic --> main["app/main.py<br/>Application startup"]
settings["app/settings<br/>Environment configuration"] -.-> routes
settings -.-> database
settings -.-> auth
The application uses a small layered architecture:
app/routes owns HTTP endpoints, request dependencies, and route grouping.app/service holds business behavior and coordinates repository calls.app/repository isolates persistence logic behind reusable async repository helpers.app/model defines SQLAlchemy database models.app/io defines request and response schemas at the API boundary.app/settings, app/auth, and app/logger keep cross-cutting concerns separate from endpoint logic.This shape is meant for teams that want a practical backend template: simple enough to understand quickly, but structured enough to grow into a real service without immediately rewriting the foundation.
uv sync
cp .env.example .env
Fill in the required values in .env before starting the app.
Development mode:
make run
make run applies alembic upgrade head with the migration dependency group, then starts the FastAPI app.
Docker-based development:
docker compose up --build
Docker Compose builds the API from Dockerfile and the one-shot migration service from Dockerfile.migration. Their default image tags include COMPOSE_PROJECT_NAME, so parallel worktrees do not overwrite each other's local images; APP_IMAGE and MIGRATION_IMAGE can still override those tags. Compose starts migrate first, waits for alembic upgrade head to exit successfully, and then starts the API container. If migrations fail, the API container does not start.
Swagger UI signs users in with the public fastapi-docs client using authorization code flow plus PKCE. The API continues to validate the fastapi-client audience. A browser client must never receive a client secret; OIDC_CLIENT_SECRET is used only by the confidential client in scenario tests.
Compose does not assign host-global container names. To run isolated stacks in parallel, give each one a unique project name, application port, Keycloak port, and public URLs:
COMPOSE_PROJECT_NAME=fastapi-feature-a \
APP_PORT=8081 \
APP_PUBLIC_URL=http://localhost:8081 \
KEYCLOAK_PORT=8181 \
OIDC_PUBLIC_URL=http://localhost:8181 \
docker compose up --build
The keycloak-config one-shot service registers the exact Swagger callback for APP_PUBLIC_URL; production deployments should likewise use exact redirect URIs rather than wildcards.
When adopting this repository, update the application name, package metadata, image names, OIDC realm/client identifiers, and Sonar/Snyk project identifiers. Compose service names such as db and keycloak are internal DNS names and do not need to be renamed for stack isolation.
Build and push both images before deployment:
Dockerfile; default command is python -m app.main; installs only application runtime dependencies.Dockerfile.migration; default command is alembic -c alembic.ini upgrade head; installs only the migration dependency group and only ships the Alembic migration files.For ECS, run the migration image as a one-off task before updating or starting the service. For EKS, run the migration image as a Kubernetes Job before rolling out the Deployment. In both cases, the migration task/job must use the same production database environment variables as the application release.
Run the default test suite:
make test
Run tests with coverage:
make test-cov
Run scenario tests against the e2e Docker Compose stack:
export COMPOSE_FILE=docker-compose.yml:docker-compose.e2e.yml
export POSTGRES_PASSWORD=postgres
export KEYCLOAK_ADMIN_PASSWORD=admin
export OIDC_CLIENT_SECRET=change-me
export E2E_PASSWORD=test-password
docker compose up --build --wait
cd scenario-tests
uv sync
OIDC_CLIENT_SECRET=change-me E2E_PASSWORD=test-password uv run behave
Run mutation testing from Linux or WSL because mutmut requires fork support:
uv run --group test --with mutmut mutmut run
The GitHub Actions workflow runs Ruff, Ty, unit tests, integration tests, coverage, Docker image build validation, and scenario tests. Dependabot keeps dependency updates visible, while SonarCloud and Snyk expose code-quality and security status at the top of this README.