Skip to main content

aiopquic - Async QUIC + WebTransport (picoquic)

aiopquic is a Python/Cython binding to picoquic, providing high-performance QUIC transport and WebTransport for asyncio applications.

Overview

aiopquic exposes picoquic's QUIC implementation through a lock-free SPSC ring buffer architecture that bridges the picoquic network thread with Python's asyncio event loop. It provides an asyncio QUIC/HTTP3 transport API in the spirit of aioquic (and its fork qh3) — similar shapes for QuicConfiguration, QuicConnection, connect / serve, and event types — plus a native WebTransport client/server layered on picoquic's H3 + h3zero. Not a drop-in replacement: semantics differ around backpressure (send_stream_data raises BufferError on full per-stream ring) and flow-control sizing.

Architecture

  • SPSC Ring Buffers -- Lock-free single producer/single consumer rings for event passing between threads, separate TX and RX rings per TransportContext.
  • TX path -- Asyncio pushes into per-stream byte ring; picoquic pulls at wire rate via prepare_to_send.
  • RX path -- picoquic pushes per-event StreamChunks; ownership transfers at pop for 1-copy delivery.
  • Cross-platform wake fd -- Linux eventfd for efficient asyncio add_reader() notification; pipe() self-pipe fallback on macOS / BSD.
  • Dedicated Network Thread -- picoquic runs in its own thread via picoquic_start_network_thread(). One worker thread per TransportContext; multiple contexts share the asyncio event loop within a single Python process.
  • Cython Bridge -- Thin Cython layer over C callbacks, minimal overhead.
  • WebTransport -- asyncio.webtransport.WebTransportSession (client + server) over picoquic's picowt_* API and h3zero.

Features

  • QUIC client and server: connect, serve, QuicConnectionProtocol
  • Stream data send/receive with FIN signaling, stream reset, stop_sending
  • WebTransport client + server: serve_webtransport, WebTransportSession
  • QUIC and WebTransport datagram TX + RX
  • Connection migration / 0-RTT (inherited from picoquic)
  • Connection management: create, close, idle timeout, application close codes
  • Per-cnx multiplexing on the server side via QuicEngine
  • TLS keylog (NSS Key Log Format) for pcap decryption
  • Native picoquic_ct / picohttp_ct subprocess smoke (catches upstream regressions on every submodule update)

Performance

