Skip to main content

⟢⟣ Zoomies

PyPI version Build Status Python 3.14+ License: MIT Status: Beta

Free-threading-native QUIC and HTTP/3 for Python 3.14t — sans-I/O, typed

Using zoomies from an AI agent (or moving fast)? See CLAUDE.md for a concise library-user guide: mental model, timing contract, event cheatsheet, and foot-guns.

import time
from zoomies.core import QuicConnection, QuicConfiguration
from zoomies.events import HandshakeComplete

config = QuicConfiguration(certificate=cert, private_key=key)
conn = QuicConnection(config)

# Sans-I/O: feed datagrams in, get events out
now = time.monotonic()
events = conn.datagram_received(datagram, addr, now=now)
for event in events:
    if isinstance(event, HandshakeComplete):
        ...
for dg in conn.send_datagrams(now=now):
    sock.sendto(dg, addr)

What is Zoomies?

Zoomies is a sans-I/O protocol library for QUIC (RFC 9000) and HTTP/3 (RFC 9114). Native to the b-stack (Pounce, Chirp), it has no b-stack dependencies and works anywhere — pure Python, cryptography only, free-threaded Python 3.14t. Alpha: full TLS 1.3 handshake, 1-RTT packets, loss recovery (RFC 9002), and congestion control.

What's good about it:

  • Sans-I/O — Protocol layer consumes bytes, produces bytes. No socket access. Caller owns I/O.
  • Types as contracts — Frozen dataclasses for events, Protocols for handlers.
  • Free-threading native — No C extensions with limited API. Uses cryptography (3.14t-compatible).
  • Composition — Packet → Crypto → Stream → Connection → Recovery → HTTP/3. Each layer testable in isolation.
  • Loss recovery — RFC 9002 loss detection, RTT estimation, NewReno congestion control. Built into the connection layer.

What it does

API Description
QuicConnection.datagram_received(data, addr, now=) Feed UDP datagram in, get protocol events
QuicConnection.send_datagrams(now=) Get outbound datagrams to transmit
QuicConnection.send_stream_data(stream_id, data, end_stream) Queue application data on a QUIC stream
QuicConnection.get_timer() Next deadline for handle_timer() (see Timer Integration)
QuicConnection.handle_timer(now) Process timer expiry (idle timeout, PTO retransmission)
QuicConnection.connect() Client: generate Initial packet with ClientHello
QuicConnection.close() Send CONNECTION_CLOSE and shut down
H3Connection.handle_event(event) Process QUIC events into HTTP/3 events
encode_headers / decode_headers QPACK header compression
pull_quic_header() Parse QUIC packet headers (Initial, Handshake, etc.)
zoomies.recovery Loss detection, RTT estimation, congestion control (RFC 9002)

Key events: HandshakeComplete, StreamDataReceived, ConnectionClosed, NewSessionTicket, ZeroRttAccepted, ZeroRttRejected, PacketDropped, DecryptionFailed


Installation

pip install zoomies

Requires Python 3.14+


Quick Start

QPACK encode/decode

from zoomies.h3 import Header, decode_headers, encode_headers

headers = [
    Header(name=":method", value="GET"),
    Header(name=":path", value="/api/users"),
    Header(name=":scheme", value="https"),
]
encoded = encode_headers(headers)
decoded = decode_headers(encoded)

Parse QUIC Initial packet

from zoomies.encoding import Buffer
from zoomies.packet import pull_quic_header

buf = Buffer(data=raw_bytes)
header = pull_quic_header(buf, host_cid_length=None)
print(f"Version: {header.version:#x}, CID: {header.destination_cid}")

Sans-I/O connection (server)

import time
from zoomies.core import QuicConnection, QuicConfiguration
from zoomies.events import HandshakeComplete

with open("cert.pem", "rb") as f:
    cert = f.read()
with open("key.pem", "rb") as f:
    key = f.read()
config = QuicConfiguration(certificate=cert, private_key=key)
conn = QuicConnection(config)

now = time.monotonic()
events = conn.datagram_received(datagram, addr, now=now)
for event in events:
    if isinstance(event, HandshakeComplete):
        print("Handshake done!")
for dg in conn.send_datagrams(now=now):
    sock.sendto(dg, addr)

Sans-I/O connection (client)

import time
from zoomies.core import QuicConnection, QuicConfiguration

config = QuicConfiguration(is_client=True, verify_mode=False)  # test only — use ca_certs in production
conn = QuicConnection(config)
conn.connect()

now = time.monotonic()
for dg in conn.send_datagrams(now=now):
    sock.sendto(dg, server_addr)

Timer integration (required for production use)

Zoomies is sans-I/O: the library never sleeps. You must drive the timer by polling get_timer() and calling handle_timer() when the deadline passes. Without this, idle timeouts and PTO retransmissions won't fire.

import time

while True:
    now = time.monotonic()
    # 1. Process incoming datagrams
    for dg in receive_from_socket():
        events = conn.datagram_received(dg, addr, now=now)
        handle_events(events)

    # 2. Send outbound datagrams
    for dg in conn.send_datagrams(now=now):
        sock.sendto(dg, addr)

    # 3. Drive the timer — this is what makes idle_timeout and PTO work
    deadline = conn.get_timer()
    if deadline is not None and now >= deadline:
        events = conn.handle_timer(now)
        handle_events(events)

