https://github.com/wtransport/pywebtransport
An async-native WebTransport stack for Python.
https://github.com/wtransport/pywebtransport
async http3 networking protocol python quic webtransport
Last synced: about 6 hours ago
JSON representation
An async-native WebTransport stack for Python.
- Host: GitHub
- URL: https://github.com/wtransport/pywebtransport
- Owner: wtransport
- License: apache-2.0
- Created: 2025-06-25T13:07:36.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-12-30T20:40:00.000Z (about 1 month ago)
- Last Synced: 2026-01-03T19:10:38.936Z (about 1 month ago)
- Topics: async, http3, networking, protocol, python, quic, webtransport
- Language: Python
- Homepage: https://python.wtransport.org
- Size: 2.44 MB
- Stars: 24
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
- Authors: AUTHORS
- Notice: NOTICE
Awesome Lists containing this project
README
# PyWebTransport
_An async-native WebTransport stack for Python_
[](https://pypi.org/project/pywebtransport/)
[](https://pypi.org/project/pywebtransport/)
[](https://opensource.org/licenses/Apache-2.0)
[](https://github.com/wtransport/pywebtransport/actions/workflows/ci.yml)
[](https://codecov.io/gh/wtransport/pywebtransport)
[](https://python.wtransport.org/)
## Features
- **Sans-I/O Architecture**: Powered by an ownership-driven Rust state machine decoupled from the I/O runtime.
- **Transport Primitives**: Full implementation of bidirectional streams, unidirectional streams, and unreliable datagrams.
- **Structured Concurrency**: Deterministic lifecycle management for connections and streams via asynchronous context managers.
- **Zero-Copy I/O**: End-to-end support for buffer protocols and `memoryview` to minimize data copying overhead.
- **Typed Messaging**: Integrated transmission of Python objects via pluggable serializers (`JSON`, `MsgPack`, `Protobuf`).
- **Application Framework**: Includes `ServerApp` with routing and middleware, plus a composable client suite for connection resilience and fleet management.
## Installation
```bash
pip install pywebtransport
```
## Quick Start
### Server
```python
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"))
@app.route(path="/")
async def echo_handler(session: WebTransportSession) -> None:
async def on_datagram(event: Event) -> None:
if isinstance(event.data, dict) and (data := event.data.get("data")):
await session.send_datagram(data=b"ECHO: " + data)
async def on_stream(event: Event) -> None:
if isinstance(event.data, dict) and (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, end_stream=True)
except Exception:
pass
if __name__ == "__main__":
app.run(host="127.0.0.1", port=4433)
```
### Client
```python
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)
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)
if isinstance(event.data, dict) and (data := event.data.get("data")):
print(f"Datagram: {data!r}")
stream = await session.create_bidirectional_stream()
await stream.write_all(data=b"Hello, Stream!", end_stream=True)
response = await stream.read_all()
print(f"Stream: {response!r}")
await session.close()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
pass
```
## Interoperability
**Infrastructure**
- [**Public Instance**](https://interop.wtransport.org): `https://interop.wtransport.org`, _Native Dual-Stack_
- [**Container Image**](https://github.com/wtransport/pywebtransport/pkgs/container/interop-server): `ghcr.io/wtransport/interop-server:latest`, _UDP Port 4433_
**Endpoints**
- **/echo**: Bidirectional stream and datagram reflection.
- **/stats**: Current session statistics and negotiated parameters.
- **/status**: Global server health and aggregate metrics.
- **/webtransport/devious-baton**: Devious Baton protocol state transition validation.
## Sponsors
## License
Distributed under the terms of the Apache License 2.0. See [`LICENSE`](https://github.com/wtransport/pywebtransport/blob/main/LICENSE) for details.