Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

webtransport-py

PyPI image License Actions status Discord

About Shiguredo's open source software

We will not respond to PRs or issues that have not been discussed on Discord. Also, Discord is only available in Japanese.

Please read https://github.com/shiguredo/oss/blob/master/README.en.md before use.

時雨堂のオープンソースソフトウェアについて

利用前に https://github.com/shiguredo/oss をお読みください。

webtransport-py について

webtransport-py は Sans I/O アーキテクチャを採用した WebTransport の Python ライブラリです。WebTransport over HTTP/3 と WebTransport over HTTP/2 の両方に対応しています。

また、WebTransport だけでなく QUIC、HTTP/3、HTTP/2 を単体のプロトコルとしても利用できます。asyncio、スレッド、独自のイベントループなど、任意の I/O フレームワークと組み合わせて利用できます。

特徴

  • Sans I/O アーキテクチャ
    • I/O 処理をライブラリ外部で制御可能
    • 任意のイベントループやフレームワークと統合可能
    • Sans I/O
  • 二層 API 設計
    • Sans I/O API: プロトコル処理のみを提供する低レベル API
    • asyncio API: すぐに使える高レベルなクライアント/サーバー実装
  • QUIC
    • Sans I/O API と asyncio API の両方を提供
    • 双方向/単方向ストリーム
    • QUIC DATAGRAM
    • 0-RTT / Session Resumption
    • 証明書のカスタム検証
    • Connection Migration
    • ngtcp2 を採用
  • HTTP/3
    • Sans I/O API と asyncio API の両方を提供
    • nghttp3 を採用
  • HTTP/2
    • Sans I/O API と asyncio API の両方を提供
    • nghttp2 を採用
  • WebTransport over HTTP/3
    • Sans I/O API と asyncio API の両方を提供
  • WebTransport over HTTP/2
    • Sans I/O API と asyncio API の両方を提供
  • Python Free-Threading 対応
  • クロスプラットフォーム対応
    • Ubuntu x86_64 / arm64
    • macOS arm64

インストール

uv add webtransport-py

使い方

WebTransport over HTTP/3

サーバー

import asyncio

from webtransport import h3


async def main() -> None:
    server = h3.Server(
        host="0.0.0.0",
        port=4433,
        certfile="cert.pem",
        keyfile="key.pem",
    )

    async def on_session_ready(session_id: int, addr: tuple[str, int]) -> None:
        print(f"セッション確立: {session_id} from {addr}")

    async def on_stream_data(
        session_id: int,
        stream_id: int,
        data: bytes,
        addr: tuple[str, int],
    ) -> None:
        print(f"データ受信: {data}")
        # エコーバック
        await server.send_stream_data(addr, stream_id, data)

    async def on_datagram(session_id: int, data: bytes, addr: tuple[str, int]) -> None:
        print(f"データグラム受信: {data}")
        # エコーバック
        await server.send_datagram(addr, session_id, data)

    server.on_session_ready(on_session_ready)
    server.on_stream_data(on_stream_data)
    server.on_datagram(on_datagram)

    async with server:
        print(f"サーバー開始: {server.host}:{server.actual_port}")
        await server.run()


if __name__ == "__main__":
    asyncio.run(main())

クライアント

import asyncio

from webtransport import h3


async def main() -> None:
    client = h3.Client(
        url="https://localhost:4433/webtransport",
        verify_peer=False,
    )

    async def on_stream_data(stream_id: int, data: bytes) -> None:
        print(f"データ受信: {data}")

    async def on_datagram(data: bytes) -> None:
        print(f"データグラム受信: {data}")

    client.on_stream_data(on_stream_data)
    client.on_datagram(on_datagram)

    if not await client.connect():
        print("接続失敗")
        return

    # ストリームでデータ送信
    stream_id = await client.open_stream()
    await client.send_stream_data(stream_id, b"Hello via stream!")

    # データグラムでデータ送信
    await client.send_datagram(b"Hello via datagram!")

    try:
        await asyncio.wait_for(client.run(), timeout=5.0)
    except TimeoutError:
        pass

    await client.close()


if __name__ == "__main__":
    asyncio.run(main())

WebTransport over HTTP/2

サーバー

import asyncio

from webtransport import h2


