{"id":44150449,"url":"https://github.com/lbliii/pounce","last_synced_at":"2026-04-01T20:04:08.222Z","repository":{"id":337091668,"uuid":"1152291289","full_name":"lbliii/pounce","owner":"lbliii","description":"=^..^= Pounce — Free-threading-native ASGI server for Python 3.14+ with real thread parallelism and streaming-first I/O","archived":false,"fork":false,"pushed_at":"2026-03-26T16:22:55.000Z","size":1084,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-26T17:46:56.197Z","etag":null,"topics":["asgi","free-threading","http","nogil","python","server"],"latest_commit_sha":null,"homepage":"https://lbliii.github.io/pounce/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lbliii.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-07T16:56:27.000Z","updated_at":"2026-03-26T16:23:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lbliii/pounce","commit_stats":null,"previous_names":["lbliii/pounce"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/lbliii/pounce","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fpounce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fpounce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fpounce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fpounce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lbliii","download_url":"https://codeload.github.com/lbliii/pounce/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbliii%2Fpounce/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291363,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asgi","free-threading","http","nogil","python","server"],"created_at":"2026-02-09T03:15:29.737Z","updated_at":"2026-04-01T20:04:08.214Z","avatar_url":"https://github.com/lbliii.png","language":"Python","readme":"# =^..^= Pounce\n\n[![PyPI version](https://img.shields.io/pypi/v/bengal-pounce.svg)](https://pypi.org/project/bengal-pounce/)\n[![Build Status](https://github.com/lbliii/pounce/actions/workflows/ci.yml/badge.svg)](https://github.com/lbliii/pounce/actions/workflows/ci.yml)\n[![Python 3.14+](https://img.shields.io/badge/python-3.14+-blue.svg)](https://pypi.org/project/bengal-pounce/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Status: Beta](https://img.shields.io/badge/status-beta-yellow.svg)](https://pypi.org/project/bengal-pounce/)\n\n**A Python ASGI server for production apps, streaming responses, and free-threaded Python.**\n\n```python\nimport pounce\n\npounce.run(\"myapp:app\")\n```\n\n---\n\n## What is Pounce?\n\nPounce is a Python ASGI server for Python 3.14+, with a worker model designed for\nfree-threaded Python 3.14t. It runs standard ASGI applications, supports streaming\nresponses, and gives you a clear upgrade path from process-based servers such as\nUvicorn.\n\nOn Python 3.14t, worker threads share one interpreter and one copy of your app. On GIL\nbuilds, Pounce falls back to multi-process workers automatically.\n\n**Why people pick it:**\n\n- **ASGI-first** — Runs standard ASGI apps with CLI and programmatic entry points\n- **Free-threading ready** — Threads, not processes, on Python 3.14t\n- **Streaming-first** — Chunked HTML, event streams, and token streaming without buffering\n- **Four protocols** — HTTP/1.1, HTTP/2, HTTP/3 (QUIC), and WebSocket (including WS over H2)\n- **Batteries included** — TLS, compression, static files, middleware, rate limiting, observability\n- **Migration path** — Familiar CLI for teams moving from Uvicorn-style deployments\n\n## Use Pounce For\n\n- **Serving ASGI apps** — Tunable workers, TLS, graceful shutdown, and deployment controls\n- **Free-threaded Python deployments** — Shared-memory worker threads on Python 3.14t\n- **Streaming workloads** — Server-sent events, streamed HTML, and token-by-token responses\n- **Teams migrating from Uvicorn** — Similar CLI shape with a different worker model\n\n---\n\n## Performance\n\nPounce matches uvicorn on multi-worker throughput — pure Python, no C extensions.\n\n| Scenario | Pounce | Uvicorn | Notes |\n|----------|--------|---------|-------|\n| 1 worker | ~12k req/s | ~12k req/s | Async event loop, h11 parser |\n| 4 workers (threads) | ~30k req/s | ~30k req/s | Linear scaling on Python 3.14t |\n\n*Measured with `wrk -t4 -c100 -d10s` on macOS, plain-text \"hello world\" ASGI app.*\n\nKey optimizations in the sync worker path:\n- **Fast HTTP/1.1 parser** — Direct bytes parsing (~3 µs/req) replaces h11 (~22 µs/req) with full safety checks (method validation, header size limits, request smuggling detection)\n- **Keep-alive connections** — Connection reuse eliminates TCP handshake overhead\n- **Shared socket distribution** — Single accept queue for thread workers avoids macOS SO_REUSEPORT limitations\n\n---\n\n## Installation\n\n```bash\npip install bengal-pounce\n```\n\nRequires Python 3.14+\n\n**Optional extras:**\n\n```bash\npip install bengal-pounce[h2]     # HTTP/2 stream multiplexing\npip install bengal-pounce[ws]     # WebSocket via wsproto\npip install bengal-pounce[tls]    # TLS with truststore\npip install bengal-pounce[h3]     # HTTP/3 (QUIC/UDP, requires TLS)\npip install bengal-pounce[full]   # All protocol extras\n```\n\n---\n\n## Quick Start\n\n| Usage | Command |\n|-------|---------|\n| **Programmatic** | `pounce.run(\"myapp:app\")` |\n| **CLI** | `pounce myapp:app` |\n| **Multi-worker** | `pounce myapp:app --workers 4` |\n| **TLS** | `pounce myapp:app --ssl-certfile cert.pem --ssl-keyfile key.pem` |\n| **HTTP/3** | `pounce myapp:app --http3 --ssl-certfile cert.pem --ssl-keyfile key.pem` |\n| **Dev reload** | `pounce myapp:app --reload` |\n| **App factory** | `pounce myapp:create_app()` |\n| **Testing** | `with TestServer(app) as server: ...` |\n\n---\n\n## Features\n\n| Feature | Description | Docs |\n|---------|-------------|------|\n| **Deployment** | Production workers, compression, observability, and shutdown behavior | [Deployment →](https://lbliii.github.io/pounce/docs/deployment/) |\n| **Migration** | Move from Uvicorn with similar CLI concepts | [Migrate from Uvicorn →](https://lbliii.github.io/pounce/docs/tutorials/migrate-from-uvicorn/) |\n| **HTTP/1.1** | h11 (async) + fast built-in parser (sync) | [HTTP/1.1 →](https://lbliii.github.io/pounce/docs/protocols/http1/) |\n| **HTTP/2** | Stream multiplexing via h2 | [HTTP/2 →](https://lbliii.github.io/pounce/docs/protocols/http2/) |\n| **HTTP/3** | QUIC/UDP via bengal-zoomies (requires TLS) | [HTTP/3 →](docs/design/http3-roadmap.md) |\n| **WebSocket** | Full RFC 6455 via wsproto (including WS over H2) | [WebSocket →](https://lbliii.github.io/pounce/docs/protocols/websocket/) |\n| **Static Files** | Pre-compressed files, ETags, range requests | [Static Files →](docs/features/) |\n| **Middleware** | ASGI3 middleware stack support | [Middleware →](docs/features/) |\n| **OpenTelemetry** | Native distributed tracing (OTLP) | [OpenTelemetry →](docs/deployment/opentelemetry.md) |\n| **Lifecycle Logging** | Structured JSON event logging | [Logging →](docs/features/lifecycle-logging.md) |\n| **Graceful Shutdown** | Kubernetes-ready connection draining | [Shutdown →](docs/deployment/graceful-shutdown.md) |\n| **Dev Error Pages** | Rich tracebacks with syntax highlighting | [Errors →](docs/development/error-pages.md) |\n| **TLS** | SSL with truststore integration | [TLS →](https://lbliii.github.io/pounce/docs/configuration/tls/) |\n| **Compression** | zstd (stdlib PEP 784) + gzip + WS compression | [Compression →](https://lbliii.github.io/pounce/docs/deployment/compression/) |\n| **Workers** | Auto-detect: threads (3.14t) or processes (GIL) | [Workers →](https://lbliii.github.io/pounce/docs/deployment/workers/) |\n| **Auto Reload** | Graceful restart on file changes | [Reload →](docs/deployment/graceful-reload.md) |\n| **Rate Limiting** | Per-IP token bucket with 429 responses | [Rate Limiting →](docs/deployment/rate-limiting.md) |\n| **Request Queueing** | Bounded queue with 503 load shedding | [Request Queueing →](docs/deployment/request-queueing.md) |\n| **Prometheus** | Built-in `/metrics` endpoint | [Metrics →](docs/deployment/prometheus-metrics.md) |\n| **Sentry** | Error tracking and performance monitoring | [Sentry →](docs/deployment/sentry.md) |\n| **Testing** | `TestServer` + pytest fixture for integration tests | [Testing →](https://lbliii.github.io/pounce/docs/testing/) |\n\n📚 **Full documentation**: [lbliii.github.io/pounce](https://lbliii.github.io/pounce/) | **[Complete Feature List →](docs/FEATURES.md)**\n\n---\n\n## Usage\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eProgrammatic Configuration\u003c/strong\u003e — Full control from Python\u003c/summary\u003e\n\n```python\nimport pounce\n\npounce.run(\n    \"myapp:app\",\n    host=\"0.0.0.0\",\n    port=8000,\n    workers=4,\n)\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHow It Works\u003c/strong\u003e — Adaptive worker model\u003c/summary\u003e\n\nOn **Python 3.14t** (free-threading): workers are threads. One process, N threads, each with\nits own asyncio event loop. Shared memory, no fork overhead, no IPC.\n\nOn **GIL builds**: workers are processes. Same API, same config. The supervisor detects the\nruntime via `sys._is_gil_enabled()` and adapts automatically.\n\nA request flows through: socket accept -\u003e protocol parser -\u003e ASGI scope\nconstruction -\u003e `app(scope, receive, send)` -\u003e response serialization -\u003e socket write.\nAsync workers use h11; sync workers use a fast built-in parser for lower latency.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eProtocol Extras\u003c/strong\u003e — Install only what you need\u003c/summary\u003e\n\n| Protocol | Backend | Install |\n|----------|---------|---------|\n| HTTP/1.1 | h11 (async) / fast built-in parser (sync) | built-in |\n| HTTP/2 | h2 (stream multiplexing, priority signals) | `pounce[h2]` |\n| WebSocket | wsproto (including WS over H2) | `pounce[ws]` |\n| TLS | stdlib ssl + truststore | `pounce[tls]` |\n| All | Everything above | `pounce[full]` |\n\nCompression uses Python 3.14's stdlib `compression.zstd` — zero external dependencies.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eTesting\u003c/strong\u003e — Real server for integration tests\u003c/summary\u003e\n\n```python\nfrom pounce.testing import TestServer\nimport httpx\n\ndef test_homepage(my_app):\n    with TestServer(my_app) as server:\n        resp = httpx.get(f\"{server.url}/\")\n        assert resp.status_code == 200\n```\n\nThe `pounce_server` pytest fixture is auto-registered when pounce is installed:\n\n```python\ndef test_api(pounce_server, my_app):\n    server = pounce_server(my_app)\n    resp = httpx.get(f\"{server.url}/health\")\n    assert resp.status_code == 200\n```\n\n\u003c/details\u003e\n\n---\n\n## Key Ideas\n\n- **Free-threading first.** Threads, not processes. One interpreter, N event loops, shared\n  immutable state. On GIL builds, falls back to multi-process automatically.\n- **Pure Python.** No Rust, no C extensions in the server core. Debuggable, hackable,\n  readable.\n- **Typed end-to-end.** Frozen config, typed ASGI definitions, zero `type: ignore` comments.\n- **One dependency.** `h11` for HTTP/1.1 parsing. Everything else is optional.\n- **Observable.** Structured lifecycle events — frozen dataclasses with nanosecond timestamps.\n  Zero overhead when no collector is attached.\n- **Chirp companion.** Built to serve Chirp apps natively, but works with any ASGI framework.\n- **Batteries included.** Static files, middleware, rate limiting, request queueing,\n  Prometheus metrics, Sentry, and OpenTelemetry — all built in, all optional.\n\n---\n\n## Documentation\n\n📚 **[lbliii.github.io/pounce](https://lbliii.github.io/pounce/)**\n\n| Section | Description |\n|---------|-------------|\n| [Get Started](https://lbliii.github.io/pounce/docs/get-started/) | Installation and quickstart |\n| [Protocols](https://lbliii.github.io/pounce/docs/protocols/) | HTTP/1.1, HTTP/2, WebSocket |\n| [Configuration](https://lbliii.github.io/pounce/docs/configuration/) | Server config, TLS, CLI |\n| [Deployment](https://lbliii.github.io/pounce/docs/deployment/) | Workers, compression, production |\n| [Extending](https://lbliii.github.io/pounce/docs/extending/) | ASGI bridge, custom protocols |\n| [Tutorials](https://lbliii.github.io/pounce/docs/tutorials/) | Uvicorn migration guide |\n| [Troubleshooting](https://lbliii.github.io/pounce/docs/troubleshooting/) | Common issues and fixes |\n| [Reference](https://lbliii.github.io/pounce/docs/reference/) | API documentation |\n| [About](https://lbliii.github.io/pounce/docs/about/) | Architecture, performance, FAQ |\n\n---\n\n## Development\n\n```bash\ngit clone https://github.com/lbliii/pounce.git\ncd pounce\nuv sync --group dev\npytest\n```\n\n---\n\n## The Bengal Ecosystem\n\nA structured reactive stack — every layer written in pure Python for 3.14t free-threading.\n\n| | | | |\n|--:|---|---|---|\n| **ᓚᘏᗢ** | [Bengal](https://github.com/lbliii/bengal) | Static site generator | [Docs](https://lbliii.github.io/bengal/) |\n| **∿∿** | [Purr](https://github.com/lbliii/purr) | Content runtime | — |\n| **⌁⌁** | [Chirp](https://github.com/lbliii/chirp) | Web framework | [Docs](https://lbliii.github.io/chirp/) |\n| **=^..^=** | **Pounce** | ASGI server ← You are here | [Docs](https://lbliii.github.io/pounce/) |\n| **)彡** | [Kida](https://github.com/lbliii/kida) | Template engine | [Docs](https://lbliii.github.io/kida/) |\n| **ฅᨐฅ** | [Patitas](https://github.com/lbliii/patitas) | Markdown parser | [Docs](https://lbliii.github.io/patitas/) |\n| **⌾⌾⌾** | [Rosettes](https://github.com/lbliii/rosettes) | Syntax highlighter | [Docs](https://lbliii.github.io/rosettes/) |\n\nPython-native. Free-threading ready. No npm required.\n\n---\n\n## License\n\nMIT\n","funding_links":[],"categories":["Http servers"],"sub_categories":["More"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flbliii%2Fpounce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flbliii%2Fpounce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flbliii%2Fpounce/lists"}