Middleware Configuration¶
This reference covers configuration classes for non-security middleware in Cello: CORS, compression, logging, static files, body limits, and Prometheus metrics.
CORS Configuration¶
CORS is enabled via app.enable_cors(). For simple use cases, pass a list of origins directly.
| Parameter | Type | Default | Description |
|---|---|---|---|
origins | list[str] | ["*"] | Allowed origin domains |
The CORS middleware automatically handles:
Access-Control-Allow-OriginheaderAccess-Control-Allow-Methodsheader (all methods enabled)Access-Control-Allow-Headersheader (common headers)Access-Control-Max-Ageheader (preflight caching)- OPTIONS preflight requests
Wildcard Origins¶
Using ["*"] allows any origin. This is convenient for development but should be restricted in production.
# Development
app.enable_cors(origins=["*"])
# Production
app.enable_cors(origins=["https://myapp.com"])
Compression Configuration¶
Enable gzip compression for responses above a size threshold.
| Parameter | Type | Default | Description |
|---|---|---|---|
min_size | int | 1024 | Minimum response body size in bytes to trigger compression |
Behavior¶
- Only compresses responses where
Content-Length >= min_size. - Only compresses when the client sends
Accept-Encoding: gzip. - Skips already-compressed content types (images, videos).
- Adds
Content-Encoding: gzipto compressed responses.
Logging Configuration¶
Enable request/response logging.
No configuration parameters. Log output includes:
| Field | Example |
|---|---|
| Method | GET |
| Path | /api/users |
| Status | 200 |
| Latency | 1.23ms |
| Timestamp | ISO 8601 |
Disabling Logs¶
Static Files Configuration¶
from cello import StaticFilesConfig
app.enable_static_files(StaticFilesConfig(
directory="./static",
prefix="/static",
index_file="index.html",
cache_max_age=3600,
))
| Field | Type | Default | Description |
|---|---|---|---|
directory | str | Required | Path to the directory containing static files |
prefix | str | "/static" | URL prefix for static file requests |
index_file | str | "index.html" | Default file served for directory requests |
cache_max_age | int | 3600 | Cache-Control: max-age value in seconds |
Example¶
With directory="./static" and prefix="/static":
GET /static/css/app.cssserves./static/css/app.cssGET /static/js/main.jsserves./static/js/main.jsGET /static/serves./static/index.html
Body Limit Configuration¶
Restrict the maximum request body size.
| Parameter | Type | Default | Description |
|---|---|---|---|
max_size | int | 10485760 | Maximum body size in bytes (10 MB) |
Requests exceeding the limit receive a 413 Payload Too Large response before the body is fully read.
Prometheus Configuration¶
Expose Prometheus-compatible metrics.
| Parameter | Type | Default | Description |
|---|---|---|---|
endpoint | str | "/metrics" | URL path for the metrics endpoint |
namespace | str | "cello" | Prometheus metric namespace |
subsystem | str | "http" | Prometheus metric subsystem |
Exposed Metrics¶
| Metric | Type | Description |
|---|---|---|
{ns}_{sub}_requests_total | Counter | Total request count by method and status |
{ns}_{sub}_request_duration_seconds | Histogram | Request latency distribution |
{ns}_{sub}_requests_in_flight | Gauge | Currently active requests |
{ns}_{sub}_response_size_bytes | Histogram | Response body size distribution |
Where {ns} is the namespace and {sub} is the subsystem.
Scraping¶
Add the metrics endpoint to your Prometheus configuration:
# prometheus.yml
scrape_configs:
- job_name: cello-app
static_configs:
- targets: ["app:8000"]
metrics_path: /metrics
scrape_interval: 15s
Caching Configuration¶
| Parameter | Type | Default | Description |
|---|---|---|---|
ttl | int | 300 | Default cache lifetime in seconds |
methods | list[str] | ["GET", "HEAD"] | HTTP methods to cache |
exclude_paths | list[str] | [] | Paths excluded from caching |
ETag Configuration¶
No configuration parameters. The middleware automatically:
- Generates an ETag hash for every response body.
- Adds the
ETagheader to responses. - Returns
304 Not Modifiedwhen the client sends a matchingIf-None-Matchheader.
Request ID Configuration¶
No configuration parameters. Each request receives a UUID v4 identifier in:
request.context["request_id"]X-Request-IDresponse header
If the incoming request already has an X-Request-ID header, that value is preserved.
Summary¶
| Configuration | Method | Key Parameters |
|---|---|---|
| CORS | enable_cors() | origins |
| Compression | enable_compression() | min_size |
| Logging | enable_logging() | None |
| Static Files | enable_static_files() | directory, prefix |
| Body Limit | enable_body_limit() | max_size |
| Prometheus | enable_prometheus() | endpoint, namespace |
| Caching | enable_caching() | ttl, exclude_paths |
| ETag | enable_etag() | None |
| Request ID | enable_request_id() | None |