An async-native WebTransport stack for Python.
Project description
Features
- Pure Async: Built entirely on
asynciofor high-concurrency, non-blocking I/O operations. - Event Architecture: Powered by a Sans-I/O unified state machine and a strictly typed
EventEmitter. - Zero-Copy I/O: End-to-end support for
memoryviewand buffer protocols to minimize data copying overhead. - Structured Messaging: Transmission of typed Python objects via pluggable serializers (
JSON,MsgPack,Protobuf). - High-Level Abstractions:
ServerAppwith routing and middleware, plusWebTransportClientutilities for fleet management. - Protocol Completeness: Implementation of bidirectional streams, unidirectional streams, and unreliable datagrams.
- Resource Safety: Async context managers for automatic connection, session, and stream lifecycle management.
- Type-Safe & Tested: Fully type-annotated API with comprehensive unit, integration, end-to-end, and benchmark coverage.
Installation
pip install pywebtransport
Quick Start
Server
import asyncio
from pywebtransport import Event, ServerApp, ServerConfig, WebTransportSession, WebTransportStream
from pywebtransport.types import EventType
from pywebtransport.utils import generate_self_signed_cert
generate_self_signed_cert(hostname="localhost")
app = ServerApp(
config=ServerConfig(
certfile="localhost.crt",
keyfile="localhost.key",
initial_max_data=1024 * 1024,
initial_max_streams_bidi=10,
)
)
@app.route(path="/")
async def echo_handler(session: WebTransportSession) -> None:
async def on_datagram(event: Event) -> None:
if isinstance(event.data, dict):
payload = event.data.get("data")
if payload:
await session.send_datagram(data=b"ECHO: " + payload)
async def on_stream(event: Event) -> None:
if isinstance(event.data, dict):
stream = event.data.get("stream")
if isinstance(stream, WebTransportStream):
asyncio.create_task(handle_stream(stream))
session.events.on(event_type=EventType.DATAGRAM_RECEIVED, handler=on_datagram)
session.events.on(event_type=EventType.STREAM_OPENED, handler=on_stream)
try:
await session.events.wait_for(event_type=EventType.SESSION_CLOSED)
finally:
session.events.off(event_type=EventType.DATAGRAM_RECEIVED, handler=on_datagram)
session.events.off(event_type=EventType.STREAM_OPENED, handler=on_stream)
async def handle_stream(stream: WebTransportStream) -> None:
try:
data = await stream.read_all()
await stream.write_all(data=b"ECHO: " + data)
except Exception:
pass
if __name__ == "__main__":
app.run(host="127.0.0.1", port=4433)
Client
import asyncio
import ssl
from pywebtransport import ClientConfig, WebTransportClient
from pywebtransport.types import EventType
async def main() -> None:
config = ClientConfig(
verify_mode=ssl.CERT_NONE,
initial_max_data=1024 * 1024,
initial_max_streams_bidi=10,
)
async with WebTransportClient(config=config) as client:
session = await client.connect(url="https://127.0.0.1:4433/")
await session.send_datagram(data=b"Hello, Datagram!")
event = await session.events.wait_for(event_type=EventType.DATAGRAM_RECEIVED, timeout=5.0)
if isinstance(event.data, dict):
print(f"Datagram: {event.data.get('data')!r}")
stream = await session.create_bidirectional_stream()
await stream.write_all(data=b"Hello, Stream!")
response = await stream.read_all()
print(f"Stream: {response!r}")
await session.close()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
pass
Interoperability
- Public Endpoint:
https://interop.pywebtransport.org- /echo: Bidirectional stream and datagram reflection.
- /status: Global server health and aggregate metrics.
- /stats: Current session statistics and negotiated parameters.
Documentation
- API Reference - Explore the complete API documentation.
Requirements
- Python 3.12+
- TLS 1.3
Contributing
Contributions are welcome! Please read our Contributing Guide for details on the development setup, testing, and pull request process.
Sponsors
Acknowledgments
- aioquic for the underlying QUIC protocol implementation.
- WebTransport Working Group for defining and standardizing the WebTransport protocol.
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: lemonsterfy@gmail.com
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
pywebtransport-0.10.1.tar.gz
(110.2 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pywebtransport-0.10.1.tar.gz.
File metadata
- Download URL: pywebtransport-0.10.1.tar.gz
- Upload date:
- Size: 110.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.2 cpython/3.12.12 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1131f0e5658db0b3646723c58b9eb3bca65fa7e49eb53cbf6452eaee8d80cd02
|
|
| MD5 |
55f58fec03337d9b1b5b136b1870eb00
|
|
| BLAKE2b-256 |
aa282014c2b3786ec2fef89eabfb42751fb36e62d7399cc17b2420c405d82d02
|
File details
Details for the file pywebtransport-0.10.1-py3-none-any.whl.
File metadata
- Download URL: pywebtransport-0.10.1-py3-none-any.whl
- Upload date:
- Size: 122.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.2 cpython/3.12.12 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
307dab85d4b486aa59446816a1be03d82d5ae8a27089d052d1e0e43ccdfa0aa8
|
|
| MD5 |
950c62026e4640ad04ecbba0ec3c62c7
|
|
| BLAKE2b-256 |
da8a566432051be99c002bb921ee203efba43fd99e924d922d329014ea20ed31
|