Metadata-Version: 2.4
Name: pywebtransport
Version: 0.7.0
Summary: The canonical, async-native WebTransport stack for Python.
Project-URL: Homepage, https://github.com/lemonsterfy/pywebtransport
Project-URL: Documentation, https://pywebtransport.readthedocs.io
Project-URL: Repository, https://github.com/lemonsterfy/pywebtransport.git
Project-URL: Issues, https://github.com/lemonsterfy/pywebtransport/issues
Project-URL: Changelog, https://github.com/lemonsterfy/pywebtransport/blob/main/CHANGELOG.md
Author-email: lemonsterfy <lemonsterfy@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: async,http3,networking,protocol,quic,webtransport
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications
Classifier: Topic :: Internet
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: aioquic<2.0.0,>=1.2.0
Requires-Dist: cryptography<46.0.0,>=45.0.4
Provides-Extra: all
Requires-Dist: msgpack<2.0.0,>=1.1.1; extra == 'all'
Requires-Dist: protobuf<7.0.0,>=6.32.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: black<26.0.0,>=25.1.0; extra == 'dev'
Requires-Dist: flake8<8.0.0,>=7.2.0; extra == 'dev'
Requires-Dist: isort<7.0.0,>=6.0.1; extra == 'dev'
Requires-Dist: mypy<2.0.0,>=1.16.1; extra == 'dev'
Requires-Dist: psutil<8.0.0,>=7.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio<2.0.0,>=1.0.0; extra == 'dev'
Requires-Dist: pytest-benchmark<6.0.0,>=5.1.0; extra == 'dev'
Requires-Dist: pytest-cov<7.0.0,>=6.2.1; extra == 'dev'
Requires-Dist: pytest-mock<4.0.0,>=3.14.1; extra == 'dev'
Requires-Dist: pytest-repeat<1.0.0,>=0.9.4; extra == 'dev'
Requires-Dist: pytest<9.0.0,>=8.4.1; extra == 'dev'
Requires-Dist: types-psutil==7.0.0.20250801; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material<10.0.0,>=9.6.14; extra == 'docs'
Requires-Dist: mkdocs<2.0.0,>=1.6.1; extra == 'docs'
Requires-Dist: mkdocstrings[python]<1.0.0,>=0.29.1; extra == 'docs'
Provides-Extra: msgpack
Requires-Dist: msgpack<2.0.0,>=1.1.1; extra == 'msgpack'
Provides-Extra: protobuf
Requires-Dist: protobuf<7.0.0,>=6.32.0; extra == 'protobuf'
Provides-Extra: test
Requires-Dist: psutil<8.0.0,>=7.0.0; extra == 'test'
Requires-Dist: pytest-asyncio<2.0.0,>=1.0.0; extra == 'test'
Requires-Dist: pytest-benchmark<6.0.0,>=5.1.0; extra == 'test'
Requires-Dist: pytest-cov<7.0.0,>=6.2.1; extra == 'test'
Requires-Dist: pytest-mock<4.0.0,>=3.14.1; extra == 'test'
Requires-Dist: pytest-repeat<1.0.0,>=0.9.4; extra == 'test'
Requires-Dist: pytest<9.0.0,>=8.4.1; extra == 'test'
Requires-Dist: types-psutil==7.0.0.20250801; extra == 'test'
Description-Content-Type: text/markdown

# PyWebTransport