See examples/realistic_server.py for a complete select()-based implementation.

0-RTT early data (TLS resumption)

After a first connection, capture the session ticket and reuse it to send data before the handshake completes on reconnection:

from zoomies.events import NewSessionTicket, ZeroRttAccepted, ZeroRttRejected

# 1. First connection: capture the session ticket
for event in events:
    if isinstance(event, NewSessionTicket):
        stored_ticket = event.ticket  # save externally (file, DB, etc.)

# 2. Reconnect with the ticket
config = QuicConfiguration(is_client=True, session_ticket=stored_ticket, ...)
conn = QuicConnection(config)
conn.connect()

# 3. Queue data immediately (sent as 0-RTT before handshake completes)
conn.send_stream_data(stream_id=0, data=b"early request", end_stream=True)

# 4. Check if the server accepted 0-RTT
for event in events:
    if isinstance(event, ZeroRttAccepted):
        pass  # early data was accepted
    elif isinstance(event, ZeroRttRejected):
        pass  # resend data — it will go as 1-RTT after handshake

See examples/zero_rtt_resumption.py for the full end-to-end flow.

Run the examples (from repo root):

uv run python -m examples.qpack_roundtrip
uv run python -m examples.parse_initial_packet
uv run python -m examples.sans_io_connection
uv run python -m examples.client_server

Examples

Example Description
examples/qpack_roundtrip.py QPACK header encode/decode
examples/parse_initial_packet.py Parse QUIC Initial packet header
examples/sans_io_connection.py Sans-I/O QuicConnection demo (uses test fixtures)
examples/stream_echo.py Stream reassembly, RTT estimation, congestion control, loss detection, PTO timer loop
examples/client_server.py HTTP/3 GET request/response over loopback (client + server in one process)

Usage

Events — Frozen dataclasses for protocol state changes
from zoomies.events import (
    HandshakeComplete,
    StreamDataReceived,
    StreamReset,
    ConnectionClosed,
)

for event in conn.datagram_received(datagram, addr):
    match event:
        case HandshakeComplete():
            ...
        case StreamDataReceived(stream_id=sid, data=data):
            ...
        case StreamReset(stream_id=sid, error_code=code):
            ...
        case ConnectionClosed():
            ...
HTTP/3 — H3Connection for request/response
from zoomies.h3 import H3Connection
from zoomies.events import H3HeadersReceived, H3DataReceived

# Wrap a QuicConnection to add HTTP/3 framing
h3 = H3Connection(sender=quic_conn)

# Client: send request
h3.send_headers(stream_id=0, headers=[
    (b":method", b"GET"), (b":path", b"/"),
    (b":scheme", b"https"), (b":authority", b"localhost"),
], end_stream=True)

# Server: process QUIC events through H3
for quic_event in events:
    for h3_event in h3.handle_event(quic_event):
        match h3_event:
            case H3HeadersReceived(headers=hdrs):
                ...
            case H3DataReceived(data=body):
                ...
Free-threading — Python 3.14t

Zoomies uses frozen dataclasses, no shared mutable state, and cryptography (3.14t-compatible). Safe to run multiple QuicConnection instances from different threads.


Development

git clone https://github.com/lbliii/zoomies.git
cd zoomies
uv sync --group dev
pytest

Lint and types:

ruff check src tests
ty check

Related: The Bengal Ecosystem

Zoomies is developed as part of the b-stack but is standalone. No imports from Bengal, Chirp, or Pounce. A structured reactive stack — every layer written in pure Python for 3.14t free-threading.

ᓚᘏᗢ Bengal Static site generator Docs
∿∿ Purr Content runtime —
⌁⌁ Chirp Web framework Docs
=^..^= Pounce ASGI server Docs
)彡 Kida Template engine Docs
ฅᨐฅ Patitas Markdown parser Docs
⌾⌾⌾ Rosettes Syntax highlighter Docs
⟢⟣ Zoomies QUIC/HTTP/3 ← You are here —

Python-native. Free-threading ready. No npm required.


License

MIT License — see LICENSE for details.

Metadata

Release files for bengal-zoomies 0.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bengal-zoomies 0.3.3
File Size Uploaded
bengal_zoomies-0.3.3.tar.gz 133.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bengal-zoomies 0.3.3
File Interpreter ABI Platform
bengal_zoomies-0.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 219.3 kB

Release files / bengal_zoomies-0.3.3.tar.gz

Download URL bengal_zoomies-0.3.3.tar.gz
Size 133.7 kB
Tags Source
SHA-256 checksum
How to use checksums
7ba3184c0fa99bf6da4a1a38de3216054f98f5a79ecb4acd3c254d41d9804c48
BLAKE2b-256 checksum
How to use checksums
957309f126ee92e1ba9a193c1309f5df01ce3156ce7a8d75a3e385fefeb1e76f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Apr 21, 2026.

Transparency log

Release files / bengal_zoomies-0.3.3-py3-none-any.whl

Download URL bengal_zoomies-0.3.3-py3-none-any.whl
Size 85.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e99849ec8ef4d0e86461213619a2705b588ac3f5946b880e9e6ae2c1ab9b6e91
BLAKE2b-256 checksum
How to use checksums
297d431f386febf15c0182bd65d71ab873c7f982d6293bdf49ce5afcc7ed5070
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Apr 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.3 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page