Skip to content

Python SDK

The Relay Python SDK. connect_relay_subscriber subscribes to track objects and connect_relay_publisher publishes them, through Relay, Mux’s Media over QUIC (MoQ) relay service. Payloads are bytes the SDK does not interpret. You need no browser, player, or media catalog.

  • Python 3.11 or later, and asyncio.
  • Network access to the relay over QUIC on UDP. The default transport is native QUIC (MOQT directly on QUIC) through aioquic, which installs as a dependency. To use another transport, pass create_transport.
  • A short-lived Relay JWT authorized for the namespace you use, and the endpoint of any relay other than the hosted one. The SDK uses tokens but does not issue them.
uv add caprid-relay

pip install caprid-relay works too. It installs caprid-moq-core as a dependency. For media publishing and reading, add caprid-moq-media.

import asyncio
from caprid_relay import (
MoqtObject,
RelaySubscriptionHandlers,
connect_relay_publisher,
connect_relay_subscriber,
read_text,
)
async def main(token: str) -> None:
namespace = ["quickstart", "unique-run"] # relative to the token's root
arrived: asyncio.Future[str] = asyncio.get_running_loop().create_future()
def on_object(obj: MoqtObject) -> None:
if obj.status == "normal" and not arrived.done():
arrived.set_result(read_text(obj))
async with (
await connect_relay_publisher(namespace=namespace, get_token=lambda: token) as publisher,
await connect_relay_subscriber(get_token=lambda: token) as subscriber,
):
ticker = publisher.register_track("ticker")
await publisher.announced
subscription = subscriber.subscribe(namespace, "ticker", RelaySubscriptionHandlers(on_object=on_object))
await subscription.subscribed # a fresh namespace can briefly reject this with error 16; retry it
await ticker.write_text("hello from caprid-relay") # waits for the subscriber's demand
print(await arrived)

With no url, each connection dials the hosted Relay, https://relay.mux.global, with the token’s root as the path, so namespaces are relative to that root. Pass url first for another relay, region or room; room_endpoint builds one.

The guide’s full demo runs the complete version of this, with credential handling, the subscribe retry, a deadline, and cleanup on failure.

Before 1.0, a minor version can break the API, and CHANGELOG.md says what changed. caprid-relay, caprid-moq-core, and caprid-moq-media always release together at the same version, and caprid-relay pins caprid-moq-core exactly. A release supports Python 3.11 or later, and MOQT draft 22 (moqt-22) with draft 20 (moqt-20) as an offered fallback, against moq-relay 0.15.4 or later.

  • Python guide: the quickstart, subscription and publishing lifecycles, async consumption, supervised connections, the aioquic transport, and the media examples.
  • API reference: in a checkout of the repository, run mise run python:docs to build it from the source.
  • Errors and recovery: stable RelayError.code and phase values, the exception subclasses, preserved transport causes, and how to recover without assuming delivery or a safe replay.
  • Shared specification: the protocol pins, behavior contract, and test vectors every Relay SDK implements.