Skip to main content

An async-native WebTransport stack for Python.

Project description

PyWebTransport

PyPI version Python Versions License: MIT Build Status Coverage Docs

An async-native WebTransport stack for Python.

Features

  • Full Async Support: Built from the ground up on asyncio for high-performance, non-blocking I/O.
  • High-Level Frameworks: Includes a ServerApp with routing and middleware, and a versatile WebTransportClient with helpers for fleet management, auto-reconnection, and browser-like navigation.
  • Advanced Messaging: Built-in managers for Pub/Sub and RPC (JSON-RPC 2.0 compliant), plus pluggable serializers (JSON, MsgPack, Protobuf) for structured data.
  • Complete Protocol Implementation: Full support for bidirectional and unidirectional streams, as well as unreliable datagrams.
  • Lifecycle and Resource Management: Robust, async context-managed components for handling connections, sessions, streams, monitoring, pooling, and resource management.
  • Event-Driven Architecture: A powerful EventEmitter system for decoupled, asynchronous communication between components.
  • Type-Safe and Tested: A fully type-annotated API with extensive test coverage (unit, integration, E2E, performance, benchmark) to ensure reliability and maintainability.

Installation

pip install pywebtransport

Quick Start

Server

# server.py
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) and isinstance(event.data.get("data"), bytes):
            await session.send_datagram(data=b"ECHO: " + event.data["data"])

    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

# client.py
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

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

Fastly

Acknowledgments

Support

License

This project is licensed under the MIT License - 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.9.0.tar.gz (114.3 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.9.0-py3-none-any.whl (138.6 kB view details)

Uploaded Python 3

File details

Details for the file pywebtransport-0.9.0.tar.gz.

File metadata

  • Download URL: pywebtransport-0.9.0.tar.gz
  • Upload date:
  • Size: 114.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.1 cpython/3.12.12 HTTPX/0.28.1

File hashes

Hashes for pywebtransport-0.9.0.tar.gz
Algorithm Hash digest
SHA256 320ddd30753c6fbc9f53488530f7d775d2acbb5a673f89d1abdb7423453cf968
MD5 79fddd066a9e4f6403017f86a2653150
BLAKE2b-256 39778d1943b6a5a8f0b408c167ade5483e5883a3da5d95db1f0b6fd4c1c1c3d9

See more details on using hashes here.

File details

Details for the file pywebtransport-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: pywebtransport-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 138.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.1 cpython/3.12.12 HTTPX/0.28.1

File hashes

Hashes for pywebtransport-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5e9a90c33c122806cf917cbe3cd1ce928ed31f980b847365815ec63607c48d33
MD5 692da54a95de5ba90104aef9ca3ebd15
BLAKE2b-256 fbe98f4fa6f17674f5392dc2e7d967c3c6a443014cfbdf3c27f0601bed728c41

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