punkasgi
punkasgi is an ASGI server for the TonIO runtime, built on top of HTTPunk.
Warning: punkasgi is in an early stage and still work in progress.
Note: punkasgi was built with substantial help from LLMs, under human supervision.
In a nutshell
- HTTP/1.0, HTTP/1.1 and HTTP/2 (prior knowledge on plain TCP, ALPN over TLS), with
every protocol behaviour coming from httpunk: keep-alive, head timeouts, framing,
Dateheaders, graceful shutdown - WebSockets over HTTP/1.1 through the sans-io
websocketsimplementation, with keepalive pings, per-message deflate and thewebsocket.http.responseextension - The ASGI 3 protocol handling (scope contents,
receive()/send()semantics, lifespan, websocket messages) follows uvicorn - Single process architecture: the TonIO runtime's threads are the workers
Installation
pip install punkasgi
punkasgi needs a free-threaded CPython 3.14 or later, as tonio does. The standard extra
adds python-dotenv (for --env-file) and PyYAML (for YAML logging configurations).
Quickstart
# main.py
async def app(scope, receive, send):
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, world!"})
punkasgi main:app
Or programmatically:
import punkasgi
punkasgi.run("main:app", host="0.0.0.0", port=8000, threads=4)
punkasgi --help lists every option. The ones worth knowing:
| option | note |
|---|---|
--threads |
size of the tonio runtime, defaults to $WEB_CONCURRENCY or the CPU count |
--http auto|h1|h2 |
protocol selection: auto sniffs the HTTP/2 preface on plain TCP and follows ALPN over TLS |
--ws/--no-ws |
WebSocket upgrades on or off; with them off an upgrade request is answered 400 |
--timeout-keep-alive |
hyper's head read timeout: it bounds the idle wait between requests together with the read of the next request head |
--timeout-graceful-shutdown |
how long a shutdown waits for in-flight requests; unset waits without a deadline |
--proxy-headers |
trust X-Forwarded-For / X-Forwarded-Proto from --forwarded-allow-ips; off by default |
--access-log |
one punkasgi.access line per response; off by default |
A first SIGINT or SIGTERM starts a graceful shutdown; a second SIGINT leaves at once
with whatever is still in flight. Environment variables use the PUNKASGI_ prefix (e.g.
PUNKASGI_PORT), loggers are punkasgi.error, punkasgi.access and punkasgi.asgi,
and the default server header is punkasgi.
Behaviours worth knowing
These follow httpunk, and through it hyper, rather than any other server:
- Unread request bodies. After a response completes, a request body the application left unread is drained only if it is already buffered; otherwise the connection closes instead of being reused for the next request.
- Response
content-length. punkasgi does not check the body against the declared length. On HTTP/1 a body shorter than declared fails the response and closes the connection, and a longer one is cut at the declared length; on HTTP/2 the frames go out as sent. Dateheader. Always written, on both protocols.
License
punkasgi is released under the BSD-3-Clause license.
Metadata
Release files for punkasgi 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| punkasgi-0.1.1.tar.gz | 42.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| punkasgi-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 83.6 kB
Release files / punkasgi-0.1.1.tar.gz
| Download URL | punkasgi-0.1.1.tar.gz |
|---|---|
| Size | 42.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
893d171f065076ec611374d6c15900ec794b23af648c5b033b36723f340ef797
|
|
BLAKE2b-256 checksum How to use checksums |
55ac1148a5b5ca0859105ae1f692654dcfce94a104a003a66db96f10fb75b7dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / punkasgi-0.1.1-py3-none-any.whl
| Download URL | punkasgi-0.1.1-py3-none-any.whl |
|---|---|
| Size | 40.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bb13716f3268cffacba5dba817c2ddc7548e1b12c29eeb9ddea72a13dcf60d14
|
|
BLAKE2b-256 checksum How to use checksums |
560cc54e115613da1a56e37d208894a9ec099ec47afdf31c991b2ed70da5c20d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log