Skip to main content

An async-native WebTransport stack for Python.

Project description

PyWebTransport Icon

PyWebTransport

An async-native WebTransport stack for Python


PyPI version Python Version License: Apache 2.0 CI Coverage Docs

Features

  • Pure Async: Built entirely on asyncio for 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 memoryview and buffer protocols to minimize data copying overhead.
  • Structured Messaging: Transmission of typed Python objects via pluggable serializers (JSON, MsgPack, Protobuf).
  • High-Level Abstractions: ServerApp with routing and middleware, plus WebTransportClient utilities 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

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

Support

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Project details


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)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pywebtransport-0.10.1-py3-none-any.whl (122.3 kB view details)

Uploaded Python 3

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

Hashes for pywebtransport-0.10.1.tar.gz
Algorithm Hash digest
SHA256 1131f0e5658db0b3646723c58b9eb3bca65fa7e49eb53cbf6452eaee8d80cd02
MD5 55f58fec03337d9b1b5b136b1870eb00
BLAKE2b-256 aa282014c2b3786ec2fef89eabfb42751fb36e62d7399cc17b2420c405d82d02

See more details on using hashes here.

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

Hashes for pywebtransport-0.10.1-py3-none-any.whl
Algorithm Hash digest
SHA256 307dab85d4b486aa59446816a1be03d82d5ae8a27089d052d1e0e43ccdfa0aa8
MD5 950c62026e4640ad04ecbba0ec3c62c7
BLAKE2b-256 da8a566432051be99c002bb921ee203efba43fd99e924d922d329014ea20ed31

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page