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

  • 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.
  • Structured Messaging: Send typed Python objects over streams and datagrams using pluggable serializers (JSON, MsgPack, Protobuf).
  • Zero-Copy Architecture: End-to-end support for memoryview and buffer protocols to minimize data copying.
  • 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, and resource cleanup.
  • 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, benchmark) to ensure reliability and maintainability.

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

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.0.tar.gz (109.8 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.0-py3-none-any.whl (122.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pywebtransport-0.10.0.tar.gz
  • Upload date:
  • Size: 109.8 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.0.tar.gz
Algorithm Hash digest
SHA256 0ab5bdb804c249ccfb9eb2231b06f2fa0db954de070471bbbca6ca594f4a7388
MD5 59d7b50d2f56e48444f481d369b72c2f
BLAKE2b-256 55c5f4864522075191e674e520e3de16a3cc16049979559098890938e8e857b5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pywebtransport-0.10.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a09a918374d6af7c0aeb9097e679b545c4daf30eb980a13db3c2d0cb081ed6b5
MD5 ba7ed0fde12bd0a7460cf25867953ac1
BLAKE2b-256 5021483f536fad598244e89b36ee571522fcc88c5c554646ddaad84246982ab8

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