{"pages": [{"category": "home", "content": "Python ASGI Server for Free-Threaded Python Pure Python. Frozen config. True parallelism. Pounce is a pure-Python ASGI server for Python 3.14t with a low-overhead HTTP/1.1 fast path, a frozen shared ServerConfig, and thread-worker reload draining. No C extensions in the server core. import pounce pounce.run(\"myapp:app\") Why Use Pounce Cpu Free-Threading Native True OS thread parallelism on Python 3.14t. N workers share one interpreter with a frozen server configuration object. Fast-Path Parsing Built-in HTTP/1.1 parser for sync workers covers method validation, header size limits, duplicate...", "description": "A Python ASGI server for deployments, streaming responses, and free-threaded Python", "dir": "/", "excerpt": "Python ASGI Server for Free-Threaded Python Pure Python. Frozen config. True parallelism. Pounce is a pure-Python ASGI server for Python 3.14t with a low-overhead HTTP/1.1 fast path, a frozen shared...", "href": "/pounce/", "kind": "page", "objectID": "/", "reading_time": 1, "title": "Pounce", "type": "page", "uri": "/", "url": "/pounce/", "weight": 100.0, "word_count": 289}, {"description": "Browse Python API documentation by package.", "dir": "/", "excerpt": "", "href": "/pounce/api/", "kind": "autodoc-python", "objectID": "/api/", "reading_time": 1, "section": "api", "title": "Pounce API Reference", "type": "autodoc-python", "uri": "/api/", "url": "/pounce/api/", "word_count": 0}, {"description": "Allow running pounce via python -m pounce.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/__main__/", "kind": "autodoc-python", "objectID": "/api/__main__/", "reading_time": 1, "section": "api", "source_file": "src/pounce/__main__.py", "title": "__main__", "type": "autodoc-python", "uri": "/api/__main__/", "url": "/pounce/api/__main__/", "word_count": 0}, {"description": "Standardized performance benchmarks for pounce.\n\nSpawns a pounce server with built-in ASGI apps and drives load using\n``http.client`` from multiple threads.  Reports throughput, latency\npercentiles, and memory usage.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_bench/", "kind": "autodoc-python", "objectID": "/api/_bench/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_bench.py", "title": "_bench", "type": "autodoc-python", "uri": "/api/_bench/", "url": "/pounce/api/_bench/", "word_count": 0}, {"description": "Command-line interface for pounce.\n\nProvides the ``pounce`` command with subcommands::\n\n    pounce serve --app myapp:app --host 0.0.0.0 --port 8000 --workers 4\n\nBuilt on milo-cli for type-driven parsing, MCP server, and llms.txt generation.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_cli/", "kind": "autodoc-python", "objectID": "/api/_cli/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_cli.py", "title": "_cli", "type": "autodoc-python", "uri": "/api/_cli/", "url": "/pounce/api/_cli/", "word_count": 0}, {"description": "Content encoding negotiation and compressor factory.\n\nParses Accept-Encoding headers, selects the best encoding, and returns\nper-request compressor instances. Each compressor is created fresh per\nrequest — never shared between requests or threads.\n\nEncoding priority: zstd > gzip > identity (matching modern browser support).\n\nZstd uses Python 3.14 stdlib compression.zstd (PEP 784).\nGzip uses stdlib zlib for the raw deflate stream.\n\nBoth are stdlib modules that work correctly under free-threading (3.14t).\n\nNote: Brotli (br) is intentionally excluded — the ``brotli`` C extension\nre-enables the GIL on Python 3.14t, defeating pounce's free-threading\narchitecture. Clients that only send ``Accept-Encoding: br`` will receive\nuncompressed responses.\n\nDictionary compression (RFC 9842): When a client sends an\n``Available-Dictionary`` header matching a server-loaded dictionary,\nresponses use ``dcz`` (dictionary-compressed zstd) encoding for\ndramatically better compression ratios on repetitive payloads.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_compression/", "kind": "autodoc-python", "objectID": "/api/_compression/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_compression.py", "title": "_compression", "type": "autodoc-python", "uri": "/api/_compression/", "url": "/pounce/api/_compression/", "word_count": 0}, {"description": "Shared structured-concurrency helpers.\n\nSingle source of truth for the ``FIRST_COMPLETED`` race that several\nrequest/connection handlers run: the ASGI app task is raced against a\ncompanion task (disconnect monitor, body reader, frame reader, ...) and\nwhichever finishes first wins. The losing task(s) are always cancelled and\nawaited so no orphaned task is leaked back into the event loop.\n\nCallers keep their own *divergent* winner handling — these helpers only own\nthe part that is byte-identical everywhere (the ``asyncio.wait`` plus the\ncancel-and-drain of losing tasks) and hand back the ``(done, pending)`` split\nso each site can inspect which task won.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_concurrency/", "kind": "autodoc-python", "objectID": "/api/_concurrency/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_concurrency.py", "title": "_concurrency", "type": "autodoc-python", "uri": "/api/_concurrency/", "url": "/pounce/api/_concurrency/", "word_count": 0}, {"description": "TOML configuration file loading for pounce.\n\nSearches for configuration in this order:\n1. ``pounce.toml`` in the current working directory\n2. ``[tool.pounce]`` section in ``pyproject.toml``\n\nValues from the config file are used as defaults — CLI arguments\nalways take precedence.\n\nExample ``pounce.toml``::\n\n    host = \"0.0.0.0\"\n    port = 8080\n    workers = 4\n    log_level = \"debug\"\n\n    [static_files]\n    \"/static\" = \"./public\"\n    \"/assets\" = \"./dist\"\n\nExample ``pyproject.toml``::\n\n    [tool.pounce]\n    host = \"0.0.0.0\"\n    port = 8080\n    workers = 4", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_config_file/", "kind": "autodoc-python", "objectID": "/api/_config_file/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_config_file.py", "title": "_config_file", "type": "autodoc-python", "uri": "/api/_config_file/", "url": "/pounce/api/_config_file/", "word_count": 0}, {"description": "ServerConfig introspection — JSON Schema export and redacted view.\n\nTwo entry points, both consumed by the ``pounce config`` subcommands:\n\n- `build_schema`() / `build_toml_template`() — emit a JSON Schema\n  (Draft 2020-12) or commented ``pounce.toml`` template from the\n  `ServerConfig` dataclass. Enables agents and humans\n  to discover the config surface without reading source.\n- `redacted_config_view`() + `INFO_ALLOWLIST` — produce the\n  fail-closed redacted view used by ``pounce config show`` and the Sprint 4\n  ``/_pounce/info`` endpoint. Every field must appear in the allowlist;\n  absent fields are implicitly redacted.\n\nDesign notes:\n\n- No new runtime dependencies. Stdlib-only (``dataclasses``, ``typing``,\n  ``json``).\n- Deterministic output: properties are emitted in sorted order so golden\n  snapshots remain stable.\n- Internal / callable / opaque fields (the ``_IIC_SKIP_FIELDS`` set in\n  ``config.py``) are skipped in both schema and redacted view.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_config_schema/", "kind": "autodoc-python", "objectID": "/api/_config_schema/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_config_schema.py", "title": "_config_schema", "type": "autodoc-python", "uri": "/api/_config_schema/", "url": "/pounce/api/_config_schema/", "word_count": 0}, {"description": "CPU affinity for worker threads (Linux only).\n\nWhen enabled, pins each worker to a dedicated CPU core to reduce cache\nthrashing and improve throughput on multi-core systems.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_cpu_affinity/", "kind": "autodoc-python", "objectID": "/api/_cpu_affinity/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_cpu_affinity.py", "title": "_cpu_affinity", "type": "autodoc-python", "uri": "/api/_cpu_affinity/", "url": "/pounce/api/_cpu_affinity/", "word_count": 0}, {"description": "Development error pages with rich tracebacks.\n\nProvides beautiful, detailed error pages for debugging during development.\nIn production mode, returns simple 500 errors without exposing internals.\n\nFeatures:\n- Full traceback with source code context\n- Syntax highlighting via Rosettes (if available)\n- Local variables inspection\n- Request details (method, path, headers)\n- Safe for production (only enabled in debug mode)\n\nSecurity:\n- Only active when debug=True in config\n- Never exposes source code or internals in production\n- Sanitizes sensitive data from error output", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_debug/", "kind": "autodoc-python", "objectID": "/api/_debug/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_debug.py", "title": "_debug", "type": "autodoc-python", "uri": "/api/_debug/", "url": "/pounce/api/_debug/", "word_count": 0}, {"description": "Built-in dictionary serving endpoint for RFC 9842 compression dictionaries.\n\nServes dictionary files at ``/.well-known/compression-dictionary/<hash>``\nso clients can download dictionaries advertised via ``Use-As-Dictionary``.\n\nAlso provides ``use_as_dictionary_headers`` for injecting the\n``Use-As-Dictionary`` response header on matching paths, enabling\nbrowser dictionary discovery.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_dictionary_endpoint/", "kind": "autodoc-python", "objectID": "/api/_dictionary_endpoint/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_dictionary_endpoint.py", "title": "_dictionary_endpoint", "type": "autodoc-python", "uri": "/api/_dictionary_endpoint/", "url": "/pounce/api/_dictionary_endpoint/", "word_count": 0}, {"description": "Shared drain-503 wire format and write helpers.\n\nSingle source of truth for the HTTP 503 response that every worker mode\nemits to *new* connections while the server is draining (SIGTERM / SIGHUP).\nKeeping the bytes in one place means the async ``Worker``, the blocking\n``SyncWorker`` and the ``AcceptDistributor`` answer byte-identically:\n\n    HTTP/1.1 503 Service Unavailable\n    Connection: close\n    Retry-After: 1\n    Content-Type: text/plain; charset=utf-8\n    Content-Length: 23\n\n    Server shutting down...\n\nThe body is short and actionable; ``Retry-After`` tells well-behaved\nclients (and load balancers) to come back, while ``Connection: close``\nguarantees the socket is torn down after the single response.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_drain/", "kind": "autodoc-python", "objectID": "/api/_drain/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_drain.py", "title": "_drain", "type": "autodoc-python", "uri": "/api/_drain/", "url": "/pounce/api/_drain/", "word_count": 0}, {"description": "Error hierarchy for pounce.\n\nAll pounce errors inherit from PounceError. Each error maps to an HTTP status\ncode for automatic error response generation.\n\nError categories:\n- ParseError: malformed HTTP from the client (400)\n- RequestTimeoutError: request or keep-alive timeout (408)\n- LimitError: headers or body exceed configured limits (413/431)\n- AppError: the ASGI application raised an exception (500)\n- LifespanError: lifespan startup or shutdown failure (500)\n- SupervisorError: worker spawn or crash-restart failure (500)\n- WorkerError: worker-level failure reported to supervisor (500)\n- TLSError: TLS configuration or handshake failure (500)\n- ReloadError: file-watcher or worker-restart failure during reload (500)\n\nEvery error carries a semantic ``code`` of the form ``POUNCE_<CATEGORY>_<SPECIFIC>``\nand an optional ``hint`` with actionable remediation. See\ndocs/design/error-codes.md for the naming scheme.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_errors/", "kind": "autodoc-python", "objectID": "/api/_errors/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_errors.py", "title": "_errors", "type": "autodoc-python", "uri": "/api/_errors/", "url": "/pounce/api/_errors/", "word_count": 0}, {"description": "Fast HTTP/1.1 parser for the sync worker — replaces h11 on the hot path.\n\nParses request lines and headers directly from bytes using split/index\noperations (~3 µs vs ~22 µs for h11) while enforcing the same safety\nchecks that matter for real-world deployment:\n\n- Method validation (rejects malformed method tokens per RFC 9110)\n- Header size limit (prevents memory exhaustion)\n- Null byte / control character injection in targets and header names\n- Duplicate Content-Length detection (request smuggling vector)\n- Duplicate Host detection (request smuggling / routing-desync vector)\n- Content-Length + Transfer-Encoding conflict (RFC 7230 §3.3.3)\n- Negative or non-numeric Content-Length rejection\n- Chunked Transfer-Encoding detection (returns flag so caller can handle)\n\nNot a full HTTP parser — does not handle:\n- Chunked body decoding (caller must handle or reject)\n- Obs-fold header continuation lines (obsolete since RFC 7230)\n- Trailer headers", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_fast_h1/", "kind": "autodoc-python", "objectID": "/api/_fast_h1/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_fast_h1.py", "title": "_fast_h1", "type": "autodoc-python", "uri": "/api/_fast_h1/", "url": "/pounce/api/_fast_h1/", "word_count": 0}, {"description": "HTTP/2 connection handler — manages multiplexed streams over a single connection.\n\nExtracted from ``worker.py`` to keep protocol-specific connection handling\nseparate from the core Worker lifecycle.  The worker delegates to\n``handle_h2_connection()`` when ALPN negotiation selects ``h2``.\n\nEach function is a standalone coroutine that receives the minimal state\nit needs (app, config, logger) — no Worker reference required.\n\nConnection flow:\n    TLS handshake → ALPN selects \"h2\" → H2Connection state machine\n    → per-stream ASGI tasks → multiplexed responses → GOAWAY", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_h2_handler/", "kind": "autodoc-python", "objectID": "/api/_h2_handler/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_h2_handler.py", "title": "_h2_handler", "type": "autodoc-python", "uri": "/api/_h2_handler/", "url": "/pounce/api/_h2_handler/", "word_count": 0}, {"description": "HTTP/3 connection handler — manages QUIC/UDP streams via zoomies.\n\nHTTP/3 uses QUIC (UDP) transport. Zoomies is sans-I/O: pounce owns the\nUDP loop and maintains a connection map. Each QUIC connection has an\nH3Connection; each HTTP/3 stream maps to one ASGI invocation.\n\nRequires the ``h3`` optional dependency (``pip install bengal-pounce[h3]``).", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_h3_handler/", "kind": "autodoc-python", "objectID": "/api/_h3_handler/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_h3_handler.py", "title": "_h3_handler", "type": "autodoc-python", "uri": "/api/_h3_handler/", "url": "/pounce/api/_h3_handler/", "word_count": 0}, {"description": "Shared header lookup utilities.\n\nSingle-pass header extraction for ASGI headers (list or tuple of\n(name, value) byte pairs). Consolidates the 7 copies of _get_header\nscattered across worker, sync_worker, async_pool, and handler modules.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_headers/", "kind": "autodoc-python", "objectID": "/api/_headers/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_headers.py", "title": "_headers", "type": "autodoc-python", "uri": "/api/_headers/", "url": "/pounce/api/_headers/", "word_count": 0}, {"description": "Built-in health check endpoint.\n\nResponds to GET requests at the configured ``health_check_path`` before\nthe request reaches the ASGI application.  Returns a JSON payload with\nserver status, uptime, active connections, and worker identity.\n\nSkips access logging by default (health checks are noisy in production).", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_health/", "kind": "autodoc-python", "objectID": "/api/_health/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_health.py", "title": "_health", "type": "autodoc-python", "uri": "/api/_health/", "url": "/pounce/api/_health/", "word_count": 0}, {"description": "Hot reload without connection drops for pounce.\n\nImplements zero-downtime code reloads by gracefully replacing workers\nwithout dropping active connections.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_hot_reload/", "kind": "autodoc-python", "objectID": "/api/_hot_reload/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_hot_reload.py", "title": "_hot_reload", "type": "autodoc-python", "uri": "/api/_hot_reload/", "url": "/pounce/api/_hot_reload/", "word_count": 0}, {"description": "Application importer — resolves string references to ASGI callables.\n\nHandles the standard \"module:attribute\" pattern used by ASGI servers:\n\n    \"myapp:app\"              → import myapp; return myapp.app\n    \"myapp.web:app\"          → import myapp.web; return myapp.web.app\n    \"myapp:create_app()\"     → import myapp; return myapp.create_app()\n\nFor development mode, `reimport_app`() clears project-local modules\nfrom ``sys.modules`` before re-importing, so that code changes on disk\nare picked up without a full process restart.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_importer/", "kind": "autodoc-python", "objectID": "/api/_importer/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_importer.py", "title": "_importer", "type": "autodoc-python", "uri": "/api/_importer/", "url": "/pounce/api/_importer/", "word_count": 0}, {"description": "``pounce init`` — scaffold a minimal pounce project in the current directory.\n\nDrops three files and refuses to overwrite without ``--force``:\n\n- ``app.py`` — vanilla ASGI \"hello from pounce\" (no framework)\n- ``pounce.toml`` — commented template of every ``ServerConfig`` default,\n  generated via `build_toml_template`()\n- ``.gitignore`` — the three lines every Python project needs\n\nSee ``docs/design/init-scope.md`` for why this is vanilla-only.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_init/", "kind": "autodoc-python", "objectID": "/api/_init/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_init.py", "title": "_init", "type": "autodoc-python", "uri": "/api/_init/", "url": "/pounce/api/_init/", "word_count": 0}, {"description": "Built-in ``/_pounce/info`` introspection endpoint (Sprint 5).\n\nDisabled by default. When ``ServerConfig.introspection_enabled`` is True,\nthe worker dispatches GET requests at ``introspection_path`` to\n`build_introspect_response`() before the request reaches the ASGI\napplication.\n\nThe response body is a JSON object with three sections:\n\n- **runtime**: Python version, GIL state, worker mode, server uptime.\n- **worker**: per-worker identity (``worker_id``) and live counters\n  (``active_connections``).\n- **config**: the `redacted_config_view`() of\n  the active `ServerConfig` — fail-closed via\n  ``INFO_ALLOWLIST``.\n\nSee ``docs/troubleshooting.md#POUNCE_CONFIG_INTROSPECTION_PUBLIC`` for the\nwarning emitted when the endpoint is bound non-loopback.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_introspect/", "kind": "autodoc-python", "objectID": "/api/_introspect/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_introspect.py", "title": "_introspect", "type": "autodoc-python", "uri": "/api/_introspect/", "url": "/pounce/api/_introspect/", "word_count": 0}, {"description": "Built-in /metrics endpoint for Prometheus scraping.\n\nProvides a lightweight ASGI app that serves metrics from a PrometheusCollector\nat a configurable path (default: /metrics).", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_metrics_handler/", "kind": "autodoc-python", "objectID": "/api/_metrics_handler/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_metrics_handler.py", "title": "_metrics_handler", "type": "autodoc-python", "uri": "/api/_metrics_handler/", "url": "/pounce/api/_metrics_handler/", "word_count": 0}, {"description": "Middleware extension system for server-level request/response processing.\n\nProvides hooks for pre-request, post-response, and exception handling without\nmodifying the ASGI bridge or requiring apps to wrap themselves in middleware.\n\nExample:\n    async def auth_middleware(scope):\n        '''Pre-request hook that can short-circuit.'''\n        headers = dict(scope[\"headers\"])\n        if not headers.get(b\"authorization\"):\n            return Response(status=401, body=b\"Unauthorized\")\n        return scope  # Continue to app\n\n    async def cors_middleware(scope, status, headers):\n        '''Post-response hook that modifies headers.'''\n        headers.append((b\"access-control-allow-origin\", b\"*\"))\n        return (status, headers)\n\n    config = ServerConfig(middleware=[auth_middleware, cors_middleware])", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_middleware/", "kind": "autodoc-python", "objectID": "/api/_middleware/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_middleware.py", "title": "_middleware", "type": "autodoc-python", "uri": "/api/_middleware/", "url": "/pounce/api/_middleware/", "word_count": 0}, {"description": "OpenTelemetry integration for distributed tracing.\n\nProvides automatic span creation for HTTP requests and inbound W3C Trace\nContext extraction, enabling pounce to integrate with observability\nplatforms like Jaeger, Datadog, Tempo, and others.\n\nFeatures:\n- Automatic span creation for each HTTP request\n- Inbound W3C Trace Context extraction (traceparent/tracestate parsed\n  from request headers so server spans join an upstream trace).  Pounce\n  is a server, not an outbound HTTP client, so it does not inject trace\n  context into downstream requests.\n- OTLP exporter configuration\n- Request/response attributes (method, path, status, duration)\n- Optional integration (graceful degradation if OTel not installed)\n- Zero overhead when disabled\n\nUsage:\n    config = ServerConfig(\n        otel_endpoint=\"http://localhost:4318\",  # OTLP HTTP endpoint\n        otel_service_name=\"my-service\",\n    )\n\nSecurity:\n- Only enabled when otel_endpoint is configured\n- Never samples sensitive data (passwords, tokens)\n- Respects standard OTel environment variables", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_otel/", "kind": "autodoc-python", "objectID": "/api/_otel/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_otel.py", "title": "_otel", "type": "autodoc-python", "uri": "/api/_otel/", "url": "/pounce/api/_otel/", "word_count": 0}, {"description": "Kida template infrastructure and one-shot branded output.\n\nProvides the shared template environment, thread-safe stderr writer, and\nbranded renders for CLI commands (error, info, check, traceback) and access\nlogs.  Server lifecycle output (banner, ready, shutdown, reload, worker\nevents) is handled by the dispatch-driven view layer in ``_state.py``.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_output/", "kind": "autodoc-python", "objectID": "/api/_output/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_output.py", "title": "_output", "type": "autodoc-python", "uri": "/api/_output/", "url": "/pounce/api/_output/", "word_count": 0}, {"description": "HTTP Priority Signals (RFC 9218).\n\nParses the ``Priority`` header (``u=N, i``) from HTTP/2 requests and\nprovides a priority-based scheduler for DATA frame writes.\n\nRFC 9218 defines:\n- ``u=N`` (urgency): 0-7, default 3. Lower is more urgent.\n- ``i`` (incremental): boolean. If present, response can be interleaved.\n\nScheduling policy (§8):\n- Streams at lower urgency numbers are served before higher ones.\n- At the same urgency, non-incremental streams are served one at a\n  time (sticky): the first-ready stream holds the slot until it is\n  unscheduled or removed.\n- At the same urgency, incremental streams round-robin via\n  `mark_wrote`() after each chunk.\n- Non-incremental streams at a given urgency preempt incremental\n  streams at that urgency, since non-incremental responses expect\n  serial delivery.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_priority/", "kind": "autodoc-python", "objectID": "/api/_priority/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_priority.py", "title": "_priority", "type": "autodoc-python", "uri": "/api/_priority/", "url": "/pounce/api/_priority/", "word_count": 0}, {"description": "Request profiling — enabled via POUNCE_PROFILE=1.\n\nSamples every Nth request and logs read/parse/app/drain timings to stderr\nfor bottleneck analysis. See docs/benchmark-pounce-chirp-deep-dive.md.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_profile/", "kind": "autodoc-python", "objectID": "/api/_profile/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_profile.py", "title": "_profile", "type": "autodoc-python", "uri": "/api/_profile/", "url": "/pounce/api/_profile/", "word_count": 0}, {"description": "Proxy header validation — extract real client info from trusted reverse proxies.\n\nWhen ``trusted_hosts`` is configured, X-Forwarded-For/Proto/Host headers are\nhonoured **only** if the direct peer IP is in the trusted set.  When no trusted\nhosts are configured, forwarded headers are stripped to prevent spoofing.\n\nRFC 7239 defines a formal ``Forwarded`` header, but the ``X-Forwarded-*``\nfamily remains the de-facto standard used by nginx, Caddy, AWS ALB, Cloudflare,\nand virtually every reverse proxy in production.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_proxy/", "kind": "autodoc-python", "objectID": "/api/_proxy/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_proxy.py", "title": "_proxy", "type": "autodoc-python", "uri": "/api/_proxy/", "url": "/pounce/api/_proxy/", "word_count": 0}, {"description": "Rate limiting and backpressure for pounce.\n\nImplements token bucket rate limiting per client IP with request queuing\nand load shedding for production overload protection.\n\nPer-worker semantics (issue #109): each worker holds its own token buckets.\nIn thread mode (3.14t) one limiter is genuinely shared, but in process mode\n(GIL build, fork) and subinterpreter mode every worker inherits an independent\ncopy of the bucket state with no IPC between them. The real per-IP ceiling is\ntherefore ``rate x workers`` (burst ``burst x workers``). The configured number\nis the aggregate guarantee only when ``workers=1``. See\n``docs/deployment/backpressure.md``.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_rate_limiter/", "kind": "autodoc-python", "objectID": "/api/_rate_limiter/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_rate_limiter.py", "title": "_rate_limiter", "type": "autodoc-python", "uri": "/api/_rate_limiter/", "url": "/pounce/api/_rate_limiter/", "word_count": 0}, {"description": "File watcher for development mode (``--reload``).\n\nPolls the application's source directory for changes and signals the\nsupervisor to restart workers when modifications are detected.\n\nUses stdlib ``pathlib`` + polling. Ignores ``__pycache__``, ``.git``,\n``node_modules``, and common virtual environment directories.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_reload/", "kind": "autodoc-python", "objectID": "/api/_reload/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_reload.py", "title": "_reload", "type": "autodoc-python", "uri": "/api/_reload/", "url": "/pounce/api/_reload/", "word_count": 0}, {"description": "Request ID generation and propagation.\n\nEach request gets a unique ID for tracing across logs and services.\nIf a trusted proxy sends X-Request-ID, we honour it.  Otherwise, we\ngenerate a new one.  The ID is injected into:\n\n- The ASGI scope extensions (``scope[\"extensions\"][\"request_id\"]``)\n- The response headers (``X-Request-ID``)\n\nUses UUID4 for uniqueness without coordination between workers.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_request_id/", "kind": "autodoc-python", "objectID": "/api/_request_id/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_request_id.py", "title": "_request_id", "type": "autodoc-python", "uri": "/api/_request_id/", "url": "/pounce/api/_request_id/", "word_count": 0}, {"description": "Shared request pipeline — functions used by both Worker and SyncWorker.\n\nEliminates duplication across the two worker types and ensures feature\nparity (access log filter, duration tracking, request ID propagation).", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_request_pipeline/", "kind": "autodoc-python", "objectID": "/api/_request_pipeline/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_request_pipeline.py", "title": "_request_pipeline", "type": "autodoc-python", "uri": "/api/_request_pipeline/", "url": "/pounce/api/_request_pipeline/", "word_count": 0}, {"description": "Request queuing and load shedding for pounce.\n\nImplements application-level request queueing with bounded capacity\nto gracefully handle server overload.\n\nPer-worker in ALL modes (issue #109): the queue is built on an\n``asyncio.Semaphore`` bound to a single event loop, so every worker -- thread,\nprocess, or subinterpreter -- gets its own queue. The effective load-shed depth\nis therefore ``max_depth x workers``, always. The configured ``max_depth`` is\nthe aggregate only when ``workers=1``. See ``docs/deployment/backpressure.md``.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_request_queue/", "kind": "autodoc-python", "objectID": "/api/_request_queue/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_request_queue.py", "title": "_request_queue", "type": "autodoc-python", "uri": "/api/_request_queue/", "url": "/pounce/api/_request_queue/", "word_count": 0}, {"description": "Pre-built HTTP response framing for the fused sync path.\n\nBypasses H1Protocol/h11 for the hot path — serializes response directly\nto avoid protocol state machine overhead. Date header cached per-second\n(RFC 7231 allows 1s resolution).", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_response_frame/", "kind": "autodoc-python", "objectID": "/api/_response_frame/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_response_frame.py", "title": "_response_frame", "type": "autodoc-python", "uri": "/api/_response_frame/", "url": "/pounce/api/_response_frame/", "word_count": 0}, {"description": "Runtime detection utilities.\n\nDetects GIL state and determines the appropriate worker mode for the\ncurrent Python interpreter. Used by the supervisor to decide between\nthread-based (nogil) and process-based (GIL) worker spawning.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_runtime/", "kind": "autodoc-python", "objectID": "/api/_runtime/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_runtime.py", "title": "_runtime", "type": "autodoc-python", "uri": "/api/_runtime/", "url": "/pounce/api/_runtime/", "word_count": 0}, {"description": "Zero-copy sendfile support for static file serving.\n\nProvides an async callable that uses ``loop.sendfile()`` to transfer file\ndata directly from the filesystem to a socket, bypassing Python memory.\n\nConstraints:\n- Only works on non-TLS connections (SSL wraps the socket, preventing sendfile)\n- Unix-like systems only (Linux, macOS, FreeBSD)\n- Falls back gracefully when unavailable\n\nBack-pressure: asyncio sets transport sockets non-blocking, so a raw\n``os.sendfile`` loop raises ``BlockingIOError`` (EAGAIN) the moment the\nkernel send buffer fills — a normal flow-control signal that crashes a\nhand-rolled loop.  ``loop.sendfile(transport, ...)`` is the transport-aware\nprimitive: it detaches the live transport from the selector, runs native\nsendfile with proper EAGAIN / ``add_writer`` retry handling, then restores\nthe transport.  See https://github.com/lbliii/pounce/issues/72.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_sendfile/", "kind": "autodoc-python", "objectID": "/api/_sendfile/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_sendfile.py", "title": "_sendfile", "type": "autodoc-python", "uri": "/api/_sendfile/", "url": "/pounce/api/_sendfile/", "word_count": 0}, {"description": "Sentry error tracking integration for pounce.\n\nOptional integration with Sentry SDK for automatic error reporting,\nperformance monitoring, and request context capture.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_sentry/", "kind": "autodoc-python", "objectID": "/api/_sentry/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_sentry.py", "title": "_sentry", "type": "autodoc-python", "uri": "/api/_sentry/", "url": "/pounce/api/_sentry/", "word_count": 0}, {"description": "Server lifecycle state machine — Elm Architecture via milo.\n\nCentralizes the server lifecycle (init → startup → ready → serving →\nreloading → shutting_down → stopped) into an immutable state model with a\npure reducer.  A render middleware produces branded output on each dispatch,\nreplacing the procedural ``if _is_pretty(): _write(_render(...))`` pattern\nwith a single dispatch-driven view layer.\n\nUsage from server.py / supervisor.py::\n\n    from pounce._state import dispatch\n\n    dispatch(\"BANNER\", config=config, effective_workers=4, ...)\n    dispatch(\"READY\", host=\"127.0.0.1\", port=8000)\n    dispatch(\"SHUTDOWN_COMPLETE\")", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_state/", "kind": "autodoc-python", "objectID": "/api/_state/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_state.py", "title": "_state", "type": "autodoc-python", "uri": "/api/_state/", "url": "/pounce/api/_state/", "word_count": 0}, {"description": "Static file serving with modern optimizations.\n\nDesigned for Bengal SSG output and Chirp static assets. Supports:\n- Protocol-owned zero-copy sendfile for supported HTTP/1 connections\n- ETag generation from mtime + size\n- 304 Not Modified responses\n- Range requests (Accept-Ranges, Content-Range, 206)\n- Precompressed file serving (.gz, .zst variants)\n- MIME type detection\n- Security: path traversal prevention, hidden file blocking\n\nExample:\n    config = ServerConfig(static_files={\"/static\": \"./public\"})\n    # Requests to /static/* will be served from ./public/", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_static/", "kind": "autodoc-python", "objectID": "/api/_static/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_static.py", "title": "_static", "type": "autodoc-python", "uri": "/api/_static/", "url": "/pounce/api/_static/", "word_count": 0}, {"description": "Subinterpreter worker bootstrap.\n\nThis module provides `bootstrap`(), the entry point executed inside\neach subinterpreter worker.  The supervisor injects IIC-safe values via\n``interp.prepare_main()`` and then runs::\n\n    from pounce._subinterpreter_bootstrap import bootstrap\n    bootstrap(ctrl_queue, status_queue, config_json,\n              app_import_path, sock_fd, worker_id, parent_sys_path)\n\nDesign\n------\nRather than duplicating Worker internals, the bootstrap:\n\n1. Reconstructs ``ServerConfig`` from JSON\n2. Imports the ASGI app by module path\n3. Reconstructs the socket from a dup'd file descriptor\n4. Creates a standard ``Worker`` with ``shutdown_event=None``\n5. Monkey-patches ``Worker._serve`` to inject an IIC shutdown bridge\n   that polls ``ctrl_queue`` and sets ``_async_shutdown`` when commanded\n\nThis keeps Worker as the single source of truth for request handling.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_subinterpreter_bootstrap/", "kind": "autodoc-python", "objectID": "/api/_subinterpreter_bootstrap/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_subinterpreter_bootstrap.py", "title": "_subinterpreter_bootstrap", "type": "autodoc-python", "uri": "/api/_subinterpreter_bootstrap/", "url": "/pounce/api/_subinterpreter_bootstrap/", "word_count": 0}, {"description": "Timing utilities and Server-Timing header builder.\n\nProvides monotonic clock helpers for request-level timing and a builder\nfor the Server-Timing HTTP header (RFC 6797 extension).\n\nAll functions use time.monotonic_ns() for high-resolution, monotonic timing\nthat is not affected by system clock adjustments.\n\nExample:\n    >>> start = monotonic_ns()\n    >>> # ... do work ...\n    >>> dur = elapsed_ms(start)\n    >>> header = ServerTiming()\n    >>> header.add(\"app\", dur)\n    >>> header.render()\n    'app;dur=12.3'", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_timing/", "kind": "autodoc-python", "objectID": "/api/_timing/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_timing.py", "title": "_timing", "type": "autodoc-python", "uri": "/api/_timing/", "url": "/pounce/api/_timing/", "word_count": 0}, {"description": "ASGI type definitions for pounce.\n\nTyped definitions for the ASGI 3.0 protocol. These replace the raw dicts and\ncallables from the ASGI spec with concrete types for internal use.\n\nExternal ASGI apps still use the standard untyped protocol — pounce translates\nat the boundary.\n\nSee Also:\n- https://asgi.readthedocs.io/en/latest/specs/main.html\n- chirp/_internal/asgi.py (same pattern for the framework side)", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_types/", "kind": "autodoc-python", "objectID": "/api/_types/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_types.py", "title": "_types", "type": "autodoc-python", "uri": "/api/_types/", "url": "/pounce/api/_types/", "word_count": 0}, {"description": "WebSocket connection handler — HTTP/1.1 upgrade lifecycle.\n\nExtracted from ``worker.py`` to keep protocol-specific connection handling\nseparate from the core Worker lifecycle.  The worker delegates to\n``handle_websocket()`` when it detects an HTTP/1.1 WebSocket upgrade.\n\nConnection flow:\n    H1 request → detect ``Connection: Upgrade`` + ``Upgrade: websocket``\n    → build ASGI ``websocket`` scope → 101 Switching Protocols\n    → wsproto frame loop → app(scope, receive, send)", "dir": "/api/", "excerpt": "", "href": "/pounce/api/_ws_handler/", "kind": "autodoc-python", "objectID": "/api/_ws_handler/", "reading_time": 1, "section": "api", "source_file": "src/pounce/_ws_handler.py", "title": "_ws_handler", "type": "autodoc-python", "uri": "/api/_ws_handler/", "url": "/pounce/api/_ws_handler/", "word_count": 0}, {"description": "AcceptDistributor — single-thread accept feeding a shared worker queue.\n\nEliminates thundering herd on macOS/Windows where SO_REUSEPORT is\nunavailable. One thread accepts connections and enqueues them into a\nsingle shared queue from which all SyncWorkers pull.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/accept_distributor/", "kind": "autodoc-python", "objectID": "/api/accept_distributor/", "reading_time": 1, "section": "api", "source_file": "src/pounce/accept_distributor.py", "title": "accept_distributor", "type": "autodoc-python", "uri": "/api/accept_distributor/", "url": "/pounce/api/accept_distributor/", "word_count": 0}, {"description": "ASGI protocol bridge.\n\nTranslates between pounce's internal connection handling and the ASGI 3.0\nprotocol that applications expect (scope, receive, send).\n\nModules:\n- bridge: Constructs ASGI scope/receive/send for HTTP requests\n- ws_bridge: Constructs ASGI scope/receive/send for WebSocket connections\n- lifespan: ASGI lifespan protocol (startup/shutdown events)", "dir": "/api/", "excerpt": "", "href": "/pounce/api/asgi/", "kind": "autodoc-python", "objectID": "/api/asgi/", "reading_time": 1, "section": "asgi", "source_file": "src/pounce/asgi/__init__.py", "title": "asgi", "type": "autodoc-python", "uri": "/api/asgi/", "url": "/pounce/api/asgi/", "word_count": 0}, {"description": "Shared scope-building logic for HTTP and WebSocket ASGI bridges.\n\nExtracts the common target parsing, path decoding, and header\nconversion used by all three bridges (HTTP/1.1, HTTP/2, WebSocket).", "dir": "/api/asgi/", "excerpt": "", "href": "/pounce/api/asgi/_scope/", "kind": "autodoc-python", "objectID": "/api/asgi/_scope/", "reading_time": 1, "section": "asgi", "source_file": "src/pounce/asgi/_scope.py", "title": "_scope", "type": "autodoc-python", "uri": "/api/asgi/_scope/", "url": "/pounce/api/asgi/_scope/", "word_count": 0}, {"description": "ASGI bridge — translates between protocol events and the ASGI interface.\n\nBuilds ASGI scope dicts from protocol events, and creates the async\nreceive/send callables that ASGI apps interact with.\n\nStreaming-first: send() writes response chunks immediately to the\ntransport. No buffering — each http.response.body message is compressed\n(if applicable) and flushed to the wire before the next one.\n\nPhase 4 hot-path optimizations:\n- Pre-encoded ASGI spec constants (avoid per-request dict allocation)\n- Bodyless fast-path receive (skip asyncio.Queue for GET/HEAD)\n- Single write call for head+body when small\n- Reduced isinstance checks", "dir": "/api/asgi/", "excerpt": "", "href": "/pounce/api/asgi/bridge/", "kind": "autodoc-python", "objectID": "/api/asgi/bridge/", "reading_time": 1, "section": "asgi", "source_file": "src/pounce/asgi/bridge.py", "title": "bridge", "type": "autodoc-python", "uri": "/api/asgi/bridge/", "url": "/pounce/api/asgi/bridge/", "word_count": 0}, {"description": "HTTP/2 ASGI bridge — maps H2Connection streams to ASGI scope/receive/send.\n\nEach HTTP/2 stream maps to one ASGI invocation, just like one HTTP/1.1\nrequest maps to one ASGI invocation. The difference is that multiple\nstreams can run concurrently on the same TCP connection.\n\nThe worker creates one ``H2StreamBridge`` per stream, which builds the\nscope and creates receive/send callables. The send callable serializes\nvia the shared ``H2Connection`` (which is single-threaded within the\nworker's event loop — no lock needed).", "dir": "/api/asgi/", "excerpt": "", "href": "/pounce/api/asgi/h2_bridge/", "kind": "autodoc-python", "objectID": "/api/asgi/h2_bridge/", "reading_time": 1, "section": "asgi", "source_file": "src/pounce/asgi/h2_bridge.py", "title": "h2_bridge", "type": "autodoc-python", "uri": "/api/asgi/h2_bridge/", "url": "/pounce/api/asgi/h2_bridge/", "word_count": 0}, {"description": "HTTP/3 ASGI bridge — maps zoomies H3 events to ASGI scope/receive/send.\n\nEach HTTP/3 stream maps to one ASGI invocation, similar to HTTP/2.\nHTTP/3 uses QUIC (UDP) transport with TLS 1.3 built-in.", "dir": "/api/asgi/", "excerpt": "", "href": "/pounce/api/asgi/h3_bridge/", "kind": "autodoc-python", "objectID": "/api/asgi/h3_bridge/", "reading_time": 1, "section": "asgi", "source_file": "src/pounce/asgi/h3_bridge.py", "title": "h3_bridge", "type": "autodoc-python", "uri": "/api/asgi/h3_bridge/", "url": "/pounce/api/asgi/h3_bridge/", "word_count": 0}, {"description": "ASGI lifespan handler.\n\nManages the ASGI lifespan protocol — sends startup/shutdown events to the\napplication and waits for completion. Used as an async context manager so\nthe server can bracket its run loop with lifespan events.\n\nHandles apps that don't support lifespan — whether they raise an\nexception or silently return for non-HTTP scopes.", "dir": "/api/asgi/", "excerpt": "", "href": "/pounce/api/asgi/lifespan/", "kind": "autodoc-python", "objectID": "/api/asgi/lifespan/", "reading_time": 1, "section": "asgi", "source_file": "src/pounce/asgi/lifespan.py", "title": "lifespan", "type": "autodoc-python", "uri": "/api/asgi/lifespan/", "url": "/pounce/api/asgi/lifespan/", "word_count": 0}, {"description": "Sync ASGI bridge — run ASGI apps from a synchronous context.\n\nFor simple request-response (no streaming receive, no streaming send),\ncollects the response in memory and returns it as a SyncResponse.\n\nIf the app sends more_body=True (streaming) or the scope type is\nwebsocket, raises NeedsAsyncError so the caller can hand off to the async pool.", "dir": "/api/asgi/", "excerpt": "", "href": "/pounce/api/asgi/sync_bridge/", "kind": "autodoc-python", "objectID": "/api/asgi/sync_bridge/", "reading_time": 1, "section": "asgi", "source_file": "src/pounce/asgi/sync_bridge.py", "title": "sync_bridge", "type": "autodoc-python", "uri": "/api/asgi/sync_bridge/", "url": "/pounce/api/asgi/sync_bridge/", "word_count": 0}, {"description": "WebSocket ASGI bridge — translates between WSProtocol events and ASGI.\n\nBuilds ASGI ``websocket`` scope dicts and creates the async receive/send\ncallables for WebSocket ASGI apps.\n\nASGI WebSocket lifecycle:\n    1. App receives ``websocket.connect``\n    2. App sends ``websocket.accept`` (or ``websocket.close`` to reject)\n    3. App receives ``websocket.receive`` messages\n    4. App sends ``websocket.send`` messages\n    5. Either side sends ``websocket.close`` / receives ``websocket.disconnect``", "dir": "/api/asgi/", "excerpt": "", "href": "/pounce/api/asgi/ws_bridge/", "kind": "autodoc-python", "objectID": "/api/asgi/ws_bridge/", "reading_time": 1, "section": "asgi", "source_file": "src/pounce/asgi/ws_bridge.py", "title": "ws_bridge", "type": "autodoc-python", "uri": "/api/asgi/ws_bridge/", "url": "/pounce/api/asgi/ws_bridge/", "word_count": 0}, {"description": "AsyncPool — dedicated event loop for streaming and WebSocket connections.\n\nReceives handoffs from SyncWorkers when the ASGI app returns a streaming\nresponse (more_body=True) or WebSocket upgrade. Wraps the socket in asyncio\nstreams and continues the ASGI lifecycle.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/async_pool/", "kind": "autodoc-python", "objectID": "/api/async_pool/", "reading_time": 1, "section": "api", "source_file": "src/pounce/async_pool.py", "title": "async_pool", "type": "autodoc-python", "uri": "/api/async_pool/", "url": "/pounce/api/async_pool/", "word_count": 0}, {"description": "Server configuration.\n\nServerConfig is the single configuration object for a pounce server instance.\nFrozen after creation — the server reads config but never mutates it.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/config/", "kind": "autodoc-python", "objectID": "/api/config/", "reading_time": 1, "section": "api", "source_file": "src/pounce/config.py", "title": "config", "type": "autodoc-python", "uri": "/api/config/", "url": "/pounce/api/config/", "word_count": 0}, {"description": "Application display identity for Pounce startup output.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/display/", "kind": "autodoc-python", "objectID": "/api/display/", "reading_time": 1, "section": "api", "source_file": "src/pounce/display.py", "title": "display", "type": "autodoc-python", "uri": "/api/display/", "url": "/pounce/api/display/", "word_count": 0}, {"description": "HTTP/3 worker — runs QUIC/UDP datagram endpoint for HTTP/3.\n\nUses asyncio.create_datagram_endpoint with a pre-bound UDP socket.\nShares app, config, lifecycle with the TCP Worker model but serves\nHTTP/3 over QUIC instead of HTTP/1.1 and HTTP/2 over TCP.\n\nRequires the ``h3`` optional dependency (``pip install bengal-pounce[h3]``).", "dir": "/api/", "excerpt": "", "href": "/pounce/api/h3_worker/", "kind": "autodoc-python", "objectID": "/api/h3_worker/", "reading_time": 1, "section": "api", "source_file": "src/pounce/h3_worker.py", "title": "h3_worker", "type": "autodoc-python", "uri": "/api/h3_worker/", "url": "/pounce/api/h3_worker/", "word_count": 0}, {"description": "Connection lifecycle events — structured, immutable records.\n\nEach event captures a moment in a connection's lifecycle as a frozen\ndataclass.  Events are designed for aggregation, replay, and\nobservability — not logging.  They form the foundation of the\nfull-stack effect observability system.\n\nEvents are produced by the worker and consumed by an optional\n``LifecycleCollector``.  The default collector (``NoopCollector``)\ndiscards all events with zero overhead.  Replace it with a\n``BufferedCollector`` or custom implementation to capture events.\n\nAll timestamps use ``time.monotonic_ns()`` for high-resolution,\nmonotonic ordering that is not affected by system clock adjustments.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/lifecycle/", "kind": "autodoc-python", "objectID": "/api/lifecycle/", "reading_time": 1, "section": "api", "source_file": "src/pounce/lifecycle.py", "title": "lifecycle", "type": "autodoc-python", "uri": "/api/lifecycle/", "url": "/pounce/api/lifecycle/", "word_count": 0}, {"description": "Logging configuration and access log formatting.\n\nConfigures stdlib logging with pounce-specific formatting. Provides text,\nJSON, and pretty (TTY) access log output for request/response metrics.\n\nFormat modes:\n    auto   — pretty on TTY, JSON when piped (default)\n    text   — classic combined-log format via stdlib logging\n    json   — flat structured JSON written directly to stderr\n    pretty — colored compact lines on TTY (resolved from auto)", "dir": "/api/", "excerpt": "", "href": "/pounce/api/logging/", "kind": "autodoc-python", "objectID": "/api/logging/", "reading_time": 1, "section": "api", "source_file": "src/pounce/logging.py", "title": "logging", "type": "autodoc-python", "uri": "/api/logging/", "url": "/pounce/api/logging/", "word_count": 0}, {"description": "Prometheus-compatible metrics collector.\n\nImplements the ``LifecycleCollector`` protocol to track standard HTTP\nserver metrics from lifecycle events.  No external dependencies — uses\ninternal counters that can be exported in Prometheus text format.\n\nMetrics:\n    - ``http_requests_total`` — counter by method and status\n    - ``http_request_duration_seconds`` — histogram of request durations\n    - ``http_connections_active`` — gauge of open connections\n    - ``http_requests_in_flight`` — gauge of in-progress requests\n\nLabel stability contract (``http_requests_total``):\n    - ``method`` — the uppercase HTTP request method as parsed (e.g.\n      ``\"GET\"``, ``\"POST\"``).  On error/early-out paths where the method\n      was never parsed, the stable sentinel ``\"unknown\"`` is used.  The\n      empty string is never emitted.\n    - ``status`` — the numeric HTTP status code rendered as a string.\n\nThread-safe: all counters use ``threading.Lock`` for free-threading mode.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/metrics/", "kind": "autodoc-python", "objectID": "/api/metrics/", "reading_time": 1, "section": "api", "source_file": "src/pounce/metrics.py", "title": "metrics", "type": "autodoc-python", "uri": "/api/metrics/", "url": "/pounce/api/metrics/", "word_count": 0}, {"description": "Network layer — socket binding, listening, and TLS.\n\nHandles the lowest level of the server: binding to addresses, accepting\nconnections, and optionally terminating TLS.\n\nModules:\n- listener: Socket bind, SO_REUSEPORT, accept loop\n- tls: TLS context creation and ALPN negotiation", "dir": "/api/", "excerpt": "", "href": "/pounce/api/net/", "kind": "autodoc-python", "objectID": "/api/net/", "reading_time": 1, "section": "net", "source_file": "src/pounce/net/__init__.py", "title": "net", "type": "autodoc-python", "uri": "/api/net/", "url": "/pounce/api/net/", "word_count": 0}, {"description": "Network listener — creates and configures server sockets.\n\nBinds to the configured address, sets socket options (SO_REUSEADDR,\nSO_REUSEPORT if available), and returns ready-to-accept sockets.\n\nPhase 2 multi-worker strategy:\n- SO_REUSEPORT available (Linux): each worker gets its own independently\n  bound socket — the kernel distributes connections across them.\n- SO_REUSEPORT unavailable (macOS, Windows): one socket is created and\n  shared by all workers — all workers accept from the same fd.\n\nThe worker receives a socket and does not know which strategy was used.", "dir": "/api/net/", "excerpt": "", "href": "/pounce/api/net/listener/", "kind": "autodoc-python", "objectID": "/api/net/listener/", "reading_time": 1, "section": "net", "source_file": "src/pounce/net/listener.py", "title": "listener", "type": "autodoc-python", "uri": "/api/net/listener/", "url": "/pounce/api/net/listener/", "word_count": 0}, {"description": "TLS context creation for pounce.\n\nCreates and configures ``ssl.SSLContext`` from ``ServerConfig`` fields.\nUses stdlib ``ssl`` with secure defaults (TLSv1.2+, no compression,\ncipher order honoured).  Optionally uses ``truststore`` (via\n``bengal-pounce[tls]``) for system certificate store integration.\n\nALPN protocols are advertised so HTTP/2 negotiation works when the h2\nprotocol handler is available.", "dir": "/api/net/", "excerpt": "", "href": "/pounce/api/net/tls/", "kind": "autodoc-python", "objectID": "/api/net/tls/", "reading_time": 1, "section": "net", "source_file": "src/pounce/net/tls.py", "title": "tls", "type": "autodoc-python", "uri": "/api/net/tls/", "url": "/pounce/api/net/tls/", "word_count": 0}, {"description": "Pounce — A free-threading-native ASGI server for Python 3.14t.\n\nPounce is a pure-Python ASGI server designed from scratch for Python's free-threading\nmode (PEP 703). Instead of the traditional fork-based worker model, pounce runs N worker\nthreads sharing a single interpreter — leveraging nogil for true parallelism without the\nmemory overhead of multi-process deployments.\n\nQuick start:\n\n    import pounce\n\n    pounce.run(\"myapp:app\", host=\"0.0.0.0\", port=8000)\n\nOr from the command line:\n\n    pounce myapp:app --workers 4\n\nPart of the Bengal ecosystem:\n\n    pounce      ASGI server       (serves apps)\n    chirp       Web framework     (serves HTML)\n    kida        Template engine   (renders HTML)\n    patitas     Markdown parser   (parses content)\n    rosettes    Syntax highlighter (highlights code)\n    bengal      Static site gen   (builds sites)", "dir": "/api/", "excerpt": "", "href": "/pounce/api/pounce/", "kind": "autodoc-python", "objectID": "/api/pounce/", "reading_time": 1, "section": "api", "source_file": "src/pounce/__init__.py", "title": "pounce", "type": "autodoc-python", "uri": "/api/pounce/", "url": "/pounce/api/pounce/", "word_count": 0}, {"description": "Protocol handlers for HTTP/1.1, HTTP/2, and WebSocket.\n\nEach protocol module translates between raw bytes on the wire and typed\nprotocol events. Protocol handlers are sans-I/O — they accept bytes and\nreturn bytes, never touching sockets or asyncio directly.\n\nModules:\n- _base: Event types and ProtocolHandler contract\n- h1: HTTP/1.1 via h11 (phase 1)\n- h2: HTTP/2 via h2 library (phase 3)\n- ws: WebSocket via wsproto (phase 3)", "dir": "/api/", "excerpt": "", "href": "/pounce/api/protocols/", "kind": "autodoc-python", "objectID": "/api/protocols/", "reading_time": 1, "section": "protocols", "source_file": "src/pounce/protocols/__init__.py", "title": "protocols", "type": "autodoc-python", "uri": "/api/protocols/", "url": "/pounce/api/protocols/", "word_count": 0}, {"description": "Protocol contracts — event types and handler interface.\n\nDefines the structural interface that all protocol handlers (H1, H2, WS) must\nconform to, and the typed events they produce. The worker layer interacts with\nany protocol handler through this interface without knowing which wire protocol\nis active.\n\nSans-I/O: protocol handlers consume bytes and produce bytes. No socket access,\nno asyncio imports. The worker feeds data in and reads data out.", "dir": "/api/protocols/", "excerpt": "", "href": "/pounce/api/protocols/_base/", "kind": "autodoc-python", "objectID": "/api/protocols/_base/", "reading_time": 1, "section": "protocols", "source_file": "src/pounce/protocols/_base.py", "title": "_base", "type": "autodoc-python", "uri": "/api/protocols/_base/", "url": "/pounce/api/protocols/_base/", "word_count": 0}, {"description": "HTTP/1.1 protocol handler — sans-I/O wrapper around h11.\n\nTranslates between raw bytes and typed ProtocolEvents. The worker feeds\nbytes in via receive_data() and reads serialized bytes out via send_response()\nand send_body().\n\nAll state is per-connection, per-request-cycle. No shared mutable state.", "dir": "/api/protocols/", "excerpt": "", "href": "/pounce/api/protocols/h1/", "kind": "autodoc-python", "objectID": "/api/protocols/h1/", "reading_time": 1, "section": "protocols", "source_file": "src/pounce/protocols/h1.py", "title": "h1", "type": "autodoc-python", "uri": "/api/protocols/h1/", "url": "/pounce/api/protocols/h1/", "word_count": 0}, {"description": "HTTP/2 connection handler — sans-I/O wrapper around the h2 library.\n\nUnlike H1Protocol (which handles one request at a time), H2Connection\nmanages a multiplexed HTTP/2 connection with concurrent streams. Each\nstream maps to one ASGI request.\n\nThe h2 library is a sans-I/O state machine: we feed it bytes and it\nproduces events and output bytes. H2Connection translates between h2's\ninternal events and pounce's typed ProtocolEvent system.\n\nRequires the ``h2`` optional dependency (``pip install bengal-pounce[h2]``).\n\nAll state is per-connection. No shared mutable state.", "dir": "/api/protocols/", "excerpt": "", "href": "/pounce/api/protocols/h2/", "kind": "autodoc-python", "objectID": "/api/protocols/h2/", "reading_time": 1, "section": "protocols", "source_file": "src/pounce/protocols/h2.py", "title": "h2", "type": "autodoc-python", "uri": "/api/protocols/h2/", "url": "/pounce/api/protocols/h2/", "word_count": 0}, {"description": "HTTP/3 (QUIC) protocol support — availability check for zoomies.\n\nHTTP/3 uses QUIC (UDP) transport. The actual protocol handling lives in\n``_h3_handler.py`` which integrates zoomies' sans-I/O QuicConnection.\n\nRequires the ``h3`` optional dependency (``pip install bengal-pounce[h3]``).", "dir": "/api/protocols/", "excerpt": "", "href": "/pounce/api/protocols/h3/", "kind": "autodoc-python", "objectID": "/api/protocols/h3/", "reading_time": 1, "section": "protocols", "source_file": "src/pounce/protocols/h3.py", "title": "h3", "type": "autodoc-python", "uri": "/api/protocols/h3/", "url": "/pounce/api/protocols/h3/", "word_count": 0}, {"description": "WebSocket protocol handler — sans-I/O wrapper around wsproto.\n\nTranslates between raw bytes and typed WebSocket events. The worker feeds\nbytes in via receive_data() and reads serialized bytes out via\nsend_message() and close().\n\nRequires the ``wsproto`` optional dependency (``pip install bengal-pounce[ws]``).\n\nArchitecture: The HTTP upgrade handshake (101 Switching Protocols) is\nhandled by the H1 layer. WSProtocol only handles WebSocket framing\n*after* the upgrade is complete. wsproto 1.x server connections start\nin OPEN state — no separate accept step in wsproto itself.\n\nAll state is per-connection. No shared mutable state.", "dir": "/api/protocols/", "excerpt": "", "href": "/pounce/api/protocols/ws/", "kind": "autodoc-python", "objectID": "/api/protocols/ws/", "reading_time": 1, "section": "protocols", "source_file": "src/pounce/protocols/ws.py", "title": "ws", "type": "autodoc-python", "uri": "/api/protocols/ws/", "url": "/pounce/api/protocols/ws/", "word_count": 0}, {"description": "Server — orchestrates the full pounce lifecycle.\n\nManages the state machine:\n    CONFIG → DETECT → BIND → LIFESPAN → SERVE → SHUTDOWN\n\nWhen ``workers == 1`` the server runs a single-worker fast path with no\nsupervisor overhead.  When ``workers > 1`` the supervisor spawns and\nmonitors worker threads (nogil) or processes (GIL).\n\nSignal handling: SIGINT/SIGTERM trigger graceful shutdown.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/server/", "kind": "autodoc-python", "objectID": "/api/server/", "reading_time": 1, "section": "api", "source_file": "src/pounce/server.py", "title": "server", "type": "autodoc-python", "uri": "/api/server/", "url": "/pounce/api/server/", "word_count": 0}, {"description": "Supervisor — spawns, monitors, and restarts workers.\n\nThe supervisor sits between the ``Server`` and the ``Worker`` layer.  It\ndetects the GIL state at startup and spawns workers as either threads\n(on nogil / 3.14t) or processes (on GIL builds).  The worker\nimplementation is identical in both modes — only the spawning mechanism\ndiffers.\n\nResponsibilities:\n- Spawn N workers with their sockets\n- Monitor worker health (is_alive check on a watchdog loop)\n- Restart crashed workers (up to ``max_restarts`` per window)\n- Coordinate graceful shutdown via ``threading.Event``\n- Forward SIGINT/SIGTERM to workers", "dir": "/api/", "excerpt": "", "href": "/pounce/api/supervisor/", "kind": "autodoc-python", "objectID": "/api/supervisor/", "reading_time": 1, "section": "api", "source_file": "src/pounce/supervisor.py", "title": "supervisor", "type": "autodoc-python", "uri": "/api/supervisor/", "url": "/pounce/api/supervisor/", "word_count": 0}, {"description": "SyncApp protocol — fused sync request-response path for Pounce.\n\nWhen a SyncApp is provided, the sync worker calls handle_sync() first.\nIf it returns a RawResponse, the request is served without asyncio,\nASGI scope, or Request/Response object construction. If it returns None,\nthe request falls through to the full ASGI path (streaming, WebSocket, etc.).", "dir": "/api/", "excerpt": "", "href": "/pounce/api/sync_protocol/", "kind": "autodoc-python", "objectID": "/api/sync_protocol/", "reading_time": 1, "section": "api", "source_file": "src/pounce/sync_protocol.py", "title": "sync_protocol", "type": "autodoc-python", "uri": "/api/sync_protocol/", "url": "/pounce/api/sync_protocol/", "word_count": 0}, {"description": "SyncWorker — blocking I/O worker for request-response workloads.\n\nOne request at a time per thread, no asyncio. On 3.14t, runs in a thread\nwith true parallelism. Handles HTTP/1.1 keep-alive in a tight recv/send loop.\n\nWhen the ASGI app returns a streaming response (more_body=True) or WebSocket\nupgrade, raises NeedsAsyncError — the supervisor hands off to the async pool\n(Phase 2). For Phase 1, streaming requests receive 501 Not Implemented.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/sync_worker/", "kind": "autodoc-python", "objectID": "/api/sync_worker/", "reading_time": 1, "section": "api", "source_file": "src/pounce/sync_worker.py", "title": "sync_worker", "type": "autodoc-python", "uri": "/api/sync_worker/", "url": "/pounce/api/sync_worker/", "word_count": 0}, {"description": "First-class testing utilities for pounce.\n\nProvides ``TestServer`` for running a real pounce server in tests — works with\nhttpx, Playwright, Selenium, or any HTTP client.\n\nUsage::\n\n    from pounce.testing import TestServer\n\n    def test_homepage():\n        with TestServer(app) as server:\n            resp = httpx.get(f\"{server.url}/\")\n            assert resp.status_code == 200\n\nWhen pounce is installed, the ``pounce_server`` pytest fixture is auto-registered\nvia the ``pytest11`` entry point.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/testing/", "kind": "autodoc-python", "objectID": "/api/testing/", "reading_time": 1, "section": "api", "source_file": "src/pounce/testing.py", "title": "testing", "type": "autodoc-python", "uri": "/api/testing/", "url": "/pounce/api/testing/", "word_count": 0}, {"description": "Worker — the heart of pounce's request handling.\n\nRuns a single asyncio event loop that accepts connections on a socket and\nprocesses requests through the protocol → bridge → ASGI pipeline.\n\nEach worker is self-contained: it owns its event loop, its set of active\nconnections, and its per-worker metrics.  The supervisor spawns workers as\nthreads (nogil) or processes (GIL) — the worker does not know which.\n\nConnection flow (HTTP/1.1):\n    socket.accept() → H1Protocol.receive_data() → build_scope()\n    → negotiate_compression() → app(scope, receive, send) → access_log()\n\nHTTP/2 and WebSocket connections are delegated to dedicated handler\nmodules (``_h2_handler`` and ``_ws_handler``) to keep this file focused\non core lifecycle and HTTP/1.1 handling.", "dir": "/api/", "excerpt": "", "href": "/pounce/api/worker/", "kind": "autodoc-python", "objectID": "/api/worker/", "reading_time": 1, "section": "api", "source_file": "src/pounce/worker.py", "title": "worker", "type": "autodoc-python", "uri": "/api/worker/", "url": "/pounce/api/worker/", "word_count": 0}, {"category": "overview", "content": "Learn Pounce Pounce is a Python ASGI server for deployments, streaming workloads, and free-threaded Python. Start with installation, then move into deployment, protocol support, and migration guides. Get Started Install Pounce and serve your first ASGI app in minutes. Globe Protocols HTTP/1.1, HTTP/2, WebSocket, and HTTP/3 — how each protocol layer works. Configuration ServerConfig, CLI options, TLS setup, and tuning parameters. Server Deployment Workers, compression, production hardening, and scaling. Migrate from Uvicorn Switch from Uvicorn with minimal CLI and deployment changes. Go Deeper...", "description": "Documentation for running, deploying, and tuning the Pounce Python ASGI server", "dir": "/", "excerpt": "Learn Pounce Pounce is a Python ASGI server for deployments, streaming workloads, and free-threaded Python. Start with installation, then move into deployment, protocol support, and migration guides....", "href": "/pounce/docs/", "kind": "doc", "objectID": "/docs/", "reading_time": 1, "section": "docs", "title": "Documentation", "type": "doc", "uri": "/docs/", "url": "/pounce/docs/", "weight": 10.0, "word_count": 130}, {"category": "explanation", "content": "Pounce is an ASGI server with a worker model tailored to Python 3.14t. This section explains how it works, where it fits, and how to compare it to more familiar servers. Architecture How Pounce's server, supervisor, and worker layers fit together The internal design of the server pipeline. Timer Performance Benchmarks and what makes Pounce fast Streaming-first design and threading performance. Shield Thread Safety How Pounce handles shared state across workers Frozen configuration and per-request mutable state. Comparison When Pounce fits, when to choose alternatives, and how it compares to...", "description": "Architecture, performance, thread model, and comparison guidance for the Pounce Python ASGI server", "dir": "/docs/", "excerpt": "Pounce is an ASGI server with a worker model tailored to Python 3.14t. This section explains how it works, where it fits, and how to compare it to more familiar servers. Architecture How Pounce's...", "href": "/pounce/docs/about/", "kind": "doc", "objectID": "/docs/about/", "reading_time": 1, "section": "about", "tags": ["architecture", "design", "about"], "title": "About", "type": "doc", "uri": "/docs/about/", "url": "/pounce/docs/about/", "weight": 20.0, "word_count": 122}, {"category": "explanation", "content": "Overview Pounce follows a three-layer architecture: Server orchestrates lifecycle, Supervisor manages workers, and Workers handle requests. All layers share a single frozen ServerConfig — no synchronization needed. flowchart TD Server[\"Server\\nCONFIG → DETECT → BIND → LIFESPAN → SERVE → SHUTDOWN\"] Supervisor[\"Supervisor\\ndetect nogil → threads\\ndetect GIL → processes\"] Server --> Supervisor Supervisor -- \"spawn N workers\" --> W1[\"Worker 1\\nasyncio event loop\"] Supervisor -- \"spawn N workers\" --> W2[\"Worker 2\\nasyncio event loop\"] Supervisor -- \"spawn N workers\" --> WN[\"Worker N\\nasyncio event...", "description": "How Pounce's server, supervisor, and worker layers fit together", "dir": "/docs/about/", "excerpt": "Overview Pounce follows a three-layer architecture: Server orchestrates lifecycle, Supervisor manages workers, and Workers handle requests. All layers share a single frozen ServerConfig — no...", "href": "/pounce/docs/about/architecture/", "kind": "doc", "objectID": "/docs/about/architecture/", "reading_time": 3, "section": "about", "tags": ["architecture", "internals", "design"], "title": "Architecture", "type": "doc", "uri": "/docs/about/architecture/", "url": "/pounce/docs/about/architecture/", "weight": 10.0, "word_count": 600}, {"category": "explanation", "content": "When to Use Pounce Pounce is built for Python 3.14t and the free-threading model. If you are evaluating Python ASGI servers, the main distinction is its worker model: threads on 3.14t, automatic process fallback on GIL builds. Pounce's Model Thread-based parallelism — N worker threads share one interpreter, one copy of your app Shared memory — Lower memory footprint than process-based workers Streaming-first — Body chunks sent immediately to socket Fast-path parsing — Built-in HTTP/1.1 parser on the sync worker hot path Thread-worker reload — Rolling restart with generational worker swap on...", "description": "When Pounce fits, how it differs from process-based ASGI servers, and when to consider alternatives", "dir": "/docs/about/", "excerpt": "When to Use Pounce Pounce is built for Python 3.14t and the free-threading model. If you are evaluating Python ASGI servers, the main distinction is its worker model: threads on 3.14t, automatic...", "href": "/pounce/docs/about/comparison/", "kind": "doc", "objectID": "/docs/about/comparison/", "reading_time": 2, "section": "about", "tags": ["architecture", "deployment"], "title": "When to Use Pounce", "type": "doc", "uri": "/docs/about/comparison/", "url": "/pounce/docs/about/comparison/", "weight": 40.0, "word_count": 435}, {"content": "The Bengal Ecosystem A structured reactive stack — every layer written in pure Python for 3.14t free-threading. Stack Overview flowchart TB subgraph contentLayer [Content Layer] Patitas[Patitas - Markdown Parser] Rosettes[Rosettes - Syntax Highlighter] end subgraph renderLayer [Rendering Layer] Kida[Kida - Template Engine] end subgraph appLayer [Application Layer] Chirp[Chirp - Web Framework] end subgraph transportLayer [Transport Layer] Pounce[Pounce - ASGI Server] end subgraph orchestrationLayer [Orchestration] Bengal[Bengal - Static Site Gen] Purr[Purr - Content Runtime] end Rosettes -->...", "description": "A structured reactive stack — every layer written in pure Python for 3.14t free-threading", "dir": "/docs/about/", "excerpt": "The Bengal Ecosystem A structured reactive stack — every layer written in pure Python for 3.14t free-threading. Stack Overview flowchart TB subgraph contentLayer [Content Layer] Patitas[Patitas -...", "href": "/pounce/docs/about/ecosystem/", "kind": "doc", "objectID": "/docs/about/ecosystem/", "reading_time": 1, "section": "about", "tags": ["about", "ecosystem"], "title": "The Bengal Ecosystem", "type": "doc", "uri": "/docs/about/ecosystem/", "url": "/pounce/docs/about/ecosystem/", "weight": 50.0, "word_count": 147}, {"category": "explanation", "content": "General What is Pounce? Pounce is a free-threading-native ASGI server for Python 3.14t. It serves ASGI applications using real OS threads sharing a single interpreter, rather than the traditional fork-based model. Does Pounce work on standard (GIL) Python? Yes. On GIL builds, Pounce automatically uses processes instead of threads. The API and configuration are identical — the supervisor detects the runtime via sys._is_gil_enabled() and adapts. What Python version do I need? Python 3.14 or later. For thread-based workers (the primary use case), you need a free-threading build (Python 3.14t)....", "description": "Frequently asked questions about Pounce", "dir": "/docs/about/", "excerpt": "General What is Pounce? Pounce is a free-threading-native ASGI server for Python 3.14t. It serves ASGI applications using real OS threads sharing a single interpreter, rather than the traditional...", "href": "/pounce/docs/about/faq/", "kind": "doc", "objectID": "/docs/about/faq/", "reading_time": 2, "section": "about", "tags": ["faq", "questions"], "title": "FAQ", "type": "doc", "uri": "/docs/about/faq/", "url": "/pounce/docs/about/faq/", "weight": 50.0, "word_count": 431}, {"content": "Free-Threading Patterns for Python 3.14t Lessons from building Pounce Python 3.14t removes the Global Interpreter Lock, enabling true parallelism across threads sharing a single interpreter. This document distills the architectural patterns Pounce uses to exploit free-threading safely and efficiently. These patterns are not HTTP-specific -- they apply to any concurrent Python infrastructure: task schedulers, message brokers, data pipelines, game servers. Each pattern targets one goal: eliminate shared mutable state, or make the remaining shared state trivially correct. 1. Frozen Configuration...", "description": "Ten architectural patterns for building concurrent Python 3.14t applications", "dir": "/docs/about/", "excerpt": "Free-Threading Patterns for Python 3.14t Lessons from building Pounce Python 3.14t removes the Global Interpreter Lock, enabling true parallelism across threads sharing a single interpreter. This...", "href": "/pounce/docs/about/nogil-patterns/", "kind": "doc", "objectID": "/docs/about/nogil-patterns/", "reading_time": 12, "section": "about", "title": "Free-Threading Patterns", "type": "doc", "uri": "/docs/about/nogil-patterns/", "url": "/pounce/docs/about/nogil-patterns/", "weight": 7.0, "word_count": 2337}, {"category": "explanation", "content": "The Fast Path Pounce's sync workers use a built-in HTTP/1.1 parser optimized for the common request-head path. Local benchmark snapshots have measured it around ~3 us per request versus h11 around ~22 us on the same parser microbenchmark, but public performance claims should include the command, hardware, Python build, workload, and variance. This isn't a C extension; it's pure Python using direct bytes.find() operations on a memoryview buffer. The fast parser has explicit tests for: Method token validation Header size limit (16 KB, matching nginx default) Null byte and control character...", "description": "What makes Pounce fast and how the streaming-first design works", "dir": "/docs/about/", "excerpt": "The Fast Path Pounce's sync workers use a built-in HTTP/1.1 parser optimized for the common request-head path. Local benchmark snapshots have measured it around ~3 us per request versus h11 around...", "href": "/pounce/docs/about/performance/", "kind": "doc", "objectID": "/docs/about/performance/", "reading_time": 4, "section": "about", "tags": ["performance", "streaming"], "title": "Performance", "type": "doc", "uri": "/docs/about/performance/", "url": "/pounce/docs/about/performance/", "weight": 20.0, "word_count": 733}, {"category": "explanation", "content": "The Free-Threading Model Python 3.14t (PEP 703) removes the Global Interpreter Lock. For the first time, Python threads execute in true parallel. This changes the rules for server design: GIL builds: Multi-worker means multi-process (fork). Each process has its own memory space. Thread safety is irrelevant between workers. Free-threading builds: Multi-worker means multi-thread. All workers share one memory space. Thread safety matters. Pounce is designed for the free-threading world. The key principle: server-owned shared configuration is frozen, mutable request data is per-request. What's...", "description": "How Pounce handles shared state across workers on free-threading builds", "dir": "/docs/about/", "excerpt": "The Free-Threading Model Python 3.14t (PEP 703) removes the Global Interpreter Lock. For the first time, Python threads execute in true parallel. This changes the rules for server design: GIL builds:...", "href": "/pounce/docs/about/thread-safety/", "kind": "doc", "objectID": "/docs/about/thread-safety/", "reading_time": 3, "section": "about", "tags": ["thread-safety", "free-threading", "nogil"], "title": "Thread Safety", "type": "doc", "uri": "/docs/about/thread-safety/", "url": "/pounce/docs/about/thread-safety/", "weight": 30.0, "word_count": 512}, {"category": "reference", "content": "Settings ServerConfig The frozen dataclass that controls everything All configuration fields, defaults, and validation rules. Terminal CLI Reference Command-line options for the pounce command All flags and arguments. Lock TLS Setting up TLS termination Certificate configuration and ALPN for HTTP/2. Monitor Display & Signage Application banner and startup display modes Name, version, tagline, and signage layout.", "description": "ServerConfig, CLI options, TLS, and display settings", "dir": "/docs/", "excerpt": "Settings ServerConfig The frozen dataclass that controls everything All configuration fields, defaults, and validation rules. Terminal CLI Reference Command-line options for the pounce command All...", "href": "/pounce/docs/configuration/", "kind": "doc", "objectID": "/docs/configuration/", "reading_time": 1, "section": "configuration", "tags": ["configuration", "settings", "cli", "tls"], "title": "Configuration", "type": "doc", "uri": "/docs/configuration/", "url": "/pounce/docs/configuration/", "weight": 40.0, "word_count": 56}, {"category": "reference", "content": "Usage pounce serve --app APP [OPTIONS] The --app argument is a Python module path with an attribute, e.g. myapp:app. The app factory pattern is also supported: myapp:create_app(). Options Server Flag Default Description --host TEXT 127.0.0.1 Bind address --port INT 8000 Bind port --uds PATH — Unix domain socket path (mutually exclusive with --host/--port) --workers INT 1 Number of workers (0 = auto-detect from CPU cores) --worker-mode TEXT auto Worker execution model: auto (sync on 3.14t, async on GIL), sync (blocking I/O), async (event loop), or subinterpreter --cpu-affinity disabled Pin...", "description": "Command-line options for the pounce command", "dir": "/docs/configuration/", "excerpt": "Usage pounce serve --app APP [OPTIONS] The --app argument is a Python module path with an attribute, e.g. myapp:app. The app factory pattern is also supported: myapp:create_app(). Options Server Flag...", "href": "/pounce/docs/configuration/cli/", "kind": "doc", "objectID": "/docs/configuration/cli/", "reading_time": 3, "section": "configuration", "tags": ["cli", "command-line", "reference"], "title": "CLI Reference", "type": "doc", "uri": "/docs/configuration/cli/", "url": "/pounce/docs/configuration/cli/", "weight": 20.0, "word_count": 666}, {"content": "Display & Signage Pounce can show an optional application banner at startup with your app's name, version, and tagline. Controlled via DisplayConfig. Configuration from pounce.config import ServerConfig from pounce.display import DisplayConfig config = ServerConfig( display=DisplayConfig( name=\"My App\", tagline=\"Hypermedia-native dashboard\", version=\"1.2.0\", signage=\"minimal\", ), ) DisplayConfig Fields Field Purpose name Application title (no app block shown if unset) tagline One-liner under the name version Shown next to the name lines Extra static lines in the app header signage full...", "description": "Application banner, startup display, and signage modes", "dir": "/docs/configuration/", "excerpt": "Display & Signage Pounce can show an optional application banner at startup with your app's name, version, and tagline. Controlled via DisplayConfig. Configuration from pounce.config import...", "href": "/pounce/docs/configuration/display/", "kind": "doc", "objectID": "/docs/configuration/display/", "reading_time": 1, "section": "configuration", "title": "Display & Signage", "type": "doc", "uri": "/docs/configuration/display/", "url": "/pounce/docs/configuration/display/", "weight": 4.0, "word_count": 196}, {"category": "reference", "content": "Overview ServerConfig is a frozen dataclass (@dataclass(frozen=True, slots=True)) that holds all server settings. It's created once at startup and shared across workers as frozen server configuration. Treat referenced objects as read-only unless their own API says otherwise. from pounce import ServerConfig config = ServerConfig( host=\"0.0.0.0\", port=8000, workers=4, compression=True, server_timing=True, health_check_path=\"/health\", ) Stability Tiers Not every knob carries the same maturity. Use the tier to decide what to lean on in production. The same classification is surfaced...", "description": "The frozen dataclass that controls all server behavior", "dir": "/docs/configuration/", "excerpt": "Overview ServerConfig is a frozen dataclass (@dataclass(frozen=True, slots=True)) that holds all server settings. It's created once at startup and shared across workers as frozen server...", "href": "/pounce/docs/configuration/server-config/", "kind": "doc", "objectID": "/docs/configuration/server-config/", "reading_time": 7, "section": "configuration", "tags": ["configuration", "serverconfig", "dataclass"], "title": "ServerConfig", "type": "doc", "uri": "/docs/configuration/server-config/", "url": "/pounce/docs/configuration/server-config/", "weight": 10.0, "word_count": 1458}, {"category": "how-to", "content": "Overview Pounce supports TLS termination using Python's stdlib ssl module, with optional truststore integration for system certificate stores. Basic Setup pounce serve --app myapp:app --ssl-certfile cert.pem --ssl-keyfile key.pem Or programmatically: import pounce pounce.run( \"myapp:app\", ssl_certfile=\"cert.pem\", ssl_keyfile=\"key.pem\", ) Note Note Both ssl_certfile and ssl_keyfile must be provided together. Setting only one raises ValueError. Self-Signed Certificates (Development) For local development, generate a self-signed certificate: openssl req -x509 -newkey rsa:2048 -keyout key.pem...", "description": "Setting up TLS termination for HTTPS and HTTP/2", "dir": "/docs/configuration/", "excerpt": "Overview Pounce supports TLS termination using Python's stdlib ssl module, with optional truststore integration for system certificate stores. Basic Setup pounce serve --app myapp:app --ssl-certfile...", "href": "/pounce/docs/configuration/tls/", "kind": "doc", "objectID": "/docs/configuration/tls/", "reading_time": 1, "section": "configuration", "tags": ["tls", "ssl", "https", "security"], "title": "TLS", "type": "doc", "uri": "/docs/configuration/tls/", "url": "/pounce/docs/configuration/tls/", "weight": 30.0, "word_count": 232}, {"category": "how-to", "content": "Deploy Pounce in production. Start with Production for the essentials, then tune Workers, enable Compression, and layer on Observability and Security as needed. Shield Production Hardening, reverse proxy, and scaling patterns Running Pounce in production environments. Cpu Workers Configuring worker count, thread vs process mode Tuning parallelism for your workload. Cloud Railway PORT, health checks, platform TLS, and deploy drains Deploying Pounce on Railway public networking. Compression Zstd, gzip, and content negotiation Zero-dependency compression with Python 3.14 stdlib. Lock Security...", "description": "Workers, compression, security, and production configuration", "dir": "/docs/", "excerpt": "Deploy Pounce in production. Start with Production for the essentials, then tune Workers, enable Compression, and layer on Observability and Security as needed. Shield Production Hardening, reverse...", "href": "/pounce/docs/deployment/", "kind": "doc", "objectID": "/docs/deployment/", "reading_time": 1, "section": "deployment", "tags": ["deployment", "production", "workers", "compression", "security", "observability"], "title": "Deployment", "type": "doc", "uri": "/docs/deployment/", "url": "/pounce/docs/deployment/", "weight": 50.0, "word_count": 135}, {"category": "how-to", "content": "Backpressure Pounce provides two complementary load protection mechanisms: rate limiting (per-client) and request queueing (per-worker load shedding). Use both together for comprehensive protection. Warning Warning Both limits are enforced per worker, not per server. With workers > 1 the real ceilings are the configured values multiplied by the worker count. See Per-Worker Limits below before sizing them. Rate Limiting Request Queueing Purpose Prevent per-client abuse Handle global overload Scope Per IP address, per worker Per worker Response 429 Too Many Requests 503 Service Unavailable...", "description": "Rate limiting and request queueing for load protection", "dir": "/docs/deployment/", "excerpt": "Backpressure Pounce provides two complementary load protection mechanisms: rate limiting (per-client) and request queueing (per-worker load shedding). Use both together for comprehensive protection....", "href": "/pounce/docs/deployment/backpressure/", "kind": "doc", "objectID": "/docs/deployment/backpressure/", "reading_time": 4, "section": "deployment", "tags": ["deployment", "rate-limiting", "queueing", "backpressure"], "title": "Backpressure", "type": "doc", "uri": "/docs/deployment/backpressure/", "url": "/pounce/docs/deployment/backpressure/", "weight": 90.0, "word_count": 728}, {"category": "how-to", "content": "Overview Pounce negotiates content-encoding automatically based on the client's Accept-Encoding header. Priority order: zstd — Best compression ratio, lowest CPU cost (Python 3.14 stdlib, PEP 784) gzip — Universal browser support (stdlib zlib) identity — No compression (fallback) All compression uses Python standard library modules — zero external dependencies. Configuration Compression is enabled by default: # Disabled (compression is enabled by default) pounce serve --app myapp:app --no-compression Programmatically: import pounce pounce.run( \"myapp:app\", compression=True,...", "description": "Zstd and gzip content-encoding with zero external dependencies", "dir": "/docs/deployment/", "excerpt": "Overview Pounce negotiates content-encoding automatically based on the client's Accept-Encoding header. Priority order: zstd — Best compression ratio, lowest CPU cost (Python 3.14 stdlib, PEP 784)...", "href": "/pounce/docs/deployment/compression/", "kind": "doc", "objectID": "/docs/deployment/compression/", "reading_time": 1, "section": "deployment", "tags": ["compression", "zstd", "gzip", "encoding"], "title": "Compression", "type": "doc", "uri": "/docs/deployment/compression/", "url": "/pounce/docs/deployment/compression/", "weight": 20.0, "word_count": 214}, {"category": "how-to", "content": "Server Lifecycle Pounce handles SIGHUP for graceful reload on supported multi-worker paths and SIGTERM / SIGINT for graceful shutdown. Both paths use connection draining: active requests get time to finish, while workers that are leaving service reject new connections. Graceful Reload (SIGHUP) On supported multi-worker thread and subinterpreter paths, send SIGHUP to perform a rolling restart with fresh code: kill -HUP <pid> # or with systemd: systemctl reload pounce What Happens Old workers continue handling existing requests App code is reimported and new workers spawn (generation N+1) Old...", "description": "Graceful reload and shutdown with connection draining", "dir": "/docs/deployment/", "excerpt": "Server Lifecycle Pounce handles SIGHUP for graceful reload on supported multi-worker paths and SIGTERM / SIGINT for graceful shutdown. Both paths use connection draining: active requests get time to...", "href": "/pounce/docs/deployment/lifecycle/", "kind": "doc", "objectID": "/docs/deployment/lifecycle/", "reading_time": 2, "section": "deployment", "tags": ["deployment", "reload", "shutdown", "rolling-reload"], "title": "Server Lifecycle", "type": "doc", "uri": "/docs/deployment/lifecycle/", "url": "/pounce/docs/deployment/lifecycle/", "weight": 60.0, "word_count": 481}, {"category": "how-to", "content": "Observability Pounce provides six observability layers: health checks, request IDs, Prometheus metrics, OpenTelemetry tracing, Sentry error tracking, and the opt-in /_pounce/info introspection endpoint. Health Checks Built-in endpoint that responds before the ASGI app is invoked: pounce serve --app myapp:app --health-check-path /health Response: {\"status\": \"ok\", \"uptime_seconds\": 3600.1, \"worker_id\": 0, \"active_connections\": 42} Characteristics: fast (bypasses ASGI), excluded from access logs, works even if your app is unhealthy, includes Cache-Control: no-cache. Kubernetes livenessProbe:...", "description": "Health checks, request tracing, Prometheus metrics, OpenTelemetry, and Sentry", "dir": "/docs/deployment/", "excerpt": "Observability Pounce provides six observability layers: health checks, request IDs, Prometheus metrics, OpenTelemetry tracing, Sentry error tracking, and the opt-in /_pounce/info introspection...", "href": "/pounce/docs/deployment/observability/", "kind": "doc", "objectID": "/docs/deployment/observability/", "reading_time": 6, "section": "deployment", "tags": ["observability", "health-check", "metrics", "tracing", "opentelemetry", "sentry", "introspection"], "title": "Observability", "type": "doc", "uri": "/docs/deployment/observability/", "url": "/pounce/docs/deployment/observability/", "weight": 50.0, "word_count": 1268}, {"category": "how-to", "content": "Recommended Configuration pounce serve --app myapp:app \\ --host 0.0.0.0 \\ --port 8000 \\ --workers 0 \\ --log-level warning \\ --log-format json \\ --header-timeout 10 \\ --health-check-path /health \\ --shutdown-timeout 15 Behind a Reverse Proxy In most production setups, Pounce runs behind a reverse proxy (nginx, Caddy, etc.) that handles TLS termination, static files, and load balancing. Nginx (TCP) upstream pounce { server 127.0.0.1:8000; } server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/ssl/cert.pem; ssl_certificate_key /etc/ssl/key.pem; location / { proxy_pass...", "description": "Running Pounce in production environments", "dir": "/docs/deployment/", "excerpt": "Recommended Configuration pounce serve --app myapp:app \\ --host 0.0.0.0 \\ --port 8000 \\ --workers 0 \\ --log-level warning \\ --log-format json \\ --header-timeout 10 \\ --health-check-path /health \\...", "href": "/pounce/docs/deployment/production/", "kind": "doc", "objectID": "/docs/deployment/production/", "reading_time": 4, "section": "deployment", "tags": ["production", "deployment", "hardening", "scaling"], "title": "Production", "type": "doc", "uri": "/docs/deployment/production/", "url": "/pounce/docs/deployment/production/", "weight": 30.0, "word_count": 741}, {"category": "how-to", "content": "Railway public networking expects the web process to listen on the Railway-provided PORT variable on 0.0.0.0. Railway terminates public TLS at the platform edge for HTTP services, so the usual Pounce deployment is plain HTTP inside the container with trusted_hosts configured only after you confirm the ingress peer addresses for your service. Start Command Use a small entrypoint when your app needs programmatic config: # railway_app.py import os import pounce from myapp import app if __name__ == \"__main__\": pounce.run( app, host=\"0.0.0.0\", port=int(os.environ[\"PORT\"]), workers=0,...", "description": "Deploying Pounce on Railway public networking", "dir": "/docs/deployment/", "excerpt": "Railway public networking expects the web process to listen on the Railway-provided PORT variable on 0.0.0.0. Railway terminates public TLS at the platform edge for HTTP services, so the usual Pounce...", "href": "/pounce/docs/deployment/railway/", "kind": "doc", "objectID": "/docs/deployment/railway/", "reading_time": 2, "section": "deployment", "tags": ["railway", "deployment", "production", "health-checks"], "title": "Railway", "type": "doc", "uri": "/docs/deployment/railway/", "url": "/pounce/docs/deployment/railway/", "weight": 35.0, "word_count": 397}, {"category": "explanation", "content": "Overview Pounce includes several defense-in-depth security measures that operate at the server level — before your ASGI application is invoked. These protections are active by default and require no configuration. Proxy Header Validation When running behind a reverse proxy (nginx, Caddy, etc.), the proxy adds headers like X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host to communicate the original client's information. The problem: A malicious client can send these headers directly to spoof their IP or protocol. Pounce prevents this by only trusting these headers from known proxy IPs....", "description": "Built-in security features for production deployments", "dir": "/docs/deployment/", "excerpt": "Overview Pounce includes several defense-in-depth security measures that operate at the server level — before your ASGI application is invoked. These protections are active by default and require no...", "href": "/pounce/docs/deployment/security/", "kind": "doc", "objectID": "/docs/deployment/security/", "reading_time": 4, "section": "deployment", "tags": ["security", "proxy", "headers", "hardening"], "title": "Security", "type": "doc", "uri": "/docs/deployment/security/", "url": "/pounce/docs/deployment/security/", "weight": 40.0, "word_count": 761}, {"category": "how-to", "content": "Worker Modes Pounce automatically selects the worker mode based on the Python runtime: Runtime Workers Are Detection Python 3.14t (free-threading) Threads sys._is_gil_enabled() returns False Standard CPython (GIL) Processes sys._is_gil_enabled() returns True You don't need to configure this — the supervisor detects it at startup. Configuring Worker Count # Single worker (no supervisor, lowest overhead) pounce serve --app myapp:app --workers 1 # Auto-detect from CPU cores pounce serve --app myapp:app --workers 0 # Explicit count pounce serve --app myapp:app --workers 4 Single Worker...", "description": "Configuring worker count and understanding thread vs process mode", "dir": "/docs/deployment/", "excerpt": "Worker Modes Pounce automatically selects the worker mode based on the Python runtime: Runtime Workers Are Detection Python 3.14t (free-threading) Threads sys._is_gil_enabled() returns False Standard...", "href": "/pounce/docs/deployment/workers/", "kind": "doc", "objectID": "/docs/deployment/workers/", "reading_time": 2, "section": "deployment", "tags": ["workers", "threading", "processes", "parallelism"], "title": "Workers", "type": "doc", "uri": "/docs/deployment/workers/", "url": "/pounce/docs/deployment/workers/", "weight": 10.0, "word_count": 418}, {"category": "explanation", "content": "Link ASGI Bridge Scope/receive/send bridge, security measures, and protocol handler interface", "description": "ASGI bridge internals and protocol handler interface", "dir": "/docs/", "excerpt": "Link ASGI Bridge Scope/receive/send bridge, security measures, and protocol handler interface", "href": "/pounce/docs/extending/", "kind": "doc", "objectID": "/docs/extending/", "reading_time": 1, "section": "extending", "tags": ["extending", "internals", "asgi", "bridge"], "title": "Extending", "type": "doc", "uri": "/docs/extending/", "url": "/pounce/docs/extending/", "weight": 60.0, "word_count": 11}, {"category": "explanation", "content": "Overview The ASGI bridge is the layer between Pounce's protocol parsers and your ASGI application. It constructs the scope dict, creates receive and send callables, and manages the per-request lifecycle. HTTP Bridge For HTTP requests, the bridge: Builds scope — Extracts method, path, headers, query string from the parsed request Validates proxy headers — Applies X-Forwarded-* from trusted peers, strips from untrusted Generates request ID — UUID4 hex or honoured from trusted proxy's X-Request-ID Creates receive — Returns request body chunks as http.request events Creates send — Accepts...", "description": "How Pounce translates protocol events to the ASGI interface", "dir": "/docs/extending/", "excerpt": "Overview The ASGI bridge is the layer between Pounce's protocol parsers and your ASGI application. It constructs the scope dict, creates receive and send callables, and manages the per-request...", "href": "/pounce/docs/extending/asgi-bridge/", "kind": "doc", "objectID": "/docs/extending/asgi-bridge/", "reading_time": 3, "section": "extending", "tags": ["asgi", "bridge", "internals"], "title": "ASGI Bridge", "type": "doc", "uri": "/docs/extending/asgi-bridge/", "url": "/pounce/docs/extending/asgi-bridge/", "weight": 10.0, "word_count": 555}, {"content": "Features Built-in capabilities that ship with pounce -- no external dependencies required (except where noted). File Static File Serving Chunked serving with ETags, range requests, and pre-compression Middleware System ASGI3 middleware stack for request/response transformation Warning Development Error Pages Rich HTML tracebacks with syntax highlighting (debug mode) Timer Lifecycle Logging Structured connection/request events with correlation IDs WebSocket Compression Permessage-deflate compression (RFC 7692) For protocol support (HTTP/1.1, HTTP/2, WebSocket, HTTP/3), see Protocols. For...", "description": "Built-in features beyond core protocol support", "dir": "/docs/", "excerpt": "Features Built-in capabilities that ship with pounce -- no external dependencies required (except where noted). File Static File Serving Chunked serving with ETags, range requests, and...", "href": "/pounce/docs/features/", "kind": "doc", "objectID": "/docs/features/", "reading_time": 1, "section": "features", "title": "Features", "type": "doc", "uri": "/docs/features/", "url": "/pounce/docs/features/", "weight": 30.0, "word_count": 79}, {"content": "Development Error Pages When your ASGI app raises an unhandled exception in debug mode, pounce renders a detailed error page with full traceback, syntax highlighting, local variables, and request context. In production, errors return a plain 500 Internal Server Error with no internals exposed. Enable Debug Mode from pounce import ServerConfig config = ServerConfig(debug=True, workers=1) Use a config file or programmatic ServerConfig for debug=True; the current CLI does not expose a debug-mode flag. What You See Exception header with type and message Request context (method, path, headers)...", "description": "Rich HTML error pages with syntax highlighting for debugging", "dir": "/docs/features/", "excerpt": "Development Error Pages When your ASGI app raises an unhandled exception in debug mode, pounce renders a detailed error page with full traceback, syntax highlighting, local variables, and request...", "href": "/pounce/docs/features/error-pages/", "kind": "doc", "objectID": "/docs/features/error-pages/", "reading_time": 1, "section": "features", "title": "Development Error Pages", "type": "doc", "uri": "/docs/features/error-pages/", "url": "/pounce/docs/features/error-pages/", "weight": 4.0, "word_count": 244}, {"content": "Lifecycle Logging Pounce captures structured events throughout the connection lifecycle for production debugging. Beyond access logs, lifecycle logging tracks connection establishment, client disconnects, slow requests, and connection teardown with correlation IDs. Quick Start from pounce import ServerConfig config = ServerConfig( lifecycle_logging=True, log_format=\"json\", log_slow_requests_threshold=2.0, # seconds ) Configuration Option Default Description lifecycle_logging False Enable structured lifecycle events log_slow_requests_threshold 5.0 Seconds before a request is flagged slow...", "description": "Structured connection and request lifecycle events with correlation IDs", "dir": "/docs/features/", "excerpt": "Lifecycle Logging Pounce captures structured events throughout the connection lifecycle for production debugging. Beyond access logs, lifecycle logging tracks connection establishment, client...", "href": "/pounce/docs/features/lifecycle-logging/", "kind": "doc", "objectID": "/docs/features/lifecycle-logging/", "reading_time": 2, "section": "features", "title": "Lifecycle Logging", "type": "doc", "uri": "/docs/features/lifecycle-logging/", "url": "/pounce/docs/features/lifecycle-logging/", "weight": 5.0, "word_count": 365}, {"content": "Middleware System Pounce supports server-level middleware for transforming HTTP requests and responses across your entire application. Middleware runs inside pounce's HTTP request pipeline, before and after your ASGI app. Lifespan, worker lifecycle, and WebSocket scopes bypass this middleware stack. Configuration Pass middleware as a list to ServerConfig. They execute in order (first = outermost): from pounce import ServerConfig, CORSMiddleware, SecurityHeadersMiddleware config = ServerConfig( middleware=[ CORSMiddleware( allow_origin=\"https://example.com\", allow_methods=\"GET, POST\",...", "description": "ASGI3 middleware stack for request/response transformation", "dir": "/docs/features/", "excerpt": "Middleware System Pounce supports server-level middleware for transforming HTTP requests and responses across your entire application. Middleware runs inside pounce's HTTP request pipeline, before...", "href": "/pounce/docs/features/middleware/", "kind": "doc", "objectID": "/docs/features/middleware/", "reading_time": 2, "section": "features", "title": "Middleware System", "type": "doc", "uri": "/docs/features/middleware/", "url": "/pounce/docs/features/middleware/", "weight": 2.0, "word_count": 303}, {"content": "Static File Serving Pounce provides high-performance static file serving with pre-compressed file support, ETags, range requests, and automatic content negotiation. Quick Start from pounce import ServerConfig config = ServerConfig( static_files={ \"/static\": \"./public\", # Serve ./public at /static \"/assets\": \"./dist/assets\", # Multiple mappings supported }, static_precompressed=True, # Serve .gz/.zst if available static_cache_control=\"public, max-age=3600\", ) Access files at: http://localhost:8000/static/style.css → ./public/style.css http://localhost:8000/assets/app.js → ./dist/assets/app.js...", "description": "Chunked file serving with pre-compression and ETags", "dir": "/docs/features/", "excerpt": "Static File Serving Pounce provides high-performance static file serving with pre-compressed file support, ETags, range requests, and automatic content negotiation. Quick Start from pounce import...", "href": "/pounce/docs/features/static-files/", "kind": "doc", "objectID": "/docs/features/static-files/", "reading_time": 2, "section": "features", "title": "Static File Serving", "type": "doc", "uri": "/docs/features/static-files/", "url": "/pounce/docs/features/static-files/", "weight": 1.0, "word_count": 410}, {"content": "WebSocket Compression Pounce supports permessage-deflate compression (RFC 7692) for WebSocket connections, reducing bandwidth by 60-80% for text messages. Configuration Enabled by default, but only negotiated when the client offers permessage-deflate in Sec-WebSocket-Extensions. Requires wsproto: pip install bengal-pounce[ws] from pounce import ServerConfig config = ServerConfig( websocket_compression=True, # default websocket_max_message_size=10_485_760, # 10 MB default ) To disable (e.g., for already-compressed data): config = ServerConfig(websocket_compression=False) How It Works Client...", "description": "Permessage-deflate compression for WebSocket connections", "dir": "/docs/features/", "excerpt": "WebSocket Compression Pounce supports permessage-deflate compression (RFC 7692) for WebSocket connections, reducing bandwidth by 60-80% for text messages. Configuration Enabled by default, but only...", "href": "/pounce/docs/features/websocket-compression/", "kind": "doc", "objectID": "/docs/features/websocket-compression/", "reading_time": 1, "section": "features", "title": "WebSocket Compression", "type": "doc", "uri": "/docs/features/websocket-compression/", "url": "/pounce/docs/features/websocket-compression/", "weight": 6.0, "word_count": 147}, {"category": "onboarding", "content": "Download Installation Install Pounce with pip, uv, or from source Get Pounce running in your environment. Quickstart Serve your first ASGI app with Pounce From zero to running server in 5 minutes.", "description": "Install Pounce and serve your first ASGI application with a production-friendly Python ASGI server", "dir": "/docs/", "excerpt": "Download Installation Install Pounce with pip, uv, or from source Get Pounce running in your environment. Quickstart Serve your first ASGI app with Pounce From zero to running server in 5 minutes.", "href": "/pounce/docs/get-started/", "kind": "doc", "objectID": "/docs/get-started/", "reading_time": 1, "section": "get-started", "tags": ["getting-started", "installation", "quickstart"], "title": "Get Started", "type": "doc", "uri": "/docs/get-started/", "url": "/pounce/docs/get-started/", "weight": 10.0, "word_count": 32}, {"category": "onboarding", "content": "Prerequisites Python 3.14+ (free-threading build recommended for thread-based workers) Note Note Pounce works on both GIL and free-threading builds. On GIL builds, multi-worker mode uses processes instead of threads — same API, same config. Install uv pip From Source uv add bengal-pounce pip install bengal-pounce git clone https://github.com/lbliii/pounce.git cd pounce uv sync --group dev Optional Extras Pounce ships with two required runtime dependencies: h11 (HTTP/1.1 parsing) and milo-cli (the CLI). The request hot path depends only on h11. Additional protocols are optional extras: Extra...", "description": "Install Pounce and optional protocol extras", "dir": "/docs/get-started/", "excerpt": "Prerequisites Python 3.14+ (free-threading build recommended for thread-based workers) Note Note Pounce works on both GIL and free-threading builds. On GIL builds, multi-worker mode uses processes...", "href": "/pounce/docs/get-started/installation/", "kind": "doc", "objectID": "/docs/get-started/installation/", "reading_time": 1, "section": "get-started", "tags": ["installation", "setup"], "title": "Installation", "type": "doc", "uri": "/docs/get-started/installation/", "url": "/pounce/docs/get-started/installation/", "weight": 10.0, "word_count": 185}, {"category": "onboarding", "content": "Create an ASGI App Create a file called app.py: async def app(scope, receive, send): \"\"\"Minimal ASGI application.\"\"\" assert scope[\"type\"] == \"http\" await send({ \"type\": \"http.response.start\", \"status\": 200, \"headers\": [ [b\"content-type\", b\"text/plain\"], ], }) await send({ \"type\": \"http.response.body\", \"body\": b\"Hello from Pounce!\", }) Serve It Command Line Programmatic pounce serve --app app:app import pounce pounce.run(\"app:app\") Open http://127.0.0.1:8000 in your browser. You should see \"Hello from Pounce!\". Enable Development Reload pounce serve --app app:app --reload Pounce watches your...", "description": "Serve your first ASGI application with Pounce", "dir": "/docs/get-started/", "excerpt": "Create an ASGI App Create a file called app.py: async def app(scope, receive, send): \"\"\"Minimal ASGI application.\"\"\" assert scope[\"type\"] == \"http\" await send({ \"type\": \"http.response.start\",...", "href": "/pounce/docs/get-started/quickstart/", "kind": "doc", "objectID": "/docs/get-started/quickstart/", "reading_time": 1, "section": "get-started", "tags": ["quickstart", "tutorial"], "title": "Quickstart", "type": "doc", "uri": "/docs/get-started/quickstart/", "url": "/pounce/docs/get-started/quickstart/", "weight": 20.0, "word_count": 242}, {"category": "explanation", "content": "Pounce supports multiple protocols through a modular handler system. The core ships with HTTP/1.1 via h11. HTTP/2 and WebSocket are optional extras. HTTP/3 is optional with limited parity while reload/drain and benchmark proof remain open. TLS support is also optional and installs with bengal-pounce[tls]. HTTP/1.1 Default protocol - h11 (pure Python) plus sync-worker fast parser The foundation of Pounce's request handling. HTTP/2 Stream multiplexing, header compression, priority signals Install with bengal-pounce[h2]. HTTP/3 Optional-limited QUIC/UDP transport, QPACK, 0-RTT policy, TLS...", "description": "HTTP/1.1, HTTP/2, and WebSocket protocol handling", "dir": "/docs/", "excerpt": "Pounce supports multiple protocols through a modular handler system. The core ships with HTTP/1.1 via h11. HTTP/2 and WebSocket are optional extras. HTTP/3 is optional with limited parity while...", "href": "/pounce/docs/protocols/", "kind": "doc", "objectID": "/docs/protocols/", "reading_time": 1, "section": "protocols", "tags": ["protocols", "http", "websocket"], "title": "Protocols", "type": "doc", "uri": "/docs/protocols/", "url": "/pounce/docs/protocols/", "weight": 30.0, "word_count": 152}, {"category": "reference", "content": "Overview HTTP/1.1 is Pounce's default and only required protocol. Two parsers are used depending on the worker mode: Parser Type Worker Speed h11 Pure Python Async workers ~22 µs/req Built-in fast parser Pure Python Sync workers ~3 µs/req The sync worker hot path automatically uses the fast built-in parser (_fast_h1.py) for simple request-response handling. Complex requests (chunked bodies, trailer headers) fall through to h11. h11 Backend The async worker parser. Pure Python, no compilation needed: import pounce pounce.run(\"myapp:app\") h11 is a state-machine-based HTTP/1.1 parser. It's...", "description": "HTTP/1.1 protocol handling via h11 and built-in fast parser", "dir": "/docs/protocols/", "excerpt": "Overview HTTP/1.1 is Pounce's default and only required protocol. Two parsers are used depending on the worker mode: Parser Type Worker Speed h11 Pure Python Async workers ~22 µs/req Built-in fast...", "href": "/pounce/docs/protocols/http1/", "kind": "doc", "objectID": "/docs/protocols/http1/", "reading_time": 2, "section": "protocols", "tags": ["http", "h11", "protocol"], "title": "HTTP/1.1", "type": "doc", "uri": "/docs/protocols/http1/", "url": "/pounce/docs/protocols/http1/", "weight": 10.0, "word_count": 362}, {"category": "reference", "content": "Overview HTTP/2 support is provided via the h2 library. Install the extra: uv add \"bengal-pounce[h2]\" If the extra is missing, the HTTP/2 path fails with an install hint: pip install bengal-pounce[h2]. HTTP/2 provides: Stream multiplexing — Multiple requests over a single TCP connection HPACK header compression — Reduced overhead for repeated headers Priority signals — Clients can indicate request priority Server push — Not implemented (deprecated in most browsers) Requirements HTTP/2 requires TLS with ALPN negotiation: pounce serve --app myapp:app --ssl-certfile cert.pem --ssl-keyfile...", "description": "HTTP/2 support via h2 — stream multiplexing, header compression, priority signals", "dir": "/docs/protocols/", "excerpt": "Overview HTTP/2 support is provided via the h2 library. Install the extra: uv add \"bengal-pounce[h2]\" If the extra is missing, the HTTP/2 path fails with an install hint: pip install...", "href": "/pounce/docs/protocols/http2/", "kind": "doc", "objectID": "/docs/protocols/http2/", "reading_time": 1, "section": "protocols", "tags": ["http2", "h2", "protocol", "multiplexing"], "title": "HTTP/2", "type": "doc", "uri": "/docs/protocols/http2/", "url": "/pounce/docs/protocols/http2/", "weight": 20.0, "word_count": 263}, {"category": "reference", "content": "HTTP/3 support is optional and uses the pure-Python bengal-zoomies QUIC stack. It requires TLS certificate configuration because QUIC includes TLS 1.3 in the transport handshake. Note Note HTTP/3 has its own support boundary from HTTP/1.1 and HTTP/2 because it uses a UDP listener and QUIC transport state. Check lifecycle, reload, 0-RTT, limit, and benchmark notes before treating it as production-equivalent to the TCP paths. WebSocket over HTTP/3 is not currently supported. Install pip install \"bengal-pounce[h3]\" If bengal-zoomies is missing, the HTTP/3 path fails with an install hint: pip...", "description": "QUIC/UDP HTTP serving through the optional bengal-zoomies transport", "dir": "/docs/protocols/", "excerpt": "HTTP/3 support is optional and uses the pure-Python bengal-zoomies QUIC stack. It requires TLS certificate configuration because QUIC includes TLS 1.3 in the transport handshake. Note Note HTTP/3 has...", "href": "/pounce/docs/protocols/http3/", "kind": "doc", "objectID": "/docs/protocols/http3/", "reading_time": 1, "section": "protocols", "tags": ["protocols", "http3", "quic", "tls"], "title": "HTTP/3", "type": "doc", "uri": "/docs/protocols/http3/", "url": "/pounce/docs/protocols/http3/", "weight": 23.0, "word_count": 264}, {"category": "reference", "content": "Overview WebSocket support is provided via the wsproto library. Install the extra: uv add \"bengal-pounce[ws]\" If wsproto is missing, WebSocket setup fails with an install hint: pip install bengal-pounce[ws]. Pounce supports: Standard WebSocket — Upgrade from HTTP/1.1 WebSocket over HTTP/2 — Multiplexed with other HTTP/2 streams when both ws and h2 extras are installed Per-message compression — Via the permessage-deflate extension ASGI WebSocket Lifecycle WebSocket connections follow the ASGI WebSocket spec: stateDiagram-v2 [*] --> Connect: websocket.connect Connect --> Accepted:...", "description": "Optional WebSocket support via wsproto", "dir": "/docs/protocols/", "excerpt": "Overview WebSocket support is provided via the wsproto library. Install the extra: uv add \"bengal-pounce[ws]\" If wsproto is missing, WebSocket setup fails with an install hint: pip install...", "href": "/pounce/docs/protocols/websocket/", "kind": "doc", "objectID": "/docs/protocols/websocket/", "reading_time": 1, "section": "protocols", "tags": ["websocket", "wsproto", "protocol", "realtime"], "title": "WebSocket", "type": "doc", "uri": "/docs/protocols/websocket/", "url": "/pounce/docs/protocols/websocket/", "weight": 30.0, "word_count": 283}, {"category": "reference", "content": "Code API Reference Public API — run(), ServerConfig, ASGI types Complete reference for the pounce package. Warning Error Reference Error hierarchy and common error messages Understanding Pounce's error types.", "description": "Complete API reference, error codes, and configuration fields", "dir": "/docs/", "excerpt": "Code API Reference Public API — run(), ServerConfig, ASGI types Complete reference for the pounce package. Warning Error Reference Error hierarchy and common error messages Understanding Pounce's...", "href": "/pounce/docs/reference/", "kind": "doc", "objectID": "/docs/reference/", "reading_time": 1, "section": "reference", "tags": ["reference", "api", "errors"], "title": "Reference", "type": "doc", "uri": "/docs/reference/", "url": "/pounce/docs/reference/", "weight": 70.0, "word_count": 29}, {"category": "reference", "content": "Public API The pounce package exports the following: from pounce import ( run, ServerConfig, ASGIApp, Scope, Receive, Send, CORSMiddleware, SecurityHeadersMiddleware, Response, StaticFiles, create_static_handler, PounceError, LifespanError, ReloadError, SupervisorError, TLSError, # Lifecycle events (new in 0.5) BufferedCollector, LoggingCollector, NoopCollector, ConnectionOpened, RequestStarted, ResponseCompleted, ClientDisconnected, ConnectionCompleted, LifecycleCollector, LifecycleEvent, ) pounce.run() Start a pounce server. def run(app: str | ASGIApp, **kwargs: Unpack[ServerConfigKwargs])...", "description": "Public API for the pounce package", "dir": "/docs/reference/", "excerpt": "Public API The pounce package exports the following: from pounce import ( run, ServerConfig, ASGIApp, Scope, Receive, Send, CORSMiddleware, SecurityHeadersMiddleware, Response, StaticFiles,...", "href": "/pounce/docs/reference/api/", "kind": "doc", "objectID": "/docs/reference/api/", "reading_time": 3, "section": "reference", "tags": ["api", "reference", "types"], "title": "API Reference", "type": "doc", "uri": "/docs/reference/api/", "url": "/pounce/docs/reference/api/", "weight": 10.0, "word_count": 517}, {"category": "reference", "content": "Error Hierarchy All pounce errors inherit from PounceError. Each error maps to an HTTP status code for automatic error response generation. flowchart TD Base[\"PounceError (500)\\nBase exception\"] Base --> ParseError[\"ParseError (400)\\nMalformed HTTP request\"] Base --> RequestTimeoutError[\"RequestTimeoutError (408)\\nRequest/keep-alive timeout\"] Base --> LimitError[\"LimitError (413/431)\\nSize limit exceeded\"] Base --> AppError[\"AppError (500)\\nUnhandled app exception\"] Base --> LifespanError[\"LifespanError (500)\\nLifespan startup/shutdown failure\"] Base --> SupervisorError[\"SupervisorError...", "description": "Pounce error hierarchy and common error messages", "dir": "/docs/reference/", "excerpt": "Error Hierarchy All pounce errors inherit from PounceError. Each error maps to an HTTP status code for automatic error response generation. flowchart TD Base[\"PounceError (500)\\nBase exception\"] Base...", "href": "/pounce/docs/reference/errors/", "kind": "doc", "objectID": "/docs/reference/errors/", "reading_time": 2, "section": "reference", "tags": ["errors", "exceptions", "reference"], "title": "Error Reference", "type": "doc", "uri": "/docs/reference/errors/", "url": "/pounce/docs/reference/errors/", "weight": 20.0, "word_count": 390}, {"category": "guide", "content": "Pounce ships a testing helper that starts a real server in a background thread. Use it when your test needs socket-level behavior instead of direct ASGI calls. Context Manager from pounce.testing import TestServer async def app(scope, receive, send): await send({\"type\": \"http.response.start\", \"status\": 200, \"headers\": []}) await send({\"type\": \"http.response.body\", \"body\": b\"ok\"}) def test_app(): with TestServer(app) as server: assert server.url.startswith(\"http://\") Pytest Fixture Installing bengal-pounce registers the pounce_server pytest fixture through the package entry point. def...", "description": "Run integration tests against a real Pounce server", "dir": "/docs/", "excerpt": "Pounce ships a testing helper that starts a real server in a background thread. Use it when your test needs socket-level behavior instead of direct ASGI calls. Context Manager from pounce.testing...", "href": "/pounce/docs/testing/", "kind": "doc", "objectID": "/docs/testing/", "reading_time": 1, "section": "testing", "tags": ["testing", "pytest", "integration"], "title": "Testing", "type": "doc", "uri": "/docs/testing/", "url": "/pounce/docs/testing/", "weight": 80.0, "word_count": 103}, {"category": "reference", "content": "Installation Issues pounce: command not found The pounce CLI is installed as a Python script. Ensure your Python scripts directory is on your PATH: # Check where pip installs scripts python -m site --user-base # The scripts directory is usually: # macOS/Linux: ~/.local/bin # Windows: %APPDATA%\\Python\\PythonXY\\Scripts requires Python >= 3.14 Pounce requires Python 3.14 or later. Check your version: python --version For free-threading support, you need a Python 3.14t build. Startup Issues Could not import module Ensure the module is importable from your current directory: # Verify the module...", "description": "Common issues and solutions", "dir": "/docs/", "excerpt": "Installation Issues pounce: command not found The pounce CLI is installed as a Python script. Ensure your Python scripts directory is on your PATH: # Check where pip installs scripts python -m site...", "href": "/pounce/docs/troubleshooting/", "kind": "doc", "objectID": "/docs/troubleshooting/", "reading_time": 2, "section": "troubleshooting", "tags": ["troubleshooting", "debugging", "errors"], "title": "Troubleshooting", "type": "doc", "uri": "/docs/troubleshooting/", "url": "/pounce/docs/troubleshooting/", "weight": 90.0, "word_count": 342}, {"category": "how-to", "content": "Migrate from Uvicorn Switch from Uvicorn to Pounce with minimal changes Side-by-side comparison and migration steps.", "description": "Step-by-step guides for common workflows and migrations", "dir": "/docs/", "excerpt": "Migrate from Uvicorn Switch from Uvicorn to Pounce with minimal changes Side-by-side comparison and migration steps.", "href": "/pounce/docs/tutorials/", "kind": "doc", "objectID": "/docs/tutorials/", "reading_time": 1, "section": "tutorials", "tags": ["tutorials", "guides", "migration"], "title": "Tutorials", "type": "doc", "uri": "/docs/tutorials/", "url": "/pounce/docs/tutorials/", "weight": 80.0, "word_count": 16}, {"category": "how-to", "content": "Overview If you're running an ASGI app with Uvicorn today, switching to Pounce is straightforward. The CLI syntax and configuration concepts are similar. CLI Comparison # Uvicorn uvicorn myapp:app --host 0.0.0.0 --port 8000 --workers 4 --reload # Pounce pounce serve --app myapp:app --host 0.0.0.0 --port 8000 --workers 4 --reload Flag Mapping Uvicorn Flag Pounce Equivalent Notes --host --host Same --port --port Same --workers --workers Pounce uses threads on 3.14t --reload --reload Built-in, no watchfiles needed --log-level --log-level Same levels --ssl-certfile --ssl-certfile Same...", "description": "Switch from Uvicorn to Pounce with minimal changes", "dir": "/docs/tutorials/", "excerpt": "Overview If you're running an ASGI app with Uvicorn today, switching to Pounce is straightforward. The CLI syntax and configuration concepts are similar. CLI Comparison # Uvicorn uvicorn myapp:app...", "href": "/pounce/docs/tutorials/migrate-from-uvicorn/", "kind": "doc", "objectID": "/docs/tutorials/migrate-from-uvicorn/", "reading_time": 2, "section": "tutorials", "tags": ["migration", "uvicorn", "tutorial"], "title": "Migrate from Uvicorn", "type": "doc", "uri": "/docs/tutorials/migrate-from-uvicorn/", "url": "/pounce/docs/tutorials/migrate-from-uvicorn/", "weight": 10.0, "word_count": 399}, {"category": "changelog", "content": "Release notes for Pounce. Each release includes highlights, new features, bug fixes, and breaking changes.", "description": "Pounce release notes and changelog", "dir": "/", "excerpt": "Release notes for Pounce. Each release includes highlights, new features, bug fixes, and breaking changes.", "href": "/pounce/releases/", "kind": "changelog", "objectID": "/releases/", "reading_time": 1, "section": "releases", "tags": ["releases", "changelog"], "title": "Releases", "type": "changelog", "uri": "/releases/", "url": "/pounce/releases/", "weight": 90.0, "word_count": 15}, {"category": "changelog", "content": "Highlights Free-threading native — Built for Python 3.14t (nogil); uses threads when GIL is disabled, processes when enabled Full protocol support — HTTP/1.1, HTTP/2, WebSocket, TLS termination Multi-worker — Auto-detects GIL state; scales across CPU cores with SO_REUSEPORT or shared sockets Dev workflow — --reload with file watcher, hot module reimport, app factory support Optional speed — pounce[fast] for C-accelerated HTTP parsing via httptools Protocol & Features HTTP/2 — ALPN negotiation, stream multiplexing, WebSocket over H2 (RFC 8441), priority signals (RFC 9218) WebSocket — Full ASGI...", "description": "Initial release — free-threading-native ASGI server with HTTP/2, WebSocket, TLS, and multi-worker", "dir": "/releases/", "excerpt": "Highlights Free-threading native — Built for Python 3.14t (nogil); uses threads when GIL is disabled, processes when enabled Full protocol support — HTTP/1.1, HTTP/2, WebSocket, TLS termination...", "href": "/pounce/releases/0.1.0/", "kind": "changelog", "objectID": "/releases/0.1.0/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.1.0", "type": "changelog", "uri": "/releases/0.1.0/", "url": "/pounce/releases/0.1.0/", "weight": 7.0, "word_count": 173}, {"category": "changelog", "content": "Highlights Security hardening — Proxy header validation, CRLF sanitization, slowloris protection, request smuggling prevention Static file serving — Pre-compressed files, ETags, range requests, chunked transfers Production observability — Built-in /health and /metrics endpoints, request IDs, OpenTelemetry, Sentry Graceful operations — Zero-downtime SIGHUP reload, connection draining for Kubernetes Developer experience — Rich error pages, hot reload, middleware system, WebSocket compression Security & Network Proxy header validation (trusted_hosts) — X-Forwarded-* only from trusted peers CRLF...", "description": "Production grade security, static files, observability, and developer experience", "dir": "/releases/", "excerpt": "Highlights Security hardening — Proxy header validation, CRLF sanitization, slowloris protection, request smuggling prevention Static file serving — Pre-compressed files, ETags, range requests,...", "href": "/pounce/releases/0.2.0/", "kind": "changelog", "objectID": "/releases/0.2.0/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.2.0", "type": "changelog", "uri": "/releases/0.2.0/", "url": "/pounce/releases/0.2.0/", "weight": 6.0, "word_count": 234}, {"category": "changelog", "content": "Highlights HTTP/3 backend: aioquic → zoomies — Replace aioquic with zoomies for HTTP/3 support. zoomies is sans-I/O, free-threading-native, and compatible with Python 3.14t. aioquic uses Limited API C extensions that do not work with free-threaded Python. Changed pounce[h3] now installs bengal-zoomies>=0.1.1 instead of aioquic>=1.3.0 0-RTT is disabled until zoomies exposes it Install uv add \"bengal-pounce==0.2.1\"", "description": "HTTP/3 backend switch to zoomies for free-threading compatibility", "dir": "/releases/", "excerpt": "Highlights HTTP/3 backend: aioquic → zoomies — Replace aioquic with zoomies for HTTP/3 support. zoomies is sans-I/O, free-threading-native, and compatible with Python 3.14t. aioquic uses Limited API...", "href": "/pounce/releases/0.2.1/", "kind": "changelog", "objectID": "/releases/0.2.1/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.2.1", "type": "changelog", "uri": "/releases/0.2.1/", "url": "/pounce/releases/0.2.1/", "weight": 5.0, "word_count": 55}, {"category": "changelog", "content": "Highlights Sync worker mode — Blocking I/O workers for request-response workloads. On Python 3.14t, runs in threads with true parallelism. No asyncio overhead for simple apps. Streaming and WebSocket hand off to an async pool. CPU affinity — Pin workers to cores on Linux for reduced cache thrashing. httptools removed — pounce[fast] extra removed. HTTP/1.1 is h11-only (pure Python, free-threading compatible). Added --worker-mode auto|sync|async — Choose worker execution model (default: auto) --cpu-affinity — Pin each worker to a CPU core (Linux only) Per-worker ThreadPoolExecutor to prevent...", "description": "Sync worker mode, CPU affinity, per-worker executor, httptools removed", "dir": "/releases/", "excerpt": "Highlights Sync worker mode — Blocking I/O workers for request-response workloads. On Python 3.14t, runs in threads with true parallelism. No asyncio overhead for simple apps. Streaming and WebSocket...", "href": "/pounce/releases/0.2.2/", "kind": "changelog", "objectID": "/releases/0.2.2/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.2.2", "type": "changelog", "uri": "/releases/0.2.2/", "url": "/pounce/releases/0.2.2/", "weight": 4.0, "word_count": 134}, {"category": "changelog", "content": "Highlights Fast HTTP/1.1 parser — Custom _fast_h1.py replaces h11 on the sync worker hot path. Direct bytes parsing was benchmarked against h11 on the parser microbenchmark, with tested checks for method validation, header size limits, null byte/control character injection rejection, duplicate Content-Length detection, and Content-Length/Transfer-Encoding ambiguity (RFC 7230 section 3.3.3). 30k req/s on pure Python — Sync worker throughput now matches uvicorn through fused parsing, shared request pipeline, and single-pass header scanning. Shared request pipeline — prepare_request(),...", "description": "Multi-worker sync performance — matching uvicorn at 30k req/s, pure Python", "dir": "/releases/", "excerpt": "Highlights Fast HTTP/1.1 parser — Custom _fast_h1.py replaces h11 on the sync worker hot path. Direct bytes parsing was benchmarked against h11 on the parser microbenchmark, with tested checks for...", "href": "/pounce/releases/0.3.0/", "kind": "changelog", "objectID": "/releases/0.3.0/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.3.0", "type": "changelog", "uri": "/releases/0.3.0/", "url": "/pounce/releases/0.3.0/", "weight": 3.0, "word_count": 229}, {"category": "changelog", "content": "Highlights Public error exports — PounceError, LifespanError, TLSError, SupervisorError, and ReloadError are now available from the top-level pounce package. Downstream packages like chirp no longer need to import from the private pounce._errors module. Added Re-export PounceError, LifespanError, TLSError, SupervisorError, ReloadError in pounce.__init__ and __all__ Install uv add \"bengal-pounce==0.3.1\"", "description": "Public error type exports for downstream consumers", "dir": "/releases/", "excerpt": "Highlights Public error exports — PounceError, LifespanError, TLSError, SupervisorError, and ReloadError are now available from the top-level pounce package. Downstream packages like chirp no longer...", "href": "/pounce/releases/0.3.1/", "kind": "changelog", "objectID": "/releases/0.3.1/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.3.1", "type": "changelog", "uri": "/releases/0.3.1/", "url": "/pounce/releases/0.3.1/", "weight": 2.0, "word_count": 48}, {"category": "changelog", "content": "Highlights First-class testing API — TestServer runs a real pounce server in a background thread. Use it as a context manager, async context manager, or via the auto-registered pounce_server pytest fixture. Ephemeral port binding, .url property, and reliable startup synchronization out of the box. Graceful shutdown overhaul — Per-worker parallel joins, bounded executor teardown, and connection draining with 503 responses during shutdown. Thread-safety fixes — Connection counter is now atomic under threading.Lock, and ASGI bridge header filtering is single-pass. Added pounce.testing.TestServer...", "description": "First-class testing API, graceful shutdown overhaul, thread-safety fixes", "dir": "/releases/", "excerpt": "Highlights First-class testing API — TestServer runs a real pounce server in a background thread. Use it as a context manager, async context manager, or via the auto-registered pounce_server pytest...", "href": "/pounce/releases/0.4.0/", "kind": "changelog", "objectID": "/releases/0.4.0/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.4.0", "type": "changelog", "uri": "/releases/0.4.0/", "url": "/pounce/releases/0.4.0/", "weight": 2.0, "word_count": 185}, {"category": "changelog", "content": "Highlights Elm Architecture lifecycle — Server lifecycle rebuilt on a Store + Reducer + Render Middleware pattern. All 16 procedural output functions replaced with typed action dispatch, giving pounce an inspectable state model and a single view layer. milo-cli adoption — argparse replaced with milo's CLI class. Subcommands, MCP server, llms.txt, and type-driven parsing out of the box. All lifecycle output rendered through branded kida templates. pounce bench — Built-in benchmarking command with wrk integration and formatted result tables. Modern Python 3.14t patterns — Final constants,...", "description": "Elm Architecture lifecycle, milo-cli adoption, bench command, modern Python 3.14t patterns", "dir": "/releases/", "excerpt": "Highlights Elm Architecture lifecycle — Server lifecycle rebuilt on a Store + Reducer + Render Middleware pattern. All 16 procedural output functions replaced with typed action dispatch, giving...", "href": "/pounce/releases/0.5.0/", "kind": "changelog", "objectID": "/releases/0.5.0/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.5.0", "type": "changelog", "uri": "/releases/0.5.0/", "url": "/pounce/releases/0.5.0/", "weight": 2.0, "word_count": 288}, {"category": "changelog", "content": "Highlights Fork context for process workers — Fixes startup failures on platforms that support the \"fork\" multiprocessing method when ASGI apps contain closures that cannot be pickled under the default \"spawn\" method. Pounce now explicitly uses the \"fork\" context so the app is inherited via the forked address space; on Windows, use thread workers instead of process workers. Changed Bump all runtime and dev dependencies to latest; adopt milo-cli 0.1.1 with --completions, --mcp, --verbose, --quiet, --no-color, --dry-run flags and PyPI version checking (#28) Flatten startup banner layout,...", "description": "Fork-context fix for process workers, dependency updates, startup banner redesign", "dir": "/releases/", "excerpt": "Highlights Fork context for process workers — Fixes startup failures on platforms that support the \"fork\" multiprocessing method when ASGI apps contain closures that cannot be pickled under the...", "href": "/pounce/releases/0.5.1/", "kind": "changelog", "objectID": "/releases/0.5.1/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.5.1", "type": "changelog", "uri": "/releases/0.5.1/", "url": "/pounce/releases/0.5.1/", "weight": 2.0, "word_count": 141}, {"category": "changelog", "content": "Highlights Subinterpreter workers — New --worker-mode subinterpreter option using Python 3.14's concurrent.interpreters (PEP 734). Thread-like performance with process-like isolation, all in one process. RFC 9842 Compression Dictionary Transport — Shared zstd dictionaries for dcz content-encoding, Available-Dictionary / Use-As-Dictionary header negotiation, and built-in dictionary serving at /.well-known/compression-dictionary/. Zero-copy sendfile — os.sendfile() for static file serving on non-TLS connections, plus RFC 7233 multipart range requests. TOML config — Load settings from...", "description": "Subinterpreter workers, RFC 9842 compression dictionaries, sendfile, framework compat tests, and 60+ fixes", "dir": "/releases/", "excerpt": "Highlights Subinterpreter workers — New --worker-mode subinterpreter option using Python 3.14's concurrent.interpreters (PEP 734). Thread-like performance with process-like isolation, all in one...", "href": "/pounce/releases/0.6.0/", "kind": "changelog", "objectID": "/releases/0.6.0/", "reading_time": 2, "section": "releases", "tags": ["release"], "title": "0.6.0", "type": "changelog", "uri": "/releases/0.6.0/", "url": "/pounce/releases/0.6.0/", "weight": 2.0, "word_count": 310}, {"category": "changelog", "content": "Highlights Protocol fail-closed behavior — HTTP/2 and HTTP/3 now reject oversized bodies and malformed pseudo-headers before apps can process empty, truncated, or ambiguous tenant-facing scopes. Config and operator UX — pounce config schema, pounce config show, pounce init, improved pounce check, and opt-in /_pounce/info make deployed configuration easier to inspect without leaking secrets. Production-shaped proof — Bengal static-site and Chirp/LB Sonic forum workloads are checked in as benchmark fixtures for representative static, tenant, form, SSE, and middleware behavior. Release-path...", "description": "Release-readiness hardening for protocols, config discovery, operator diagnostics, and production-shaped benchmark coverage", "dir": "/releases/", "excerpt": "Highlights Protocol fail-closed behavior — HTTP/2 and HTTP/3 now reject oversized bodies and malformed pseudo-headers before apps can process empty, truncated, or ambiguous tenant-facing scopes....", "href": "/pounce/releases/0.7.0/", "kind": "changelog", "objectID": "/releases/0.7.0/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.7.0", "type": "changelog", "uri": "/releases/0.7.0/", "url": "/pounce/releases/0.7.0/", "weight": 2.0, "word_count": 288}, {"category": "changelog", "content": "Highlights Protocol-owned sendfile — HTTP/1 static-file sendfile framing now stays under protocol ownership, aligning range responses, streaming fallbacks, and ASGI send completion behavior. Public-contract guardrails — API, config, CLI, docs, protocol status, and public claims now have stronger tests and ledgers to keep release wording tied to shipped behavior. Benchmark evidence — Checked-in Bengal and Chirp local benchmark artifacts record workload, command, platform, Python build, and caveats for performance-proof traceability. Release governance cleanup — Steward guidance, planning...", "description": "Patch release for HTTP/1 sendfile ownership, public-contract guardrails, and benchmark proof artifacts", "dir": "/releases/", "excerpt": "Highlights Protocol-owned sendfile — HTTP/1 static-file sendfile framing now stays under protocol ownership, aligning range responses, streaming fallbacks, and ASGI send completion behavior....", "href": "/pounce/releases/0.7.1/", "kind": "changelog", "objectID": "/releases/0.7.1/", "reading_time": 1, "section": "releases", "tags": ["release"], "title": "0.7.1", "type": "changelog", "uri": "/releases/0.7.1/", "url": "/pounce/releases/0.7.1/", "weight": 2.0, "word_count": 224}, {"category": "changelog", "content": "Highlights HTTP/3 reload & drain parity — graceful_reload now rotates HTTP/3 (QUIC) workers alongside TCP workers so the H3 generation picks up reimported app code, and HTTP/3 graceful shutdown drains in-flight stream tasks within shutdown_timeout instead of hard-cancelling them. Subinterpreter FD leak fixed — subinterpreter workers no longer leak the dup'd listener file descriptor on abnormal stop, and the supervisor reclaims FDs on crash-respawn and after force-stopping a non-draining old generation during reload, so repeated crashes/reloads no longer exhaust the FD budget. Shared request...", "description": "Patch release for HTTP/3 reload/drain parity, the subinterpreter FD leak fix, shared request-pipeline consolidation, and the drain benchmark profile", "dir": "/releases/", "excerpt": "Highlights HTTP/3 reload & drain parity — graceful_reload now rotates HTTP/3 (QUIC) workers alongside TCP workers so the H3 generation picks up reimported app code, and HTTP/3 graceful shutdown...", "href": "/pounce/releases/0.8.1/", "kind": "changelog", "objectID": "/releases/0.8.1/", "reading_time": 3, "section": "releases", "tags": ["release"], "title": "0.8.1", "type": "changelog", "uri": "/releases/0.8.1/", "url": "/pounce/releases/0.8.1/", "weight": 1.0, "word_count": 576}, {"description": "", "dir": "/", "excerpt": "", "href": "/pounce/tags/", "kind": "tag-index", "objectID": "/tags/", "reading_time": 1, "title": "All Tags", "type": "tag-index", "uri": "/tags/", "url": "/pounce/tags/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/about/", "kind": "tag", "objectID": "/tags/about/", "reading_time": 1, "title": "Posts tagged 'about'", "type": "tag", "uri": "/tags/about/", "url": "/pounce/tags/about/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/api/", "kind": "tag", "objectID": "/tags/api/", "reading_time": 1, "title": "Posts tagged 'api'", "type": "tag", "uri": "/tags/api/", "url": "/pounce/tags/api/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/architecture/", "kind": "tag", "objectID": "/tags/architecture/", "reading_time": 1, "title": "Posts tagged 'architecture'", "type": "tag", "uri": "/tags/architecture/", "url": "/pounce/tags/architecture/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/asgi/", "kind": "tag", "objectID": "/tags/asgi/", "reading_time": 1, "title": "Posts tagged 'asgi'", "type": "tag", "uri": "/tags/asgi/", "url": "/pounce/tags/asgi/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/backpressure/", "kind": "tag", "objectID": "/tags/backpressure/", "reading_time": 1, "title": "Posts tagged 'backpressure'", "type": "tag", "uri": "/tags/backpressure/", "url": "/pounce/tags/backpressure/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/bridge/", "kind": "tag", "objectID": "/tags/bridge/", "reading_time": 1, "title": "Posts tagged 'bridge'", "type": "tag", "uri": "/tags/bridge/", "url": "/pounce/tags/bridge/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/changelog/", "kind": "tag", "objectID": "/tags/changelog/", "reading_time": 1, "title": "Posts tagged 'changelog'", "type": "tag", "uri": "/tags/changelog/", "url": "/pounce/tags/changelog/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/cli/", "kind": "tag", "objectID": "/tags/cli/", "reading_time": 1, "title": "Posts tagged 'cli'", "type": "tag", "uri": "/tags/cli/", "url": "/pounce/tags/cli/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/command-line/", "kind": "tag", "objectID": "/tags/command-line/", "reading_time": 1, "title": "Posts tagged 'command-line'", "type": "tag", "uri": "/tags/command-line/", "url": "/pounce/tags/command-line/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/compression/", "kind": "tag", "objectID": "/tags/compression/", "reading_time": 1, "title": "Posts tagged 'compression'", "type": "tag", "uri": "/tags/compression/", "url": "/pounce/tags/compression/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/configuration/", "kind": "tag", "objectID": "/tags/configuration/", "reading_time": 1, "title": "Posts tagged 'configuration'", "type": "tag", "uri": "/tags/configuration/", "url": "/pounce/tags/configuration/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/dataclass/", "kind": "tag", "objectID": "/tags/dataclass/", "reading_time": 1, "title": "Posts tagged 'dataclass'", "type": "tag", "uri": "/tags/dataclass/", "url": "/pounce/tags/dataclass/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/debugging/", "kind": "tag", "objectID": "/tags/debugging/", "reading_time": 1, "title": "Posts tagged 'debugging'", "type": "tag", "uri": "/tags/debugging/", "url": "/pounce/tags/debugging/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/deployment/", "kind": "tag", "objectID": "/tags/deployment/", "reading_time": 1, "title": "Posts tagged 'deployment'", "type": "tag", "uri": "/tags/deployment/", "url": "/pounce/tags/deployment/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/design/", "kind": "tag", "objectID": "/tags/design/", "reading_time": 1, "title": "Posts tagged 'design'", "type": "tag", "uri": "/tags/design/", "url": "/pounce/tags/design/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/ecosystem/", "kind": "tag", "objectID": "/tags/ecosystem/", "reading_time": 1, "title": "Posts tagged 'ecosystem'", "type": "tag", "uri": "/tags/ecosystem/", "url": "/pounce/tags/ecosystem/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/encoding/", "kind": "tag", "objectID": "/tags/encoding/", "reading_time": 1, "title": "Posts tagged 'encoding'", "type": "tag", "uri": "/tags/encoding/", "url": "/pounce/tags/encoding/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/errors/", "kind": "tag", "objectID": "/tags/errors/", "reading_time": 1, "title": "Posts tagged 'errors'", "type": "tag", "uri": "/tags/errors/", "url": "/pounce/tags/errors/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/exceptions/", "kind": "tag", "objectID": "/tags/exceptions/", "reading_time": 1, "title": "Posts tagged 'exceptions'", "type": "tag", "uri": "/tags/exceptions/", "url": "/pounce/tags/exceptions/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/extending/", "kind": "tag", "objectID": "/tags/extending/", "reading_time": 1, "title": "Posts tagged 'extending'", "type": "tag", "uri": "/tags/extending/", "url": "/pounce/tags/extending/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/faq/", "kind": "tag", "objectID": "/tags/faq/", "reading_time": 1, "title": "Posts tagged 'faq'", "type": "tag", "uri": "/tags/faq/", "url": "/pounce/tags/faq/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/free-threading/", "kind": "tag", "objectID": "/tags/free-threading/", "reading_time": 1, "title": "Posts tagged 'free-threading'", "type": "tag", "uri": "/tags/free-threading/", "url": "/pounce/tags/free-threading/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/getting-started/", "kind": "tag", "objectID": "/tags/getting-started/", "reading_time": 1, "title": "Posts tagged 'getting-started'", "type": "tag", "uri": "/tags/getting-started/", "url": "/pounce/tags/getting-started/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/guides/", "kind": "tag", "objectID": "/tags/guides/", "reading_time": 1, "title": "Posts tagged 'guides'", "type": "tag", "uri": "/tags/guides/", "url": "/pounce/tags/guides/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/gzip/", "kind": "tag", "objectID": "/tags/gzip/", "reading_time": 1, "title": "Posts tagged 'gzip'", "type": "tag", "uri": "/tags/gzip/", "url": "/pounce/tags/gzip/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/h11/", "kind": "tag", "objectID": "/tags/h11/", "reading_time": 1, "title": "Posts tagged 'h11'", "type": "tag", "uri": "/tags/h11/", "url": "/pounce/tags/h11/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/h2/", "kind": "tag", "objectID": "/tags/h2/", "reading_time": 1, "title": "Posts tagged 'h2'", "type": "tag", "uri": "/tags/h2/", "url": "/pounce/tags/h2/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/hardening/", "kind": "tag", "objectID": "/tags/hardening/", "reading_time": 1, "title": "Posts tagged 'hardening'", "type": "tag", "uri": "/tags/hardening/", "url": "/pounce/tags/hardening/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/headers/", "kind": "tag", "objectID": "/tags/headers/", "reading_time": 1, "title": "Posts tagged 'headers'", "type": "tag", "uri": "/tags/headers/", "url": "/pounce/tags/headers/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/health-check/", "kind": "tag", "objectID": "/tags/health-check/", "reading_time": 1, "title": "Posts tagged 'health-check'", "type": "tag", "uri": "/tags/health-check/", "url": "/pounce/tags/health-check/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/health-checks/", "kind": "tag", "objectID": "/tags/health-checks/", "reading_time": 1, "title": "Posts tagged 'health-checks'", "type": "tag", "uri": "/tags/health-checks/", "url": "/pounce/tags/health-checks/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/http/", "kind": "tag", "objectID": "/tags/http/", "reading_time": 1, "title": "Posts tagged 'http'", "type": "tag", "uri": "/tags/http/", "url": "/pounce/tags/http/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/http2/", "kind": "tag", "objectID": "/tags/http2/", "reading_time": 1, "title": "Posts tagged 'http2'", "type": "tag", "uri": "/tags/http2/", "url": "/pounce/tags/http2/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/http3/", "kind": "tag", "objectID": "/tags/http3/", "reading_time": 1, "title": "Posts tagged 'http3'", "type": "tag", "uri": "/tags/http3/", "url": "/pounce/tags/http3/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/https/", "kind": "tag", "objectID": "/tags/https/", "reading_time": 1, "title": "Posts tagged 'https'", "type": "tag", "uri": "/tags/https/", "url": "/pounce/tags/https/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/installation/", "kind": "tag", "objectID": "/tags/installation/", "reading_time": 1, "title": "Posts tagged 'installation'", "type": "tag", "uri": "/tags/installation/", "url": "/pounce/tags/installation/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/integration/", "kind": "tag", "objectID": "/tags/integration/", "reading_time": 1, "title": "Posts tagged 'integration'", "type": "tag", "uri": "/tags/integration/", "url": "/pounce/tags/integration/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/internals/", "kind": "tag", "objectID": "/tags/internals/", "reading_time": 1, "title": "Posts tagged 'internals'", "type": "tag", "uri": "/tags/internals/", "url": "/pounce/tags/internals/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/introspection/", "kind": "tag", "objectID": "/tags/introspection/", "reading_time": 1, "title": "Posts tagged 'introspection'", "type": "tag", "uri": "/tags/introspection/", "url": "/pounce/tags/introspection/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/metrics/", "kind": "tag", "objectID": "/tags/metrics/", "reading_time": 1, "title": "Posts tagged 'metrics'", "type": "tag", "uri": "/tags/metrics/", "url": "/pounce/tags/metrics/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/migration/", "kind": "tag", "objectID": "/tags/migration/", "reading_time": 1, "title": "Posts tagged 'migration'", "type": "tag", "uri": "/tags/migration/", "url": "/pounce/tags/migration/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/multiplexing/", "kind": "tag", "objectID": "/tags/multiplexing/", "reading_time": 1, "title": "Posts tagged 'multiplexing'", "type": "tag", "uri": "/tags/multiplexing/", "url": "/pounce/tags/multiplexing/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/nogil/", "kind": "tag", "objectID": "/tags/nogil/", "reading_time": 1, "title": "Posts tagged 'nogil'", "type": "tag", "uri": "/tags/nogil/", "url": "/pounce/tags/nogil/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/observability/", "kind": "tag", "objectID": "/tags/observability/", "reading_time": 1, "title": "Posts tagged 'observability'", "type": "tag", "uri": "/tags/observability/", "url": "/pounce/tags/observability/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/opentelemetry/", "kind": "tag", "objectID": "/tags/opentelemetry/", "reading_time": 1, "title": "Posts tagged 'opentelemetry'", "type": "tag", "uri": "/tags/opentelemetry/", "url": "/pounce/tags/opentelemetry/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/parallelism/", "kind": "tag", "objectID": "/tags/parallelism/", "reading_time": 1, "title": "Posts tagged 'parallelism'", "type": "tag", "uri": "/tags/parallelism/", "url": "/pounce/tags/parallelism/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/performance/", "kind": "tag", "objectID": "/tags/performance/", "reading_time": 1, "title": "Posts tagged 'performance'", "type": "tag", "uri": "/tags/performance/", "url": "/pounce/tags/performance/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/processes/", "kind": "tag", "objectID": "/tags/processes/", "reading_time": 1, "title": "Posts tagged 'processes'", "type": "tag", "uri": "/tags/processes/", "url": "/pounce/tags/processes/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/production/", "kind": "tag", "objectID": "/tags/production/", "reading_time": 1, "title": "Posts tagged 'production'", "type": "tag", "uri": "/tags/production/", "url": "/pounce/tags/production/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/protocol/", "kind": "tag", "objectID": "/tags/protocol/", "reading_time": 1, "title": "Posts tagged 'protocol'", "type": "tag", "uri": "/tags/protocol/", "url": "/pounce/tags/protocol/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/protocols/", "kind": "tag", "objectID": "/tags/protocols/", "reading_time": 1, "title": "Posts tagged 'protocols'", "type": "tag", "uri": "/tags/protocols/", "url": "/pounce/tags/protocols/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/proxy/", "kind": "tag", "objectID": "/tags/proxy/", "reading_time": 1, "title": "Posts tagged 'proxy'", "type": "tag", "uri": "/tags/proxy/", "url": "/pounce/tags/proxy/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/pytest/", "kind": "tag", "objectID": "/tags/pytest/", "reading_time": 1, "title": "Posts tagged 'pytest'", "type": "tag", "uri": "/tags/pytest/", "url": "/pounce/tags/pytest/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/questions/", "kind": "tag", "objectID": "/tags/questions/", "reading_time": 1, "title": "Posts tagged 'questions'", "type": "tag", "uri": "/tags/questions/", "url": "/pounce/tags/questions/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/queueing/", "kind": "tag", "objectID": "/tags/queueing/", "reading_time": 1, "title": "Posts tagged 'queueing'", "type": "tag", "uri": "/tags/queueing/", "url": "/pounce/tags/queueing/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/quic/", "kind": "tag", "objectID": "/tags/quic/", "reading_time": 1, "title": "Posts tagged 'quic'", "type": "tag", "uri": "/tags/quic/", "url": "/pounce/tags/quic/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/quickstart/", "kind": "tag", "objectID": "/tags/quickstart/", "reading_time": 1, "title": "Posts tagged 'quickstart'", "type": "tag", "uri": "/tags/quickstart/", "url": "/pounce/tags/quickstart/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/railway/", "kind": "tag", "objectID": "/tags/railway/", "reading_time": 1, "title": "Posts tagged 'railway'", "type": "tag", "uri": "/tags/railway/", "url": "/pounce/tags/railway/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/rate-limiting/", "kind": "tag", "objectID": "/tags/rate-limiting/", "reading_time": 1, "title": "Posts tagged 'rate-limiting'", "type": "tag", "uri": "/tags/rate-limiting/", "url": "/pounce/tags/rate-limiting/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/realtime/", "kind": "tag", "objectID": "/tags/realtime/", "reading_time": 1, "title": "Posts tagged 'realtime'", "type": "tag", "uri": "/tags/realtime/", "url": "/pounce/tags/realtime/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/reference/", "kind": "tag", "objectID": "/tags/reference/", "reading_time": 1, "title": "Posts tagged 'reference'", "type": "tag", "uri": "/tags/reference/", "url": "/pounce/tags/reference/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/release/", "kind": "tag", "objectID": "/tags/release/", "reading_time": 1, "title": "Posts tagged 'release'", "type": "tag", "uri": "/tags/release/", "url": "/pounce/tags/release/", "word_count": 0}, {"description": "", "dir": "/tags/release/page/", "excerpt": "", "href": "/pounce/tags/release/page/2/", "kind": "tag", "objectID": "/tags/release/page/2/", "reading_time": 1, "title": "Posts tagged 'release'", "type": "tag", "uri": "/tags/release/page/2/", "url": "/pounce/tags/release/page/2/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/releases/", "kind": "tag", "objectID": "/tags/releases/", "reading_time": 1, "title": "Posts tagged 'releases'", "type": "tag", "uri": "/tags/releases/", "url": "/pounce/tags/releases/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/reload/", "kind": "tag", "objectID": "/tags/reload/", "reading_time": 1, "title": "Posts tagged 'reload'", "type": "tag", "uri": "/tags/reload/", "url": "/pounce/tags/reload/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/rolling-reload/", "kind": "tag", "objectID": "/tags/rolling-reload/", "reading_time": 1, "title": "Posts tagged 'rolling-reload'", "type": "tag", "uri": "/tags/rolling-reload/", "url": "/pounce/tags/rolling-reload/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/scaling/", "kind": "tag", "objectID": "/tags/scaling/", "reading_time": 1, "title": "Posts tagged 'scaling'", "type": "tag", "uri": "/tags/scaling/", "url": "/pounce/tags/scaling/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/security/", "kind": "tag", "objectID": "/tags/security/", "reading_time": 1, "title": "Posts tagged 'security'", "type": "tag", "uri": "/tags/security/", "url": "/pounce/tags/security/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/sentry/", "kind": "tag", "objectID": "/tags/sentry/", "reading_time": 1, "title": "Posts tagged 'sentry'", "type": "tag", "uri": "/tags/sentry/", "url": "/pounce/tags/sentry/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/serverconfig/", "kind": "tag", "objectID": "/tags/serverconfig/", "reading_time": 1, "title": "Posts tagged 'serverconfig'", "type": "tag", "uri": "/tags/serverconfig/", "url": "/pounce/tags/serverconfig/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/settings/", "kind": "tag", "objectID": "/tags/settings/", "reading_time": 1, "title": "Posts tagged 'settings'", "type": "tag", "uri": "/tags/settings/", "url": "/pounce/tags/settings/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/setup/", "kind": "tag", "objectID": "/tags/setup/", "reading_time": 1, "title": "Posts tagged 'setup'", "type": "tag", "uri": "/tags/setup/", "url": "/pounce/tags/setup/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/shutdown/", "kind": "tag", "objectID": "/tags/shutdown/", "reading_time": 1, "title": "Posts tagged 'shutdown'", "type": "tag", "uri": "/tags/shutdown/", "url": "/pounce/tags/shutdown/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/ssl/", "kind": "tag", "objectID": "/tags/ssl/", "reading_time": 1, "title": "Posts tagged 'ssl'", "type": "tag", "uri": "/tags/ssl/", "url": "/pounce/tags/ssl/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/streaming/", "kind": "tag", "objectID": "/tags/streaming/", "reading_time": 1, "title": "Posts tagged 'streaming'", "type": "tag", "uri": "/tags/streaming/", "url": "/pounce/tags/streaming/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/testing/", "kind": "tag", "objectID": "/tags/testing/", "reading_time": 1, "title": "Posts tagged 'testing'", "type": "tag", "uri": "/tags/testing/", "url": "/pounce/tags/testing/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/thread-safety/", "kind": "tag", "objectID": "/tags/thread-safety/", "reading_time": 1, "title": "Posts tagged 'thread-safety'", "type": "tag", "uri": "/tags/thread-safety/", "url": "/pounce/tags/thread-safety/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/threading/", "kind": "tag", "objectID": "/tags/threading/", "reading_time": 1, "title": "Posts tagged 'threading'", "type": "tag", "uri": "/tags/threading/", "url": "/pounce/tags/threading/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/tls/", "kind": "tag", "objectID": "/tags/tls/", "reading_time": 1, "title": "Posts tagged 'tls'", "type": "tag", "uri": "/tags/tls/", "url": "/pounce/tags/tls/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/tracing/", "kind": "tag", "objectID": "/tags/tracing/", "reading_time": 1, "title": "Posts tagged 'tracing'", "type": "tag", "uri": "/tags/tracing/", "url": "/pounce/tags/tracing/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/troubleshooting/", "kind": "tag", "objectID": "/tags/troubleshooting/", "reading_time": 1, "title": "Posts tagged 'troubleshooting'", "type": "tag", "uri": "/tags/troubleshooting/", "url": "/pounce/tags/troubleshooting/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/tutorial/", "kind": "tag", "objectID": "/tags/tutorial/", "reading_time": 1, "title": "Posts tagged 'tutorial'", "type": "tag", "uri": "/tags/tutorial/", "url": "/pounce/tags/tutorial/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/tutorials/", "kind": "tag", "objectID": "/tags/tutorials/", "reading_time": 1, "title": "Posts tagged 'tutorials'", "type": "tag", "uri": "/tags/tutorials/", "url": "/pounce/tags/tutorials/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/types/", "kind": "tag", "objectID": "/tags/types/", "reading_time": 1, "title": "Posts tagged 'types'", "type": "tag", "uri": "/tags/types/", "url": "/pounce/tags/types/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/uvicorn/", "kind": "tag", "objectID": "/tags/uvicorn/", "reading_time": 1, "title": "Posts tagged 'uvicorn'", "type": "tag", "uri": "/tags/uvicorn/", "url": "/pounce/tags/uvicorn/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/websocket/", "kind": "tag", "objectID": "/tags/websocket/", "reading_time": 1, "title": "Posts tagged 'websocket'", "type": "tag", "uri": "/tags/websocket/", "url": "/pounce/tags/websocket/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/workers/", "kind": "tag", "objectID": "/tags/workers/", "reading_time": 1, "title": "Posts tagged 'workers'", "type": "tag", "uri": "/tags/workers/", "url": "/pounce/tags/workers/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/wsproto/", "kind": "tag", "objectID": "/tags/wsproto/", "reading_time": 1, "title": "Posts tagged 'wsproto'", "type": "tag", "uri": "/tags/wsproto/", "url": "/pounce/tags/wsproto/", "word_count": 0}, {"description": "", "dir": "/tags/", "excerpt": "", "href": "/pounce/tags/zstd/", "kind": "tag", "objectID": "/tags/zstd/", "reading_time": 1, "title": "Posts tagged 'zstd'", "type": "tag", "uri": "/tags/zstd/", "url": "/pounce/tags/zstd/", "word_count": 0}], "sections": [{"count": 8, "name": "about"}, {"count": 59, "name": "api"}, {"count": 8, "name": "asgi"}, {"count": 5, "name": "configuration"}, {"count": 9, "name": "deployment"}, {"count": 1, "name": "docs"}, {"count": 2, "name": "extending"}, {"count": 6, "name": "features"}, {"count": 3, "name": "get-started"}, {"count": 3, "name": "net"}, {"count": 11, "name": "protocols"}, {"count": 3, "name": "reference"}, {"count": 14, "name": "releases"}, {"count": 1, "name": "testing"}, {"count": 1, "name": "troubleshooting"}, {"count": 2, "name": "tutorials"}], "site": {"baseurl": "/pounce", "build_time": "2026-06-18T02:06:41.517860", "description": "A free-threading-native ASGI server for Python 3.14t", "title": "Pounce"}, "tags": [{"count": 13, "name": "release"}, {"count": 6, "name": "deployment"}, {"count": 4, "name": "reference"}, {"count": 3, "name": "architecture"}, {"count": 3, "name": "internals"}, {"count": 3, "name": "tls"}, {"count": 3, "name": "security"}, {"count": 3, "name": "production"}, {"count": 3, "name": "protocol"}, {"count": 3, "name": "errors"}, {"count": 2, "name": "design"}, {"count": 2, "name": "about"}, {"count": 2, "name": "configuration"}, {"count": 2, "name": "cli"}, {"count": 2, "name": "workers"}, {"count": 2, "name": "compression"}, {"count": 2, "name": "observability"}, {"count": 2, "name": "hardening"}, {"count": 2, "name": "asgi"}, {"count": 2, "name": "bridge"}, {"count": 2, "name": "installation"}, {"count": 2, "name": "quickstart"}, {"count": 2, "name": "tutorial"}, {"count": 2, "name": "protocols"}, {"count": 2, "name": "http"}, {"count": 2, "name": "websocket"}, {"count": 2, "name": "api"}, {"count": 2, "name": "migration"}, {"count": 1, "name": "ecosystem"}, {"count": 1, "name": "faq"}, {"count": 1, "name": "questions"}, {"count": 1, "name": "performance"}, {"count": 1, "name": "streaming"}, {"count": 1, "name": "thread-safety"}, {"count": 1, "name": "free-threading"}, {"count": 1, "name": "nogil"}, {"count": 1, "name": "settings"}, {"count": 1, "name": "command-line"}, {"count": 1, "name": "serverconfig"}, {"count": 1, "name": "dataclass"}, {"count": 1, "name": "ssl"}, {"count": 1, "name": "https"}, {"count": 1, "name": "rate-limiting"}, {"count": 1, "name": "queueing"}, {"count": 1, "name": "backpressure"}, {"count": 1, "name": "zstd"}, {"count": 1, "name": "gzip"}, {"count": 1, "name": "encoding"}, {"count": 1, "name": "reload"}, {"count": 1, "name": "shutdown"}, {"count": 1, "name": "rolling-reload"}, {"count": 1, "name": "health-check"}, {"count": 1, "name": "metrics"}, {"count": 1, "name": "tracing"}, {"count": 1, "name": "opentelemetry"}, {"count": 1, "name": "sentry"}, {"count": 1, "name": "introspection"}, {"count": 1, "name": "scaling"}, {"count": 1, "name": "railway"}, {"count": 1, "name": "health-checks"}, {"count": 1, "name": "proxy"}, {"count": 1, "name": "headers"}, {"count": 1, "name": "threading"}, {"count": 1, "name": "processes"}, {"count": 1, "name": "parallelism"}, {"count": 1, "name": "extending"}, {"count": 1, "name": "getting-started"}, {"count": 1, "name": "setup"}, {"count": 1, "name": "h11"}, {"count": 1, "name": "http2"}, {"count": 1, "name": "h2"}, {"count": 1, "name": "multiplexing"}, {"count": 1, "name": "http3"}, {"count": 1, "name": "quic"}, {"count": 1, "name": "wsproto"}, {"count": 1, "name": "realtime"}, {"count": 1, "name": "types"}, {"count": 1, "name": "exceptions"}, {"count": 1, "name": "testing"}, {"count": 1, "name": "pytest"}, {"count": 1, "name": "integration"}, {"count": 1, "name": "troubleshooting"}, {"count": 1, "name": "debugging"}, {"count": 1, "name": "tutorials"}, {"count": 1, "name": "guides"}, {"count": 1, "name": "uvicorn"}, {"count": 1, "name": "releases"}, {"count": 1, "name": "changelog"}]}