async def main() -> None:
    server = h2.Server(
        host="0.0.0.0",
        port=8443,
        certfile="cert.pem",
        keyfile="key.pem",
    )

    async def on_session_ready(session_writer: h2.SessionWriter) -> None:
        print(f"セッション確立: {session_writer.session_id}")

    async def on_stream_data(
        stream_id: int,
        data: bytes,
        session_writer: h2.SessionWriter,
    ) -> None:
        print(f"データ受信: {data}")
        # エコーバック
        await session_writer.send_stream_data(stream_id, data)

    async def on_datagram(data: bytes, session_writer: h2.SessionWriter) -> None:
        print(f"データグラム受信: {data}")
        # エコーバック
        await session_writer.send_datagram(data)

    server.on_session_ready(on_session_ready)
    server.on_stream_data(on_stream_data)
    server.on_datagram(on_datagram)

    async with server:
        print(f"サーバー開始: {server.host}:{server.actual_port}")
        await server.run()


if __name__ == "__main__":
    asyncio.run(main())

クライアント

import asyncio

from webtransport import h2


async def main() -> None:
    client = h2.Client(
        url="https://localhost:8443/webtransport",
        verify_peer=False,
    )

    async def on_stream_data(stream_id: int, data: bytes) -> None:
        print(f"データ受信: {data}")

    async def on_datagram(data: bytes) -> None:
        print(f"データグラム受信: {data}")

    client.on_stream_data(on_stream_data)
    client.on_datagram(on_datagram)

    if not await client.connect():
        print("接続失敗")
        return

    # ストリームでデータ送信
    stream_id = await client.open_stream()
    await client.send_stream_data(stream_id, b"Hello via stream!")

    # データグラムでデータ送信
    await client.send_datagram(b"Hello via datagram!")

    try:
        await asyncio.wait_for(client.run(), timeout=5.0)
    except TimeoutError:
        pass

    await client.close()


if __name__ == "__main__":
    asyncio.run(main())

QUIC

サーバー

import asyncio

from webtransport import quic


async def main() -> None:
    server = quic.Server(
        host="0.0.0.0",
        port=4433,
        certfile="cert.pem",
        keyfile="key.pem",
    )

    async def on_handshake_completed(addr: tuple[str, int]) -> None:
        print(f"ハンドシェイク完了: {addr}")

    async def on_stream_data(
        stream_id: int,
        data: bytes,
        fin: bool,
        addr: tuple[str, int],
    ) -> None:
        print(f"データ受信: {data}")
        # エコーバック
        await server.send_stream_data(addr, stream_id, data, fin)

    server.on_handshake_completed(on_handshake_completed)
    server.on_stream_data(on_stream_data)

    async with server:
        print(f"サーバー開始: {server.host}:{server.actual_port}")
        await server.run()


if __name__ == "__main__":
    asyncio.run(main())

クライアント

import asyncio

from webtransport import quic


async def main() -> None:
    client = quic.Client(
        host="localhost",
        port=4433,
        verify_peer=False,
    )

    if not await client.connect():
        print("接続失敗")
        return

    # 双方向ストリームを開いてデータ送信 (FIN でストリームを閉じる)
    stream_id = await client.open_stream(bidirectional=True)
    await client.send_stream_data(stream_id, b"Hello, QUIC!", fin=True)

    # サーバーからのエコーを FIN まで受信する
    try:
        data, _ = await client.recv_stream_data(stream_id, timeout=5.0)
        print(f"データ受信: {data}")
    except TimeoutError:
        print("受信タイムアウト")

    await client.close()


if __name__ == "__main__":
    asyncio.run(main())

Python

  • 3.14
  • 3.14t

プラットフォーム

  • Ubuntu 24.04 LTS x86_64
  • Ubuntu 24.04 LTS arm64
  • macOS 26 arm64

リリースビルド

make wheel

開発ビルド

make develop

テスト

uv sync
make test

サンプル

examples/ ディレクトリにサンプルコードがあります。

ngtcp2 ライセンス

https://github.com/ngtcp2/ngtcp2/blob/main/COPYING

The MIT License

Copyright (c) 2016 ngtcp2 contributors

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

nghttp3 ライセンス

https://github.com/ngtcp2/nghttp3/blob/main/COPYING

The MIT License

Copyright (c) 2019 nghttp3 contributors

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

nghttp2 ライセンス

https://github.com/nghttp2/nghttp2/blob/master/COPYING

The MIT License

Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

ライセンス

Apache License 2.0

Copyright 2026 Shiguredo Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

webtransport_py-2026.1.0.dev8-cp314-cp314t-manylinux_2_39_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.39+ x86-64

