Skip to content

Quicr/quicr-py

Repository files navigation

quicr-py

Cython bindings for libquicr - Python library for Media over QUIC (MoQ) protocol.

Installation

Prerequisites

  • Python 3.9+
  • C++20 compatible compiler (GCC 10+, Clang 12+, or MSVC 2019+)
  • CMake 3.20+
  • Cython 3.0+

Quick Setup (Recommended)

# Clone the repository with submodules
git clone --recursive https://github.com/cisco/quicr-py.git
cd quicr-py

# Run the build script (creates venv, installs deps, builds package)
./build.sh

# Activate the virtual environment
source venv/bin/activate  # Linux/macOS
# source venv/Scripts/activate  # Windows

Manual Setup with Virtual Environment

If you prefer manual setup:

# Clone the repository with submodules
git clone --recursive https://github.com/cisco/quicr-py.git
cd quicr-py

# Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate  # Linux/macOS
# source venv/Scripts/activate  # Windows

# Install build dependencies
pip install cython cmake scikit-build-core

# Build and install
pip install -e .

Using pip

pip install quicr-cython

Quick Start

Async API (Recommended)

import asyncio
from quicr_cython import AsyncClient, ClientConfig, TrackName

async def main():
    # Configure the client
    config = ClientConfig(
        connect_uri="moqt://relay.example.com:443",
        endpoint_id="my-client"
    )

    # Connect to the relay
    async with AsyncClient(config) as client:
        track = TrackName(["example", "chat"], "messages")

        # Subscribe to messages
        async with client.subscriber(track) as sub:
            async for obj in sub:
                print(f"Received: {obj.data.decode()}")
                if obj.data == b"quit":
                    break

asyncio.run(main())

Publishing Data

import asyncio
from quicr_cython import AsyncClient, ClientConfig, TrackName, TrackMode

async def publish_messages():
    config = ClientConfig(connect_uri="moqt://relay.example.com:443")

    async with AsyncClient(config) as client:
        track = TrackName(["example", "chat"], "messages")

        async with client.publisher(track, track_mode=TrackMode.STREAM) as pub:
            # Publish with auto-sequencing
            await pub.publish(b"Hello, world!")
            await pub.publish(b"Another message")

            # Start a new group
            await pub.new_group()
            await pub.publish(b"First message in new group")

asyncio.run(publish_messages())

Fetching Historical Data

import asyncio
from quicr_cython import AsyncClient, ClientConfig, TrackName

async def fetch_history():
    config = ClientConfig(connect_uri="moqt://relay.example.com:443")

    async with AsyncClient(config) as client:
        track = TrackName(["example", "chat"], "messages")

        # Fetch groups 0-10
        async with client.fetcher(track, start_group=0, end_group=10) as fetch:
            async for obj in fetch:
                print(f"Historical message: {obj.data.decode()}")

asyncio.run(fetch_history())

Synchronous API

For simpler use cases or integration with non-async code:

from quicr_cython import (
    Client, ClientConfig, TrackName, TrackMode,
    ObjectHeaders, PublishObjectStatus
)

# Create and connect client
config = ClientConfig(connect_uri="moqt://relay.example.com:443")
client = Client(config)
client.connect()

# Create a publish track
track_name = TrackName(["example", "video"], "stream1")
publisher = client.create_publish_track(
    track_name,
    track_mode=TrackMode.STREAM,
    default_priority=1,
    default_ttl=5000
)

# Activate publishing
client.publish_track(publisher)

# Publish objects
headers = ObjectHeaders(group_id=0, object_id=0, payload_length=100)
data = b"video frame data..."
status = publisher.publish_object(headers, data)

if status == PublishObjectStatus.OK:
    print("Published successfully")

# Cleanup
client.unpublish_track(publisher)
client.disconnect()

Examples

See the examples/ directory for complete working examples:

  • simple_publisher.py - Basic publishing example
  • simple_subscriber.py - Basic subscription example

Testing

# Make sure virtual environment is activated
source venv/bin/activate  # Linux/macOS

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/

# Run with coverage
pytest tests/ --cov=quicr_cython --cov-report=html

Documentation

# Make sure virtual environment is activated
source venv/bin/activate  # Linux/macOS

pip install -e ".[docs]"
cd docs
make html

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

BSD-2-Clause - See LICENSE file for details.

About

Python Wrapper for libquicr C++ api

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published