[![PyPI version](https://badge.fury.io/py/pywebtransport.svg)](https://badge.fury.io/py/pywebtransport)
[![Python Versions](https://img.shields.io/pypi/pyversions/pywebtransport.svg)](https://pypi.org/project/pywebtransport/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Build Status](https://github.com/lemonsterfy/pywebtransport/workflows/CI/badge.svg)](https://github.com/lemonsterfy/pywebtransport/actions)
[![Coverage](https://codecov.io/gh/lemonsterfy/pywebtransport/branch/main/graph/badge.svg)](https://codecov.io/gh/lemonsterfy/pywebtransport)
[![Docs](https://readthedocs.org/projects/pywebtransport/badge/?version=latest)](https://pywebtransport.readthedocs.io/en/latest/)

The canonical, async-native WebTransport stack for Python.

## Features

## 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 pooling, auto-reconnection, and proxying.
- **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, and monitoring.
- **Event-Driven Architecture**: A powerful EventEmitter and EventBus system for decoupled, asynchronous communication between components.
- **Type-Safe and Tested**: A fully type-annotated API with extensive test coverage (unit, integration, E2E) to ensure reliability and maintainability.

## Installation

```bash
pip install pywebtransport
```

For more detailed instructions, including virtual environments and platform-specific notes, see the [Installation Guide](docs/installation.md).

## Quick Start

### Server

```python
# server.py
import asyncio

from pywebtransport import (
    ConnectionError,
    ServerApp,
    ServerConfig,
    SessionError,
    WebTransportSession,
    WebTransportStream,
)
from pywebtransport.utils import generate_self_signed_cert

generate_self_signed_cert(hostname="localhost")

app = ServerApp(
    config=ServerConfig.create(
        certfile="localhost.crt",
        keyfile="localhost.key",
        initial_max_data=1024 * 1024,
        initial_max_streams_bidi=10,
    )
)


async def handle_datagrams(session: WebTransportSession) -> None:
    try:
        datagram_transport = await session.datagrams
        while True:
            data = await datagram_transport.receive()
            await datagram_transport.send(data=b"ECHO: " + data)
    except (ConnectionError, SessionError, asyncio.CancelledError):
        pass


async def handle_streams(session: WebTransportSession) -> None:
    try:
        async for stream in session.incoming_streams():
            if isinstance(stream, WebTransportStream):
                data = await stream.read_all()
                await stream.write_all(data=b"ECHO: " + data)
    except (ConnectionError, SessionError, asyncio.CancelledError):
        pass


@app.route(path="/")
async def echo_handler(session: WebTransportSession) -> None:
    datagram_task = asyncio.create_task(handle_datagrams(session))
    stream_task = asyncio.create_task(handle_streams(session))
    try:
        await session.wait_closed()
    finally:
        datagram_task.cancel()
        stream_task.cancel()


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=4433)

```

### Client

```python
# client.py
import asyncio
import ssl

from pywebtransport import ClientConfig, WebTransportClient


async def main() -> None:
    config = ClientConfig.create(
        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/")

        print("Connection established. Testing datagrams...")
        datagram_transport = await session.datagrams
        await datagram_transport.send(data=b"Hello, Datagram!")
        response = await datagram_transport.receive()
        print(f"Datagram echo: {response!r}\n")

        print("Testing streams...")
        stream = await session.create_bidirectional_stream()
        await stream.write_all(data=b"Hello, Stream!")
        response = await stream.read_all()
        print(f"Stream echo: {response!r}")

        await session.close()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass

```

## Documentation

- **[Installation Guide](docs/installation.md)** - In-depth setup and installation guide.
- **[Quick Start](docs/quickstart.md)** - A 5-minute tutorial to get started.
- **[API Reference](docs/api-reference/)** - Complete API documentation.

## Requirements

- Python 3.11+
- asyncio support
- TLS 1.3

**Dependencies:**

- aioquic >= 1.2.0
- cryptography >= 45.0.4

## Contributing

Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on the development setup, testing, and pull request process.

**Development Setup:**

```bash
git clone https://github.com/lemonsterfy/pywebtransport.git
cd pywebtransport
pip install -r dev-requirements.txt
pip install -e .
tox
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

- [aioquic](https://github.com/aiortc/aioquic) for the underlying QUIC protocol implementation.
- [WebTransport Working Group](https://datatracker.ietf.org/wg/webtrans/) for standardizing the protocol.

## Support

- **Issues**: [GitHub Issues](https://github.com/lemonsterfy/pywebtransport/issues)
- **Discussions**: [GitHub Discussions](https://github.com/lemonsterfy/pywebtransport/discussions)
- **Email**: lemonsterfy@gmail.com