webtransport_py-2026.1.0.dev8-cp314-cp314t-manylinux_2_39_aarch64.whl (2.1 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.39+ ARM64

webtransport_py-2026.1.0.dev8-cp314-cp314t-macosx_26_0_arm64.whl (1.8 MB view details)

Uploaded CPython 3.14tmacOS 26.0+ ARM64

webtransport_py-2026.1.0.dev8-cp314-cp314-manylinux_2_39_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.39+ x86-64

webtransport_py-2026.1.0.dev8-cp314-cp314-manylinux_2_39_aarch64.whl (2.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.39+ ARM64

webtransport_py-2026.1.0.dev8-cp314-cp314-macosx_26_0_arm64.whl (1.8 MB view details)

Uploaded CPython 3.14macOS 26.0+ ARM64

File details

Details for the file webtransport_py-2026.1.0.dev8-cp314-cp314t-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for webtransport_py-2026.1.0.dev8-cp314-cp314t-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 98e23b54891aec70474ebcb51fe53f43ee23aecbdf3c94c9789f54e6a85b0662
MD5 c0ee5ca18a358e7920e6ca8eb04da981
BLAKE2b-256 6b72079ba620fe9bf3b0a16919123e6015fb9b45c8c142cb7472ee98a8fddf23

See more details on using hashes here.

Provenance

The following attestation bundles were made for webtransport_py-2026.1.0.dev8-cp314-cp314t-manylinux_2_39_x86_64.whl:

Publisher: wheel.yml on shiguredo/webtransport-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file webtransport_py-2026.1.0.dev8-cp314-cp314t-manylinux_2_39_aarch64.whl.

File metadata

File hashes

Hashes for webtransport_py-2026.1.0.dev8-cp314-cp314t-manylinux_2_39_aarch64.whl
Algorithm Hash digest
SHA256 b4ae847d31efe6a43300a2e65b9919684d7b4a9baf760e823de2f832909709a7
MD5 3fa4a54735242bf7a4901255df697c31
BLAKE2b-256 932bc7053437f84da177b8b50d76b021839bd43aa96099d203bb9298099a72a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for webtransport_py-2026.1.0.dev8-cp314-cp314t-manylinux_2_39_aarch64.whl:

Publisher: wheel.yml on shiguredo/webtransport-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file webtransport_py-2026.1.0.dev8-cp314-cp314t-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for webtransport_py-2026.1.0.dev8-cp314-cp314t-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 cdfc0a8cf020f0c9eed39a13c5655513c9791341f8c3a3d336617664d491553a
MD5 29a8451c90247a5c00ebc728d979f141
BLAKE2b-256 870ae5eee129adcda6615a64c32fa7ea7adc5c1658a11086c76d53f6c856be0c

See more details on using hashes here.

Provenance

The following attestation bundles were made for webtransport_py-2026.1.0.dev8-cp314-cp314t-macosx_26_0_arm64.whl:

Publisher: wheel.yml on shiguredo/webtransport-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file webtransport_py-2026.1.0.dev8-cp314-cp314-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for webtransport_py-2026.1.0.dev8-cp314-cp314-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 89d4ff3a95c44f28c3b113fece9843e8d6f73e8702b00175c5ec4418b7a70c7f
MD5 0d00efc2f9e24380482bd10c300eaa31
BLAKE2b-256 9c5312940b5afd15bc19eb06dd0e2d5ac3fa631c6b5243de3dca81c05b2145c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for webtransport_py-2026.1.0.dev8-cp314-cp314-manylinux_2_39_x86_64.whl:

Publisher: wheel.yml on shiguredo/webtransport-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file webtransport_py-2026.1.0.dev8-cp314-cp314-manylinux_2_39_aarch64.whl.

File metadata

File hashes

Hashes for webtransport_py-2026.1.0.dev8-cp314-cp314-manylinux_2_39_aarch64.whl
Algorithm Hash digest
SHA256 1fa556ee0cc5408d2b27ff9af807b6eb612a216a46efcf6cf5820ad0721175b8
MD5 44e5dc4197b35ce15817a9eda1734200
BLAKE2b-256 bcb7fb41f5af7827affa9085d56b308788e91ade7d2b5d4a2a7c98154ea68f15

See more details on using hashes here.

Provenance

The following attestation bundles were made for webtransport_py-2026.1.0.dev8-cp314-cp314-manylinux_2_39_aarch64.whl:

Publisher: wheel.yml on shiguredo/webtransport-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file webtransport_py-2026.1.0.dev8-cp314-cp314-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for webtransport_py-2026.1.0.dev8-cp314-cp314-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 2412f14e8dc41ff31442fc6925aa2000705ec12c90093a43e5f98005e811bbdc
MD5 167d189c21ffa7b262df666a7b92653d
BLAKE2b-256 e26a0daf787f2e35f15970f023f1aa6108cf1f626ea5b940d7cf6f31fa337436

See more details on using hashes here.

Provenance

The following attestation bundles were made for webtransport_py-2026.1.0.dev8-cp314-cp314-macosx_26_0_arm64.whl:

Publisher: wheel.yml on shiguredo/webtransport-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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