Multi-Gbps sustained throughput over loopback on commodity hardware: 2+ Gbps through the full asyncio API at the QUIC default MTU (where the kernel's sendmsg syscall rate is the wall), 11+ Gbps protocol-only. Numbers, methodology, reproduction commands, build flags, and runtime tuning (jemalloc, GSO, wake thresholds) live in PERFORMANCE.md. The TX/RX dataflow and flow-control model — including the TX backpressure configuration parameters — are documented in DATAFLOW.md.

Installation

Wheels for cp312 / cp313 / cp314 on Linux (manylinux_2_34, glibc 2.34+) and macOS arm64 are published to PyPI:

uv pip install aiopquic     # or: pip install aiopquic

For older Linux (glibc 2.28–2.33) install via sdist; build toolchain required.

From source

git clone https://github.com/gmarzot/aiopquic.git
cd aiopquic
./bootstrap_python.sh    # creates .venv with uv-managed Python 3.14 (GIL build) and pins cython 3.2+
source .venv/bin/activate
./build.sh               # reconcile submodules, build picotls/picoquic + drivers, relink + verify
uv pip install -e '.[dev]'    # add dev/test extras — or: pip install -e '.[dev]'

Re-run ./build.sh after any git checkout or submodule bump — it is idempotent (a matching fingerprint skips the compile) and guarantees the imported aiopquic reflects the current source, host-tuned. ./build.sh --check is a read-only doctor that reports submodule drift, a stale native build, or a portable wheel shadowing the editable install, and exits nonzero — handy as a pre-benchmark or CI gate.

On macOS, set OPENSSL_ROOT_DIR if Homebrew OpenSSL is not auto-detected (the build script tries openssl@3 then openssl@1.1).

Reporting issues

Include the full version report in any issue — it captures aiopquic plus the picoquic + picotls submodule SHAs the binding was built from:

python -m aiopquic.versions   # or the console script: aiopquic-versions

Sample output:

aiopquic:  0.3.7.dev12+g6eef9caf6 (~/Projects/moq/aiopquic/src/aiopquic) [2026-06-12 08:55]
  - picoquic:  1.1.49.2 (d6c5653d) [2026-06-05]
  - picotls:   master (bfa67875) [2026-04-20]

If you're running aiomoqt on top, prefer python -m aiomoqt.versions — it chains through to this report and includes the aiomoqt version too.

Usage

Low-level Transport API

from aiopquic._binding._transport import TransportContext

server = TransportContext()
server.start(port=4433, cert_file="cert.pem", key_file="key.pem", alpn="moq-00", is_client=False)

client = TransportContext()
client.start(port=0, alpn="moq-00", is_client=True)
client.create_client_connection("127.0.0.1", 4433, sni="localhost", alpn="moq-00")

Asyncio API

from aiopquic.asyncio.client import connect
from aiopquic.quic.configuration import QuicConfiguration

configuration = QuicConfiguration(alpn_protocols=["myproto"], is_client=True)

async with connect("server", 4433, configuration=configuration) as protocol:
    quic = protocol._quic
    stream_id = quic.get_next_available_stream_id()
    quic.send_stream_data(stream_id, payload, end_stream=True)

payload is opaque bytes; the library doesn't impose framing. Consumers that want HTTP/3 layer on top of aiopquic's picowt-backed h3zero plumbing; consumers that want WebTransport use serve_webtransport / connect_webtransport. Most direct users of the asyncio API ship their own protocol bytes (MoQT, custom binary frames, etc.).

Clients verify the server's certificate chain and name against certifi's roots. A private CA goes in QuicConfiguration.cafile (or load_verify_locations(cafile=...)), and connect_webtransport(ca_file=...) takes the same file. To accept any certificate, such as a self-signed test server, set verify_mode=ssl.CERT_NONE or pass connect_webtransport(verify_peer=False). Clients offer a classic key share first; QuicConfiguration.key_exchange_groups (or start(key_exchange_groups=...)) puts KEX_X25519MLKEM768 first for a post-quantum key exchange with servers that support it.

WebTransport

from aiopquic.asyncio.webtransport import (
    serve_webtransport, WebTransportSession,
)
# See src/aiopquic/asyncio/webtransport.py and tests/ for full examples.

Development

uv pip install -e '.[dev]'    # or: pip install -e '.[dev]'
python -m pytest tests/ -v -m "not interop and not native"

# Microbenches (opt-in)
python -m pytest tests/bench

Test-suite coverage, benchmark methodology, performance builds (AIOPQUIC_PERF=1, io_uring scaffolding), and runtime tuning are documented in PERFORMANCE.md.

Known Limitations

  • Free-threaded Python (3.14t) not yet supported -- the TX-ring producer side, TransportContext lifecycle, and the WebTransport engine state currently rely on the GIL for serialization. FT support deferred until a per-context locking audit lands.

TODO

  • Windows support (eventfd alternative — IOCP / WSAEventSelect on the wake-fd path)
  • Free-threaded Python (3.14t) support after producer-side locking audit
  • Datagram benches: latency percentiles, payload-size sweep, loss / jitter under load (today's bench_datagram is fire-and-count throughput only)
  • Pure stream open/close microbench (lifecycle rate without payload, separate from bench_stream_churn_highlevel which bundles writes + FIN)
  • Submit aiopquic to the QUIC interop runner for cross-implementation coverage

Resources



A Marz Research project.
Author: G. S. Marzot <gmarzot@marzresearch.net>

License

MIT License -- see LICENSE

Metadata

Release files for aiopquic 0.5.0

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

Source distribution (sdist)

Source distribution for aiopquic 0.5.0
File Size Uploaded Provenance
aiopquic-0.5.0.tar.gz 3.7 MB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for aiopquic 0.5.0
File
aiopquic-0.5.0-cp314-cp314-manylinux_2_34_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.34+ x86-64 Details
aiopquic-0.5.0-cp314-cp314-manylinux_2_34_aarch64.whl CPython 3.14 CPython 3.14 Linux glibc 2.34+ ARM64 Details
aiopquic-0.5.0-cp314-cp314-macosx_14_0_arm64.whl CPython 3.14 CPython 3.14 macOS 14.0+ ARM64 Details
aiopquic-0.5.0-cp313-cp313-manylinux_2_34_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.34+ x86-64 Details
aiopquic-0.5.0-cp313-cp313-manylinux_2_34_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.34+ ARM64 Details
aiopquic-0.5.0-cp313-cp313-macosx_14_0_arm64.whl CPython 3.13 CPython 3.13 macOS 14.0+ ARM64 Details
aiopquic-0.5.0-cp312-cp312-manylinux_2_34_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.34+ x86-64 Details
aiopquic-0.5.0-cp312-cp312-manylinux_2_34_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.34+ ARM64 Details
aiopquic-0.5.0-cp312-cp312-macosx_14_0_arm64.whl CPython 3.12 CPython 3.12 macOS 14.0+ ARM64 Details

Total release size: 48.9 MB

Release files / aiopquic-0.5.0.tar.gz

Download URL aiopquic-0.5.0.tar.gz
Size 3.7 MB
Tags Source
SHA-256 checksum
How to use checksums
7e2041b438e456e037adbb89110d784a6faafe6a12c8698450a0c40a8e94f4ef
BLAKE2b-256 checksum
How to use checksums
7f9a70e914a1ddceaae6e63c62184ee5ce59daf5e9a0b76fdd9cdc44a2c4ad6f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp314-cp314-manylinux_2_34_x86_64.whl

Download URL aiopquic-0.5.0-cp314-cp314-manylinux_2_34_x86_64.whl
Size 5.6 MB
Tags CPython 3.14 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
6acfb48c50f5a990c3404c26a39765c57e449b619cb66d76d5e1b224c6299674
BLAKE2b-256 checksum
How to use checksums
9daf8f98e4d57819a89ec7627795e900df6ffad400c87ccb8fb567182c12b46b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp314-cp314-manylinux_2_34_aarch64.whl

Download URL aiopquic-0.5.0-cp314-cp314-manylinux_2_34_aarch64.whl
Size 5.3 MB
Tags CPython 3.14 Linux glibc 2.34+ ARM64
SHA-256 checksum
How to use checksums
f1767d1c79d4390ebe15ba95338cc0789078a80aa2a8d8c512b6429fe3a26800
BLAKE2b-256 checksum
How to use checksums
3c734bd569f5e8472c5d03c41eedfc08e7654164f1bbf8ed8382261a1e6ed46a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp314-cp314-macosx_14_0_arm64.whl

Download URL aiopquic-0.5.0-cp314-cp314-macosx_14_0_arm64.whl
Size 4.2 MB
Tags CPython 3.14 macOS 14.0+ ARM64
SHA-256 checksum
How to use checksums
975c445eddcdddd0305baa06c2a5bed4433a491a31e561ebea529c2349e24bed
BLAKE2b-256 checksum
How to use checksums
86856699c4bf521a88dd8fac2762de19c4a7b923086a3d80b833b598c33c74d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp313-cp313-manylinux_2_34_x86_64.whl

Download URL aiopquic-0.5.0-cp313-cp313-manylinux_2_34_x86_64.whl
Size 5.6 MB
Tags CPython 3.13 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
3278cadecba1811d6587efa8c26af0e5de59203c59ea03dfb6a7163719e08fd1
BLAKE2b-256 checksum
How to use checksums
332362c9b21c90cf2d0c4d2ef91a041c1ad843562acdea8872549faacf51d2c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp313-cp313-manylinux_2_34_aarch64.whl

Download URL aiopquic-0.5.0-cp313-cp313-manylinux_2_34_aarch64.whl
Size 5.3 MB
Tags CPython 3.13 Linux glibc 2.34+ ARM64
SHA-256 checksum
How to use checksums
a7967df7ff3036f15d7e83db1dae570c82a933841ecb936c8bee5a51e14a26c3
BLAKE2b-256 checksum
How to use checksums
69b2c08d9ea6327814b31e77d24d8db9dec80b0338e607bdb7d3f458d4b7b29b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp313-cp313-macosx_14_0_arm64.whl

Download URL aiopquic-0.5.0-cp313-cp313-macosx_14_0_arm64.whl
Size 4.2 MB
Tags CPython 3.13 macOS 14.0+ ARM64
SHA-256 checksum
How to use checksums
93220fb695b40bdf348699827403883c6e7cea7be84525eb7529506a72b37872
BLAKE2b-256 checksum
How to use checksums
6e60bd11df208e1ffb81a217a849aee13327bf5357b4d640f374d07567772cee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp312-cp312-manylinux_2_34_x86_64.whl

Download URL aiopquic-0.5.0-cp312-cp312-manylinux_2_34_x86_64.whl
Size 5.6 MB
Tags CPython 3.12 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
64aa9d5642b0a4f8cba7d5fe170aa1cc3322f857171aba0b68af0d7eb7a52deb
BLAKE2b-256 checksum
How to use checksums
ba5bc9a9c62d93f1a90cabd16d486292d458911bc40bdef547337288152a4ba8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp312-cp312-manylinux_2_34_aarch64.whl

Download URL aiopquic-0.5.0-cp312-cp312-manylinux_2_34_aarch64.whl
Size 5.3 MB
Tags CPython 3.12 Linux glibc 2.34+ ARM64
SHA-256 checksum
How to use checksums
b38d0a2a7040922c42bc4510cc82245cd87c9ad9bdb26613ffc77f522e172966
BLAKE2b-256 checksum
How to use checksums
be7e20312c84bc4d9ec8472a692d414dc05b17ec09aa66ea0a7c096129c309ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / aiopquic-0.5.0-cp312-cp312-macosx_14_0_arm64.whl

Download URL aiopquic-0.5.0-cp312-cp312-macosx_14_0_arm64.whl
Size 4.2 MB
Tags CPython 3.12 macOS 14.0+ ARM64
SHA-256 checksum
How to use checksums
077f324dfa9a8b7bcf58573f3fc5eebca387a2996adad10ca23a5939a3f6f878
BLAKE2b-256 checksum
How to use checksums
764bd4fd454fe8e0d6970022c11acebfc6f38bf5a7b9db384c0fc78511569846
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Security for aiopquic 0.5.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.5.0 This release

10 release files No provenance

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