FastAPI Boilerplate Changelog¶
Introduction¶
The Changelog documents all notable changes to FastAPI Boilerplate, organized by version. For releases before v0.18.0, see GitHub releases.
For the full narrative on each release — rationale, decisions, migration guide — see the corresponding GitHub release page.
[0.18.0] - May 24, 2026 — The Pluggable Restructure¶
This is the release we promised in v0.17.0; the one that tears the layout apart and rebuilds it as a real plugin system. If you've been pinned to v0.17.0 waiting for it, this is your moment.
A heads-up before we go further: the diff is enormous; v0.17.0 → v0.18.0 is not the kind of upgrade you run git pull for. The Python package moved, auth changed completely, workers changed, the admin panel changed, there's a new CLI in a new workspace member. We didn't do this lightly.
Why this release is so different¶
We didn't iterate on the v0.17.0 codebase to get here. We rebased the project on the fastroai-template structure.
fastroai-template is the production-tested template we use internally (and sell) for AI SaaS products. It's been running real apps for months and the structural choices (three-layer architecture, vertical-slice modules, server-side sessions, SQLAdmin, Taskiq, swappable infrastructure) have proven themselves under load. Reinventing all of that for FastAPI-boilerplate would have meant another six months of polish; rebasing meant we could ship the good parts on day one.
The trade-off is that fastroai-template carries a lot of stuff this boilerplate's audience doesn't necessarily need: a Stripe integration, subscription/credits/entitlements modeling, AI agent orchestration, usage tracking with cost calculation, OAuth-specific provisioning for SaaS, an Astro frontend. Excellent for an AI SaaS starter, wrong for a general FastAPI boilerplate.
So this release is fastroai-template minus the SaaS/AI parts, plus a plugin system that fastroai-template doesn't have. What's left is the structural skeleton; the parts that any FastAPI app needs and that we've watched hold up in real use:
- The three-layer split (
interfaces/,infrastructure/,modules/) - Vertical-slice modules (
user/,tier/,api_keys/,rate_limit/) - Server-side sessions + CSRF, OAuth (Google wired, GitHub scaffolded)
- SQLAdmin, Taskiq, swappable cache/session/rate-limit backends
- The production security validator that refuses to boot with insecure defaults
The new part, the one fastroai-template doesn't have, is bp — a plugin-aware CLI. fastroai-template ships everything in-tree because that's appropriate for an AI SaaS starter. FastAPI-boilerplate's whole pitch is "use what you need, drop what you don't", and that pitch only works if dropping things and adding things are first-class operations. The bp.commands and bp.features entry points are how external Python packages contribute new commands and feature generators without touching the core. Build a Stripe plugin, a Prometheus plugin, a CRUD-generator plugin, they all ship as separate packages.
If you can stay on v0.17.0, consider it¶
For brand-new projects, v0.18.0 is the better starting point. For existing apps with significant custom code on v0.17.0, the honest answer is: the migration path is "copy your business logic into the new structure", not a sed-style find-and-replace. If your fork has diverged from v0.17.0 in non-trivial ways, pinning to v0.17.0 may be the right call. We'll keep v0.17.0 around as a tag forever.
For the full migration guide and per-section detail, see the full release notes on GitHub.
Added¶
- Three-layer architecture by @igorbenav
backend/src/{interfaces,infrastructure,modules}/split- Vertical-slice modules: each domain owns its full vertical (
models,schemas,crud,service,routes,enums) -
Modules shipped:
user,tier,api_keys,rate_limit,common -
uv workspace split by @igorbenav
- Workspace root with two members:
backend/(deployable) andcli/(developer tool) - Single shared
.venv; prod Dockerfile only copiesbackend/src/ -
Install with
uv sync --all-packages --all-extrasfrom the repo root -
bpCLI with plugin extension points by @igorbenav bp.commands— external Typer sub-apps mount under the rootbp.features— external feature generators with manifest + plan + rollback- In-tree commands:
bp deploy generate {local,prod,nginx},bp env gen-secret,bp env validate -
Built-in
deployfeature with Jinja templates for compose + nginx -
OAuth provider framework by @igorbenav, @LucasQR
- Google end-to-end (callback creates session, sets cookie)
- GitHub scaffolded with the same provider/factory shape
-
Documentation at
docs/user-guide/authentication/ -
API keys module by @igorbenav
- Named keys with permissions and usage limits
- Per-call usage recording for analytics
- scrypt hashing with per-row salt (CodeQL strong-KDF compliant)
-
Lookup via indexed
key_prefixcolumn with constant-time verify -
Production security validator by @igorbenav
- Startup gate that refuses to boot prod with insecure defaults
- Checks
SECRET_KEY, DB credentials, CORS policy, session flags, debug mode,CREATE_TABLES_ON_STARTUP -
bp env validateruns the same checks against any config -
Server-side sessions by @igorbenav
- Opaque session IDs in
HttpOnlycookies - Backed by Redis (default), Memcached, or in-memory
- CSRF enforced by default for state-changing endpoints
-
Documentation at
docs/user-guide/authentication/sessions.md -
Swappable infrastructure backends by @igorbenav
- Cache, rate limit, session storage all behind ABCs in
*/base.py - Concrete backends in
*/backends/{redis,memcached,memory}.py -
Env-selectable:
SESSION_BACKEND,CACHE_BACKEND,RATE_LIMITER_BACKEND -
Multi-stage Dockerfile by @igorbenav
dev/migrate/prodstages from a singlebackend/Dockerfile- Uses
uv exportagainst the lockfile for reproducible builds with hash verification -
Pinned uv version (
0.9.9) for build reproducibility -
Python 3.14 dependency compatibility by @carlosplanchon
-
Dependency bumps that compile and run on Python 3.14
-
CI workflows for the workspace by @igorbenav
tests.yml,linting.yml,type-checking.yml,docs.ymlcovering both members- Least-privilege
permissions: contents: readon all workflows (docs.ymladditionally haspages: writeandid-token: write)
Changed¶
- JWT → server-side sessions by @igorbenav
- JWT access tokens, refresh tokens, and the
token_blacklisttable removed -
API surface is cookie-based now; clients sending
Authorization: Bearerare rejected -
CRUDAdmin → SQLAdmin by @igorbenav
- Custom admin panel replaced with SQLAdmin
DataclassModelMixinadded forMappedAsDataclassmodel compatibility-
Env:
CRUD_ADMIN_*removed; useADMIN_ENABLED(uses mainSECRET_KEY) -
ARQ → Taskiq by @igorbenav
- Async-native worker stack with Redis or RabbitMQ broker
- Worker command:
taskiq worker infrastructure.taskiq.worker:default_broker -
DBSessiondependency injection in tasks -
MkDocs → Zensical by @igorbenav
- Docs site generator swapped; configured via
zensical.toml - Local:
uvx zensical serve; build:uvx zensical build -
Deploy via
.github/workflows/docs.ymlto GitHub Pages -
Settings layout by @igorbenav
- Composed setting groups (
AuthSettings,CacheSettings,RateLimiterSettings, etc.) ininfrastructure/config/settings.py get_settings()returns the composedSettingsinstance- Most env var names stable; a few moved between groups
Security¶
- Dropped
python-jose/ecdsaby @igorbenav - Removed unused
fastsecuredep, which was pulling inpython-joseandecdsa - Addresses the Minerva timing attack on P-256 in python-ecdsa (the project explicitly won't fix it; switching to
cryptographywas the upstream recommendation) -
bcryptis now a direct dependency (was transitive viafastsecure) -
Bumped
idnato 3.16 by @igorbenav -
Fixes CVE-2024-3651 bypass for crafted inputs to
idna.encode() -
Bumped
sqladminto 0.26.0 by @igorbenav -
Fixes the
ajax_lookupauthorization bypass -
scrypt for API key hashing by @igorbenav
- Per-row salt, format
scrypt$N$r$p$salt$derived - Compliance with CodeQL's strong-KDF allowlist
-
Constant-time verify via
hmac.compare_digest -
Workflow permissions tightened by @igorbenav
- All CI workflows now declare explicit
permissions:blocks - Read-only on test/lint/type-check; targeted writes only where needed
Improved¶
- Full documentation rewrite by @igorbenav, @LucasQR, @emiliano-gandini-outeda
- Every page under
docs/user-guide/rewritten for the new structure - New
docs/cli/section:index.md,commands.md,plugins.md - New
docs/user-guide/authentication/sessions.md -
README slimmed but still self-contained
-
Lint enforcement:
PLC0415by @igorbenav - No deferred imports anywhere — all imports at module top
-
Surfaced and resolved a circular import in session storage by extracting
AbstractSessionStoragetoauth/session/base.py -
README polish by @carlosplanchon
- Installation scripts moved out of Gists into the repo
- DeepWiki documentation link added
Removed¶
src/app/layout — replaced bybackend/src/{interfaces,infrastructure,modules}/- JWT auth +
token_blacklisttable — replaced by server-side sessions - CRUDAdmin views — replaced by SQLAdmin
- ARQ workers — replaced by Taskiq
- Deployment scripts (
setup.py,scripts/{local_with_uvicorn,gunicorn_managing_uvicorn_workers,production_with_nginx}/) — replaced bybp deploy generate mkdocs.yml— replaced byzensical.toml- Demo
postsmodule — pure demo code, not needed backend/uv.lock— stale duplicate of workspaceuv.lock
Breaking Changes¶
⚠️ Eight breaking changes. The migration path for forks with significant custom code is "copy your business logic into the new structure" — there is no sed-style find-and-replace.
| Change | Impact | Migration |
|---|---|---|
src/app/ layout removed |
Imports break at import time | Manual restructure into modules/<name>/ |
| JWT removed | Authorization: Bearer clients rejected |
Switch clients to cookie auth |
| CRUDAdmin → SQLAdmin | Custom admin views need porting | Port to ModelView shape |
| ARQ → Taskiq | Workers need re-registration | Rewrite tasks as @broker.task async functions |
| API key hash format | Existing keys won't validate | Users must regenerate |
| Settings composition | Env var names mostly stable; a few moved | Diff .env.example |
| Sync command | cd backend && uv sync --extra dev produces broken venv |
Use uv sync --all-packages --all-extras from repo root |
| Deployment scaffolder | ./setup.py local removed |
uv run bp deploy generate {local,prod,nginx} |
For brand-new projects, v0.18.0 is the better starting point. For existing apps with significant custom code on v0.17.0, pinning to v0.17.0 may be the right call — that tag stays supported.
New Co-Maintainers¶
- @carlosplanchon and @emiliano-gandini-outeda are now officially helping maintain and improve the boilerplate.
Full release notes: https://github.com/benavlabs/FastAPI-boilerplate/releases/tag/v0.18.0 Full changelog: https://github.com/benavlabs/FastAPI-boilerplate/compare/v0.17.0...v0.18.0