Fabbro
An opinionated Python web framework for building custom, on-demand web software fast — and for making AI-generated code production-fit: secured by default, no hardcoded secrets, built around reusable modules.
fabbro create scaffolds a working project with a production-ready foundation —
authentication, an encrypted secret vault, a background worker queue, and an
external-API registry — plus a dev-only interactive playbook that walks you
through it.
Install
pip install fabbro
Requires Python 3.12+.
Quickstart
fabbro create myproject
cd myproject
python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
fabbro doctor # pre-flight checks; creates .env with the keys it needs
fabbro secret gen # fill SECRET_KEY / FERNET_KEY in .env
fabbro create-admin # create the first admin user
fabbro start # run playbooks + app + all workers together
Prefer to scaffold into the current directory (e.g. a fresh git repo root)
instead of a subfolder? Use fabbro create myproject --here.
fabbro start is the local equivalent of docker-compose: it loads secrets from
.env and runtime vars (DB_PATH, APP_BASE_URL) from config/runtime.yaml,
then boots the playbook server (:4600), the app (:5000), and every worker
under workers/ — auto-discovered, no extra terminals. One Ctrl-C stops it
all.
What you get
Fabbro turns AI-generated code into production-fit code. The two failure modes of AI-written web apps — secrets and settings hardcoded into logic, and security reinvented (badly) on every project — are designed out from the start:
- Nothing hardcoded. What AI usually bakes into code — passwords hashing
cost, cookie flags, token TTLs, rate limits, CSP, role policy — lives in
versioned YAML config, not in source. Change a limit, rotate a policy,
tighten a cookie: edit
config/, not your logic. - Security is reusable and already implemented. Rate limiting, secure
cookies, CSRF, CSP, HSTS, Argon2id — shipped once in
core/, imported and never rewritten. AI extends your app through config and extension points, not by re-authoring the security layer each time.
The scaffolded project ships with a reusable core/ you import but never edit:
| Area | What's in the box |
|---|---|
| Auth & sessions | Argon2id hashing with rehash · session rotation on login · CSRF on every mutation · CSP with per-request nonce · require_auth / require_role gating · role policy in auth.yaml |
| Rate limiting | Per-route limits by IP, email, and user — all declared in security.yaml (10 per minute on login, tighter on password reset, etc.) |
| Secure defaults | Cookie SameSite + secure, HSTS, permissions-policy, Argon2 tuning — every value in config, none in code |
| Secret vault | Provider credentials encrypted at rest (Fernet) · one canonical resolution cascade (vault → _FILE → env) — never in source |
| Background worker | SQLite-backed job queue · atomic claim under a WAL lock · heartbeat reaper for crashed jobs |
| API registry | Register providers by OpenAPI spec, autodiscovery, or manually · bind endpoints as stable service.verb aliases your modules call |
CLI
| Command | Purpose |
|---|---|
fabbro create <name> |
Scaffold a new project (--here scaffolds into the current directory) |
fabbro start |
Run the whole dev stack: playbooks, app, and all workers |
fabbro create-admin |
Create the first admin user |
fabbro doctor |
Run the project's pre-flight checks |
fabbro secret gen |
Generate base secrets into .env |
fabbro vault set·list·rm |
Manage provider API credentials |
fabbro registry … |
Inspect and drive the API registry |
Run any command with
--helpfor its full options.
Notes for 0.1.1
A 0.x release with a couple of deliberate, declared gaps — safe under the
intended single-tenant, trusted-input use, and scheduled to change as the
surface grows:
| Area | Current behavior |
|---|---|
| Registry autodiscovery | Outbound requests to a provider's base_url aren't yet validated against private/loopback ranges — use trusted base_url values. Full SSRF allowlist lands with the public-API surface. |
| Session fingerprinting | Sessions are bound to user-agent + IP, so a network or device change logs the user out. Intentional for now; its exact role is an open design decision. |
© Forjelo · Licensed under BUSL-1.1 · Built for certified Fabbro developers.
Metadata
Release files for fabbro 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fabbro-0.1.1.tar.gz | 420.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fabbro-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 873.0 kB
Release files / fabbro-0.1.1.tar.gz
| Download URL | fabbro-0.1.1.tar.gz |
|---|---|
| Size | 420.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4b1c28a0c9d2b1f2ce2cde8661b260250f368dfb684fb922e41bd8dfb749e68c
|
|
BLAKE2b-256 checksum How to use checksums |
8836177fc463c5cf83a05fe1c408e133130344ca04351a49ffcb1fd9cfa8a2b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Release files / fabbro-0.1.1-py3-none-any.whl
| Download URL | fabbro-0.1.1-py3-none-any.whl |
|---|---|
| Size | 452.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cb10a28b50e7734ecb1f67acdfbe547cf6edd105341da93c49d0e2b24d5c5d14
|
|
BLAKE2b-256 checksum How to use checksums |
8a51b88956504c0e7775dabf68c016e16d599ee840b588111dd61646295127a3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|