AppConfig
Chirp uses a frozen dataclass for configuration. Every field has IDE autocomplete, type checking, and no runtimeKeyErrorsurprises.
from chirp import App, AppConfig
config = AppConfig(
debug=True,
host="0.0.0.0",
port=8000,
secret_key="change-me-in-production",
template_dir="templates/",
)
app = App(config=config)
AppConfig is @dataclass(frozen=True, slots=True). Once created, it cannot be mutated. This is intentional -- config should not change after the app starts.
Configuration Fields
| Field | Type | Default | Description |
|---|---|---|---|
debug |
bool |
False |
Enable debug mode (verbose errors, template auto-reload) |
host |
str |
"127.0.0.1" |
Bind address for the development server |
port |
int |
8000 |
Bind port for the development server |
secret_key |
str | None |
None |
Secret key for session signing (required for sessions) |
template_dir |
str |
"templates" |
Directory for kida templates |
static_dir |
str | None |
None |
Directory for static files (if using StaticFiles middleware) |
static_url |
str |
"/static" |
URL prefix for static files |
safe_target |
bool |
True |
Auto-addhx-target="this"to event-driven elements |
sse_lifecycle |
bool |
True |
Inject SSE connection status (data-sse-state) and custom events |
view_transitions |
bool | str |
False |
View Transitions tier:False/"off" (none), True/"htmx" (htmx only), "full"(htmx + MPA) |
speculation_rules |
bool | str |
False |
Speculation Rules tier:False/"off" (none), True/"conservative" (prefetch on hover), "moderate", "eager" |
alpine |
bool |
False |
Enable Alpine.js script injection (use_chirp_ui sets this to Trueautomatically) |
alpine_version |
str |
"3.15.8" |
Pinned Alpine version (jsdelivr CDN) |
alpine_csp |
bool |
False |
Use CSP-safe Alpine build for strict Content-Security-Policy |
islands |
bool |
False |
Inject framework-agnostic islands runtime lifecycle hooks |
islands_version |
str |
"1" |
Version tag exposed indata-island-versionand runtime events |
islands_contract_strict |
bool |
False |
Warn on missing stable island mount IDs duringapp.check() |
sse_heartbeat_interval |
float |
15.0 |
Seconds between SSE heartbeat comments |
sse_retry_ms |
int | None |
None |
SSE reconnection interval sent to client |
max_content_length |
int |
16777216 |
Maximum request body size in bytes (16 MB) |
Debug Mode
Whendebug=True:
- Detailed error pages with tracebacks are shown in the browser
- Templates auto-reload when modified (no server restart needed)
- Stricter validation warnings are surfaced
config = AppConfig(debug=True)
Warning
Never enable debug mode in production. It exposes internal details including source code and tracebacks.
Secret Key
Required for session middleware and CSRF protection. Use a strong random value in production:
import secrets
config = AppConfig(
secret_key=secrets.token_hex(32),
)
Note
If you useSessionMiddleware or CSRFMiddleware without setting a secret_key, Chirp raises a ConfigurationErrorat startup.
Default Configuration
If you don't pass a config, sensible defaults are used:
app = App() # Uses default AppConfig
This is equivalent to:
app = App(config=AppConfig())
Next Steps
- App Lifecycle -- How the app freezes
- Built-in Middleware -- Middleware that uses config
- API Reference -- Complete API surface