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"))


@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

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

https://interop.wtransport.org

  • /echo: Bidirectional stream and datagram reflection.
  • /status: Global server health and aggregate metrics.
  • /stats: Current session statistics and negotiated parameters.

Sponsors

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.11.0.tar.gz (106.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.11.0-py3-none-any.whl (114.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pywebtransport-0.11.0.tar.gz
  • Upload date:
  • Size: 106.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.11.0.tar.gz
Algorithm Hash digest
SHA256 340ecba80f5519d82416ff01315282d384e5030b8e2895b90323e45337764104
MD5 f1f3757edd1eb71d638c08b64d20380b
BLAKE2b-256 1223e1cefffe751411d5693c605b1cb475a25cc39c5d82431226de00e82c671c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pywebtransport-0.11.0-py3-none-any.whl
  • Upload date:
  • Size: 114.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.11.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3cc7101f9ebccc34a3d9791af6b4eb64d66ada5fc3f3b40ff2fd6cd9ac66bb54
MD5 101a6d6ab464e2bbfc08a3d40b17c15a
BLAKE2b-256 05604c4f36881b88f25bf5a86db8b833d13755db9d704125574cf30cc3ef0f6c

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