Python SDK¶
raclip is the official Python SDK. It's a thin, typed wrapper around the HTTP API — every SDK call corresponds to a documented endpoint.
Install¶
Requires Python 3.10+. The only runtime dependencies are httpx and pydantic.
Authenticate¶
Pass an API key explicitly, or set RACLIP_API_KEY in your environment:
from raclip import Client
# Reads RACLIP_API_KEY from the environment
client = Client()
# Or pass explicitly
client = Client(api_key="raclip_prod_…")
The SDK never sends your org_id on the wire — the gateway derives it from the key.
Quickstart¶
from raclip import Client
with Client() as client:
devices = client.devices.list()
print(f"{devices.total} devices in this org")
for device in devices.devices:
print(device.device_id, device.status, device.last_seen)
if devices.devices:
device_id = devices.devices[0].device_id
calls = client.calls.list(device_id, per_page=5)
for call in calls.calls:
print(call.call_id, call.duration_seconds, "sec")
print(" download:", call.download_url)
AsyncClient mirrors the sync surface one-for-one — every method has an async twin under the same name.
Download a recording¶
download_url on a call response is a short-lived URL. You can fetch it with anything that speaks HTTP:
Or use the SDK's streaming helper, which avoids leaking your Authorization header on the redirect:
dest accepts a path (string or Path) or any binary file-like object.
Error handling¶
Every non-2xx response converts to a typed exception so you can catch the cases you care about:
from raclip import (
Client, AuthenticationError, NotFoundError, RateLimitError
)
with Client() as client:
try:
call = client.calls.get("device-id", "call-id")
except NotFoundError:
print("call is gone")
except RateLimitError as e:
print(f"slow down; retry after {e.retry_after}s")
except AuthenticationError:
print("check your API key")
Hierarchy: RaclipError → AuthenticationError, PermissionError, NotFoundError, ValidationError, RateLimitError, APIError, APIConnectionError.
Clients¶
Client is the synchronous entry point. AsyncClient is the asyncio twin — same surface, same method names, every call awaitable. Both auto-read RACLIP_API_KEY from the environment if api_key is omitted.
Client¶
Synchronous raclip API client.
Example
from raclip import Client
with Client() as client: # RACLIP_API_KEY from env for device in client.devices.list().devices: print(device.device_id, device.status)
AsyncClient¶
Asynchronous raclip API client.
Example
import asyncio from raclip import AsyncClient
async def main(): async with AsyncClient() as client: result = await client.devices.list() for device in result.devices: print(device.device_id, device.status)
asyncio.run(main())
Resources¶
Each Client exposes two resource groups: devices and calls. Both have sync and async variants. Methods are paired one-for-one — anything you can do synchronously you can await.
Devices¶
Calls¶
raclip.resources.calls.CallsResource ¶
download ¶
download(
device_id: str,
call_id: str,
*,
dest: DownloadDest,
chunk_size: int = 64 * 1024,
) -> Path | IO[bytes]
Stream a call's MP3 to a file path or file-like.
Fetches metadata to resolve the presigned S3 URL, then downloads the bytes over a fresh httpx stream that does NOT carry the Authorization header — S3 rejects unexpected auth headers on presigned URLs.
Models¶
Every API response is parsed into a Pydantic v2 model.
Device¶
raclip.Device ¶
Bases: _RaclipModel
raclip.DeviceListResponse ¶
Bases: _RaclipModel
raclip.DeviceStats ¶
Bases: _RaclipModel
raclip.DeviceStatusSnapshot ¶
Bases: _RaclipModel
Call¶
raclip.Call ¶
Bases: _RaclipModel
A call recording.
Shape is the union of what the list and retrieval endpoints return — fields present on one endpoint but not the other are marked optional, so the same model works in both contexts.
raclip.CallListResponse ¶
Bases: _RaclipModel
raclip.CallStatistics ¶
Bases: _RaclipModel
Exceptions¶
Every non-2xx response raises a typed exception in the RaclipError tree:
RaclipError
├── APIConnectionError # network failure, DNS, TLS, etc.
├── APIError # 5xx from the gateway
├── AuthenticationError # 401
├── PermissionError # 403
├── NotFoundError # 404
├── ValidationError # 400 / 422
└── RateLimitError # 429 — exposes .retry_after
RaclipError ¶
Bases: Exception
Base class for all raclip SDK errors.