# 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.

URL: https://www.caprid.com/docs/sdks/python/
Source: https://github.com/caprids/relay-sdks/blob/main/python/packages/caprid-relay/README.md

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.

## Requirements

- 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.

## Install

```sh
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`.

## Publish and subscribe

```python
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](https://github.com/caprids/relay-sdks/blob/main/python/README.md#run-the-full-demo-from-a-checkout)
runs the complete version of this, with credential handling, the subscribe retry, a deadline, and
cleanup on failure.

## Stability

Before 1.0, a minor version can break the API, and
[CHANGELOG.md](https://github.com/caprids/relay-sdks/blob/main/python/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.

## Documentation

- [Python guide](https://github.com/caprids/relay-sdks/blob/main/python/README.md): 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](https://github.com/caprids/relay-sdks/blob/main/python/README.md#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](https://github.com/caprids/relay-sdks/blob/main/spec/README.md): the
  protocol pins, behavior contract, and test vectors every Relay SDK implements.
