Overview
chirpis the command-line entry point installed with the framework. You use it
to scaffold a new project, validate your hypermedia wiring, run the dev or
production server, and inspect routes. This page is the reference for the three
commands you reach for most —chirp new, chirp check, and
chirp shapes-codegen— plus a table of the rest.
Every command takes an app import string of the formmodule:attribute
(for examplemyapp:app). When you omit the attribute, it defaults to app, so
myapp resolves to myapp.app. A callable that is not already an App— an app
factory likecreate_app— is called to produce one.
chirp --version # chirp, kida, pounce, and Python versions
chirp <command> --help # flags for any command
Command summary
| Command | What it does |
|---|---|
chirp new <name> |
Scaffold a new project directory. |
chirp check <app> |
Validate hypermedia contracts (mirrorsapp.check()). |
chirp shapes-codegen [path] |
Suggest@shapedecorators and audit Shape drift. |
chirp run <app> |
Start the dev or production server. |
chirp dev <app> |
Dev server with browser reload on template/CSS changes. |
chirp routes <app> |
Print the registered route table. |
chirp security-check <app> |
Audit config against an OWASP checklist. |
chirp freeze <app> <out> |
Render routes to static HTML files. |
chirp makemigrations |
Generate a schema migration from a SQL diff. |
chirp migrate |
Apply pending schema migrations (one-shot deploy job). |
The three commands below are documented in full. Forrun/devsee
Production deployment; forfreezesee
Freeze and hybrid hosting; for
makemigrations and migratesee Database.
chirp new— scaffold a project
chirp new <name>creates a project directory you can run immediately. The
default scaffold is auth-ready: a filesystem-routedpages/tree with a login
flow, a dashboard, the secure-by-default middleware stack, and a passing
chirp check. Flags switch to a different starting point.
chirp new myapp
cd myapp && python app.py
The default scaffold prints its own next steps — a login of admin / password
and a dashboard at/dashboard. It refuses to overwrite an existing directory.
| Flag | Result |
|---|---|
| (none) | Auth + dashboard + filesystem routing (pages/), tests, pyproject.toml. |
--minimal |
A single-file project:app.py plus templates/index.html. |
--sse |
SSE boilerplate — anEventStream route wired with sse_scope. |
--shell |
A persistent app shell (topbar, sidebar) over filesystem routing. |
--with-chirpui |
Require chirp-ui templates; fail if it is not installed. |
Every scaffold — including--minimal— wires the secure-by-default stack
(SessionMiddleware → CSRFMiddleware → SecurityHeadersMiddleware) and reads
the secret key fromCHIRP_SECRET_KEY, so a generated app passes chirp check
out of the box.
chirp check— validate contracts
chirp check <app>resolves the app, runs the contract suite, and prints the
report. It is the same validation that [[docs/about/core-concepts/contracts|app.check()]]
runs in debug mode — fail loud at startup, not silent at runtime. The process
exits with code 1 when any ERROR-severity issue is found, which makes it a CI
gate.
chirp check myapp:app
| Flag | Effect |
|---|---|
--warnings-as-errors |
Exit 1 if any WARNING is present, not just ERRORs. The standard CI posture. |
--coverage |
Print route/template contract coverage counters alongside the report. |
--deploy |
Run env-aware rules with production-posture severity. Implies--warnings-as-errors. |
--deployis the deploy preflight. Some rules — a missing secure-by-default
stack on an app with mutating routes is the canonical one — fire at a lower
severity in development than in production.--deployescalates those to
production posture even when you run it locally, so a deploy-blocking
misconfiguration surfaces as an ERROR before you ship. It does not mutate your
app; a genuinely deploy-ready app still passes.
# Standard CI gate — fail on any error or warning
chirp check myapp:app --warnings-as-errors
# Deploy preflight — production posture (implies --warnings-as-errors)
chirp check myapp:app --deploy
chirp shapes-codegen— adopt and audit Shapes
New in 0.8chirp shapes-codegen [path]helps you adopt Shapes
incrementally. It has two non-destructive modes.
Suggest decorators (default). It scans Python files for frozen dataclasses
sitting near an explicit named-columnSELECTliteral, pairs each class to the
SELECTwhose output columns are a subset of its fields, and prints a
@shape(...) suggestion above each match. --dry-runis the default and the
only write behavior — nothing on disk changes.
chirp shapes-codegen pages/
--- pages/boards.py:14 (BoardView)
+ @shape('SELECT id, title FROM boards WHERE id = :id')
@dataclass(frozen=True, slots=True)
class BoardView: # columns: id, title
3 @shape suggestion(s) (dry-run — no files written).
Already-decorated classes are skipped, and only SELECTs the conservative parser
can read are paired (SELECT *, expressions, CTEs, and UNIONare skipped), so a
suggestion is always one the contract checker can later verify.
Audit drift (--audit). It loads an app and reports every surface-contract
name with no backing Shape, reusing the exact registry-drift logicapp.check()
runs. With--audit, pathbecomes an app import string, and the command exits
non-zero when drift is found — so it drops straight into CI.
chirp shapes-codegen myapp:app --audit
| Argument / flag | Purpose |
|---|---|
path |
Directory or file to scan (default.); with --audit, an app import string like myapp:app. |
--dry-run |
Print suggested@shapedecorators without writing files (the default behavior). |
--audit |
Auditsurface_contractsfor names with no backing Shape; exit non-zero on drift. |
--migrations DIR |
Migrations directory (reserved for future incremental codegen output). |
chirp migrate— apply pending migrations
New in 0.9chirp migrate --db <url> --migrations-dir <dir>applies pending migrations
from a directory as a one-shot job. It connects to the database, runs
[[docs/build-apps/forms-data/database|migrate()]], prints a summary, and
disconnects. It does not import or boot your app (no freeze, no contract
checks) — it takes the same--db / --migrations-dirflags as
makemigrations, not an app import string.
chirp migrate --db "$DATABASE_URL" --migrations-dir migrations
It is fail-loud: a failed migration, an invalid migrations directory, or a
checksum-drift edit of an already-applied migration prints the error and exits
1. Nothing is swallowed.
Pair it withAppConfig(skip_migrations=True) (or CHIRP_SKIP_MIGRATIONS=1) so
the app does not also run migrations on boot. In a multi-replica deploy this
lets a single pre-deploy job own migration application instead of every replica
racing on startup. When the on-boot run is skipped, the app logs a
lifecycle:migrations-skippedwarning so a missing deploy job (and the
resulting stale schema) is visible. See
Production deployment.
| Flag | Effect |
|---|---|
--db |
Database URL (required), e.g.sqlite:///app.db. |
--migrations-dir |
Directory containing migration files (defaultmigrations). |