Module

app

Chirp application facade.

Classes

App 42
The chirp application. Mutable during setup (route registration, middleware, filters). Frozen at r…

The chirp application.

Mutable during setup (route registration, middleware, filters). Frozen at runtime whenapp.run() or __call__()is first invoked.

Methods

db 0 Database
property
def db(self) -> Database
Returns
Database
tools 0 Any
The frozen ``ToolRegistry`` — available after ``app.run()`` / freeze. Use to i…
property
def tools(self) -> Any

The frozenToolRegistry — available after app.run()/ freeze.

Use to inspect registered tools::

for tool_info in app.tools.list_tools():
    print(tool_info["name"])

RaisesRuntimeErrorif accessed before the app is frozen.

Returns
Any
tool_events 0
property
def tool_events(self)
bind_config 1
Set ``config`` on the app and mirror it into internal subsystems. The compiler…
def bind_config(self, config: AppConfig) -> None

Setconfigon the app and mirror it into internal subsystems.

The compiler, ASGI runtime, server launcher, lifecycle coordinator, and contract checker each hold their own reference from construction. Reassigningapp.configalone leaves those stale — use this after App() when CLI helpers or extensions replace fields (e.g. debug, alpine, dev_browser_reload) before run()/freeze.

Parameters
Name Type Description
config
route 6 Callable[[Callable[..., …
def route(self, path: str, *, methods: list[str] | None = None, name: str | None = None, referenced: bool = False, template: str | None = None, inline: bool = False) -> Callable[[Callable[..., Any]], Callable[..., Any]]
Parameters
Name Type Description
path
methods Default:None
name Default:None
referenced Default:False
template Default:None
inline Default:False
Returns
Callable[[Callable[..., Any]], Callable[..., Any]]
provide 2
def provide(self, annotation: type, factory: Callable[..., Any]) -> None
Parameters
Name Type Description
annotation
factory
mount_pages 1
def mount_pages(self, pages_dir: str | None = None) -> None
Parameters
Name Type Description
pages_dir Default:None
register_domain 1
def register_domain(self, domain: object) -> None
Parameters
Name Type Description
domain
tool 2 Callable[[Callable[..., …
def tool(self, name: str, *, description: str = '') -> Callable[[Callable[..., Any]], Callable[..., Any]]
Parameters
Name Type Description
name
description Default:''
Returns
Callable[[Callable[..., Any]], Callable[..., Any]]
error 1 Callable[[Callable[..., …
def error(self, code_or_exception: int | type[Exception]) -> Callable[[Callable[..., Any]], Callable[..., Any]]
Parameters
Name Type Description
code_or_exception
Returns
Callable[[Callable[..., Any]], Callable[..., Any]]
register_oob_region 5
Register an OOB region for automatic layout-contract discovery. Call during se…
def register_oob_region(self, block_name: str, *, target_id: str, swap: str = 'innerHTML', wrap: bool = True, optional: bool = False) -> None

Register an OOB region for automatic layout-contract discovery.

Call during setup (before app.run()). The block_name must match a {% region <block_name>(...) %}in your layout template.

optional: When True, layouts that omit the block are allowed — the region is silently skipped at render time and the orphan-registration check downgrades to WARNING. Default False means missing blocks are ERRORs atapp.check()and render-time KeyErrors become BlockNotFoundErrorwith a clear message.

Parameters
Name Type Description
block_name
target_id
swap Default:'innerHTML'
wrap Default:True
optional Default:False
register_fragment_target 5
Register a fragment target for HTMX content-region block selection. When HX-Ta…
def register_fragment_target(self, target_id: str, *, fragment_block: str, triggers_shell_update: bool = True, scope_name: str | None = None, omit_outer_layouts: bool = False) -> None

Register a fragment target for HTMX content-region block selection.

When HX-Target matches target_id (e.g.page-root), Chirp uses fragment_block instead of composition.page_block. Call during setup.

triggers_shell_update: When True (default), swapping this target triggers shell_actions OOB (topbar, breadcrumbs, sidebar). Use False for narrow content swaps (e.g. page-content-inner) that should not update the shell.

scope_name: Optional symbolic scope (e.g."site") for hierarchical OOB propagation. When set, OOB updates are scoped to this level and above.

omit_outer_layouts: When True, boosted fragment responses for this target skip wrapping with filesystem layouts (page block only). Use for root marketing shells whose outlet is the primary{% block content %} region so the layout is not nested inside itself on swap.

Parameters
Name Type Description
target_id
fragment_block
triggers_shell_update Default:True
scope_name Default:None
omit_outer_layouts Default:False
register_page_shell_contract 1
Register a named page shell contract and its fragment targets. This makes app-…
def register_page_shell_contract(self, contract: PageShellContract) -> None

Register a named page shell contract and its fragment targets.

This makes app-shell expectations explicit and lets contract checks validate required fragment blocks across page templates.

Parameters
Name Type Description
contract
register_layout_preset 8
Register a named preset for `_layout.html` metadata defaults. Layouts opt in w…
def register_layout_preset(self, name: str, *, target: str | None = None, domain_name: str | None = None, shell_name: str | None = None, swap_scope_name: str | None = None, outlet_target_id: str | None = None, frame_targets: frozenset[str] | None = None, outlet_mode: OutletSwapMode | None = None) -> None

Register a named preset for_layout.htmlmetadata defaults.

Layouts opt in with{# preset: name #}. Explicit comments in the template override preset defaults, letting apps encode a shell convention once and keep route-tree metadata terse.

Parameters
Name Type Description
name
target Default:None
domain_name Default:None
shell_name Default:None
swap_scope_name Default:None
outlet_target_id Default:None
frame_targets Default:None
outlet_mode Default:None
register_swap_scope 2
Map a symbolic swap scope to a concrete fragment target id (no ``#``). Used by…
def register_swap_scope(self, scope: str, target_id: str) -> None

Map a symbolic swap scope to a concrete fragment target id (no#).

Used byresolve_navigation_swap() and the swap_attrstemplate global so layouts can declare{# swap_scope: name #}and links can resolvehx-targetfrom route geometry.

Parameters
Name Type Description
scope
target_id
get_layout_chain_for_path 1 LayoutChain | None
Return the filesystem `LayoutChain` for a GET route path, if any. Uses the com…
def get_layout_chain_for_path(self, path: str) -> LayoutChain | None

Return the filesystemLayoutChainfor a GET route path, if any.

Uses the compiled router and route table built at freeze time. Unknown paths or non-filesystem routes returnNone.

Parameters
Name Type Description
path
Returns
LayoutChain | None
freeze_params 1 Callable[[Callable[..., …
Register a parameter provider for ``chirp freeze``. The decorated function mus…
def freeze_params(self, path: str) -> Callable[[Callable[..., Any]], Callable[..., Any]]

Register a parameter provider forchirp freeze.

The decorated function must return a list of dicts, each mapping parameter names to values. Example::

@app.freeze_params("/docs/{slug:path}")
def docs_params():
    return [{"slug": p.slug} for p in collection.pages]
Parameters
Name Type Description
path
Returns
Callable[[Callable[..., Any]], Callable[..., Any]]
freeze_exclude 1
Exclude a route path from ``chirp freeze``. Fragment-only or dynamic routes th…
def freeze_exclude(self, path: str) -> None

Exclude a route path fromchirp freeze.

Fragment-only or dynamic routes that should never be written as static pages can call this during setup::

app.freeze_exclude("/docs/search")
Parameters
Name Type Description
path
live_block 6 Callable[[Callable[..., …
Declare a live block — a template block served dynamically from a frozen page. …
def live_block(self, route: str, block: str, *, trigger: str = 'load', swap: str = 'innerHTML', skeleton: str | None = None, cache_seconds: int | None = None) -> Callable[[Callable[..., Any]], Callable[..., Any]]

Declare a live block — a template block served dynamically from a frozen page.

At freeze time the named block is replaced in the emitted HTML with an htmx placeholder that fetches from/_frag{route}?_b={block}. At request time the block-fetch dispatcher invokes the decorated handler and returns only the named block.

route must match a registered route; blockmust be a named block in that route's template. Both are validated atapp.check()::

@app.live_block("/docs/{slug:path}", "recent_updates")
async def recent_updates(request: Request) -> Fragment:
    return Fragment("docs/page.html", "recent_updates", updates=...)
Parameters
Name Type Description
route
block
trigger Default:'load'
swap Default:'innerHTML'
skeleton Default:None
cache_seconds Default:None
Returns
Callable[[Callable[..., Any]], Callable[..., Any]]
mount 2
Mount a plugin at the given URL prefix. Calls ``plugin.register(app, prefix)``…
def mount(self, prefix: str, plugin: object) -> None

Mount a plugin at the given URL prefix.

Callsplugin.register(app, prefix)during setup phase.

Parameters
Name Type Description
prefix
plugin
mount_app 2
Mount another Chirp `App` at ``prefix``, consuming it. Hoists the sub-app's pe…
def mount_app(self, prefix: str, sub_app: App) -> None

Mount another ChirpApp at prefix, consuming it.

Hoists the sub-app's pending routes (prefixed), middleware, lifecycle hooks, template globals/filters, and other registrations ontoself. Parent wins on template-global / filter / error-handler / provider collisions (seechirp.app.mountfor the full merge matrix).

After this call,sub_appis consumed — calling sub_app.freeze() or sub_app.run() raises RuntimeError. Use this during migrations when you need two full apps on one port, not as a permanent composition pattern. Seedocs/rfcs/005-mount-app.md.

Parameters
Name Type Description
prefix
sub_app
add_loader 1
Add a template loader (e.g., from a plugin's PackageLoader).
def add_loader(self, loader: object) -> None
Parameters
Name Type Description
loader
add_middleware 1
def add_middleware(self, middleware: object) -> None
Parameters
Name Type Description
middleware
add_reload_dir 1
def add_reload_dir(self, path: str) -> None
Parameters
Name Type Description
path
register_section 1
Register a named section for route metadata resolution.
def register_section(self, section: Section) -> None
Parameters
Name Type Description
section
register_contract_check 1
Register a custom contract check that runs during ``app.check()``. The callabl…
def register_contract_check(self, check: Callable[..., Any]) -> None

Register a custom contract check that runs duringapp.check().

The callable must accept(snapshot, result)where snapshot is aContractCheckSnapshotand result is a CheckResult. Append issues to result.issues.

Both plain functions and callable class instances are accepted.

Parameters
Name Type Description
check
set_contract_check_data 2
Store arbitrary data for use by custom contract checks. Data is available in `…
def set_contract_check_data(self, key: str, value: Any) -> None

Store arbitrary data for use by custom contract checks.

Data is available insnapshot.extras[key]during app.check().

Parameters
Name Type Description
key
value
override_contract_severity 2
Override the severity of all contract issues in *category*. Applied as a post-…
def override_contract_severity(self, category: str, severity: Severity) -> None

Override the severity of all contract issues in category.

Applied as a post-processing step after all checks (built-in and custom) have run. For example, to promote dead-template warnings to errors::

app.override_contract_severity("dead", Severity.ERROR)
Parameters
Name Type Description
category
severity
template_filter 1 Callable[[Callable[..., …
def template_filter(self, name: str | None = None) -> Callable[[Callable[..., Any]], Callable[..., Any]]
Parameters
Name Type Description
name Default:None
Returns
Callable[[Callable[..., Any]], Callable[..., Any]]
template_global 1 Callable[[Callable[..., …
def template_global(self, name: str | None = None) -> Callable[[Callable[..., Any]], Callable[..., Any]]
Parameters
Name Type Description
name Default:None
Returns
Callable[[Callable[..., Any]], Callable[..., Any]]
url_for 2 str
Reverse a named route to a URL path. Path-param kwargs substitute into ``{brac…
def url_for(self, name: str, /, **params: Any) -> str

Reverse a named route to a URL path.

Path-param kwargs substitute into{braces}and are percent-encoded; any leftover kwargs become a urlencoded query string.

RaisesLookupError when nameis not registered (the message lists every known name) andKeyErrorwhen a required path param is missing. Also registered as theurl_fortemplate global.

Parameters
Name Type Description
name
**params
Returns
str
on_startup 1 Callable[..., Any]
def on_startup(self, func: Callable[..., Any]) -> Callable[..., Any]
Parameters
Name Type Description
func
Returns
Callable[..., Any]
on_shutdown 1 Callable[..., Any]
def on_shutdown(self, func: Callable[..., Any]) -> Callable[..., Any]
Parameters
Name Type Description
func
Returns
Callable[..., Any]
on_worker_startup 1 Callable[..., Any]
def on_worker_startup(self, func: Callable[..., Any]) -> Callable[..., Any]
Parameters
Name Type Description
func
Returns
Callable[..., Any]
on_worker_shutdown 1 Callable[..., Any]
def on_worker_shutdown(self, func: Callable[..., Any]) -> Callable[..., Any]
Parameters
Name Type Description
func
Returns
Callable[..., Any]
run 3
Freeze the app and start the development server. In debug mode, freeze runs th…
def run(self, host: str | None = None, port: int | None = None, *, lifecycle_collector: LifecycleCollector | None = None) -> None

Freeze the app and start the development server.

In debug mode, freeze runs the full hypermedia contract suite (routes, fragment targets, OOB regions, htmx attrs, SSE wiring, layouts, alpine CDN, defer_falsy, composition_extends, plus any registered custom checks) and prints a colored banner to stderr. An ERROR-severity issue exits before the server starts. Disable withAppConfig(skip_contract_checks=True)or CHIRP_SKIP_CONTRACT_CHECKS=1.

Parameters
Name Type Description
host Default:None
port Default:None
lifecycle_collector Default:None
handle_sync 1 object | None
Fused sync path — bypass ASGI for simple request-response handlers. Returns Ra…
def handle_sync(self, raw: object) -> object | None

Fused sync path — bypass ASGI for simple request-response handlers.

Returns RawResponse for sync handling, or None to fall through to ASGI.

Parameters
Name Type Description
raw
Returns
object | None
freeze 0
Freeze the app, finalizing all configuration. Idempotent — safe to call multip…
def freeze(self) -> None

Freeze the app, finalizing all configuration.

Idempotent — safe to call multiple times. After freezing, no further routes, middleware, or plugins can be registered.

In debug mode, freeze also runs the hypermedia contract checks and exits on ERROR (same suite asapp.check()). Disable with AppConfig(skip_contract_checks=True)or the CHIRP_SKIP_CONTRACT_CHECKSenv var.

Useful in tests and CI to callapp.check()without starting a server::

app.freeze()
app.check()
check 2
Validate hypermedia contracts against the frozen app and print a report. Runs …
def check(self, *, warnings_as_errors: bool = False, coverage: bool = False) -> None

Validate hypermedia contracts against the frozen app and print a report.

Runs every registered contract check (routes, fragment targets, OOB regions, htmx attributes, SSE wiring, accessibility, layout chains, plus any custom checks added viaregister_contract_check()) and writes a colored report to stdout.

Intended use: call from CI or a startup script.chirp check <app> wraps this method.

Parameters
Name Type Description
warnings_as_errors

When True, WARNING-severity issues fail the check alongside errors (use this in CI to fail on drift).

Default:False
coverage

When True, include contract coverage counters for POST form contracts, mounted page contracts, app-shell targets, and OOB regions.

Default:False
render 1 str
Render a Fragment, Template, or InlineTemplate to HTML without an HTTP request.…
def render(self, value: Fragment | Template | InlineTemplate) -> str

Render a Fragment, Template, or InlineTemplate to HTML without an HTTP request.

Use for tests, background jobs, scripts, or AI runtimes that need to produce HTML from the app's templates.

Parameters
Name Type Description
value
Returns
str
Internal Methods 2
__init__ 4
def __init__(self, config: AppConfig | None = None, *, db: Database | str | None = None, migrations: str | None = None, kida_env: Environment | None = None) -> None
Parameters
Name Type Description
config Default:None
db Default:None
migrations Default:None
kida_env Default:None
__call__ 3
async
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None
Parameters
Name Type Description
scope
receive
send