Installation
The realtime client lives behind an optional extra:livekit (LiveKit’s Python client) alongside the core SDK. The decart.realtime module won’t import without it.
Quick Start
Creating Client Tokens
When your Python backend serves browser or mobile clients, mint short-lived client tokens instead of shipping your permanent API key.Backend Examples
Connecting
Creating a video track
The SDK consumes a LiveKitLocalVideoTrack. Build one from any source that can produce RGB frames at the model’s width × height × fps:
examples/ folder in the SDK shows two common shapes:
realtime_synthetic.py— push generated frames at the model’sfps.realtime_file.py— read frames from a video file via OpenCV.
Establishing the connection
base_url(required) —client.realtime_base_url(wss://api3.decart.aiby default)api_key(required) — your Decart API key or a client tokenlocal_track(required) — a LiveKitLocalVideoTrack. PassNoneonly when subscribing to an existing session.options: RealtimeConnectOptions:model(required) — frommodels.realtime(...)on_remote_stream(required) — callback receiving the LiveKitRemoteVideoTrackfor the transformed outputinitial_state(optional) —ModelStatewithpromptand/orimageresolution(optional) —"720p"(default) or"1080p"on supported modelspreferred_video_codec(optional) —"h264"(default) or"vp9". Picks the codec offered to the LiveKit publisher.
Consuming the remote track
on_remote_stream hands you a LiveKit RemoteVideoTrack. Wrap it with rtc.VideoStream to receive decoded frames:
Output resolution
Opt into 1080p output from supported models; otherwise the server returns 720p:Codec preference
preferred_video_codec controls the codec the SDK offers to the LiveKit publisher:
Managing Prompts
Change the transformation style mid-session.set_prompt is async and waits for the server ack — it raises on ack failure or timeout.
prompt: str— style descriptionenhance: bool— auto-enhance the prompt (default:True)
Prompt enhancement uses Decart’s AI to expand simple prompts for better results. Disable it when you need exact prompt control.
Unified State Update
set() replaces the entire session state in a single atomic call. Fields you omit are cleared.
SetInput fields:
prompt: Optional[str]— at least one ofpromptorimageis requiredenhance: bool— auto-enhance the prompt (default:True)image: Optional[Union[bytes, str]]— reference image as raw bytes, a URL, a data URL, a file path, or raw base64.Noneclears it.
Connection State
"connecting"— initial connection in progress"connected"— connected and ready to send prompts"generating"— actively generating transformed video (sticky until disconnected)"reconnecting"— connection lost; the SDK is automatically retrying"disconnected"— initial state, afterdisconnect(), or after reconnect failure
The SDK retries with exponential backoff on unexpected disconnects (up to 5 attempts). If every retry fails, the state transitions to
"disconnected" and an error event fires.Error Handling
InvalidAPIKeyError— API key invalid or missingWebRTCError— LiveKit / signaling / ICE failureModelNotFoundError— model not foundInvalidInputError— invalid input parameterDecartSDKError— base class for all SDK errors
Generation Ticks
Track session duration for billing or usage display:Session Identifiers
Once the LiveKit room info arrives, the SDK populates a session id and a subscribe token:Session Viewing (Subscribe)
Other clients can watch an active session as read-only viewers. The producer’ssubscribe_token is the handle viewers connect with.
Subscribers are receive-only — they cannot send prompts or images. They see exactly what the producer’s
on_remote_stream receives.Cleanup
Best Practices
Match the source to the model
Match the source to the model
Build
rtc.VideoSource(model.width, model.height) and push frames at model.fps. Mismatched dimensions get rescaled server-side and waste bandwidth.Seed the first frame
Seed the first frame
Pass
initial_state.prompt and/or initial_state.image to connect() so the very first generated frame is already transformed. Without it, viewers briefly see the raw input.Use `set()` for combined changes
Use `set()` for combined changes
When changing prompt and image together, prefer
set(SetInput(prompt=..., image=...)) over separate set_prompt / set_image calls — it avoids the intermediate state the model would otherwise render.Always disconnect
Always disconnect
await realtime.disconnect() from a finally block or async-context exit. The LiveKit room and HTTP session aren’t reclaimed until you do.Run on Python 3.10+
Run on Python 3.10+
The SDK targets Python ≥ 3.10. The
decart[realtime] extra adds livekit and tenacity on top of the core dependencies.API Reference
await RealtimeClient.connect(base_url, api_key, local_track, options)
Connects to the realtime transformation service. Returns a connected RealtimeClient.
Parameters:
base_url: str—client.realtime_base_urlapi_key: str— your Decart API key or a client tokenlocal_track: Optional[rtc.LocalVideoTrack]— input video trackoptions: RealtimeConnectOptions:model: ModelDefinition— frommodels.realtime(...)on_remote_stream: Callable[[rtc.RemoteVideoTrack], None]— callback for the transformed trackinitial_state: Optional[ModelState]— initial prompt / imageresolution: Optional[Literal["720p", "1080p"]]— output resolutionpreferred_video_codec: Literal["h264", "vp9"]— codec preference (default"h264")
WebRTCError on signaling, ICE, or LiveKit room failures.
await realtime.set(input)
Replaces the entire session state atomically. Fields not included are cleared.
Parameters:
input: SetInput— at least one of:prompt: Optional[str]enhance: bool(defaultTrue)image: Optional[Union[bytes, str]]— bytes, URL, data URL, file path, or raw base64
await realtime.set_prompt(prompt, enhance=True)
Changes the prompt and waits for the server ack.
Raises DecartSDKError on ack failure or timeout, InvalidInputError on empty prompt.
await realtime.set_image(image, prompt=None, enhance=True, timeout=30.0)
Sends (or clears, with image=None) a reference image. Optionally bundles a prompt.
realtime.is_connected() / realtime.get_connection_state()
Synchronous accessors for the current state ("connected" | "connecting" | "generating" | "reconnecting" | "disconnected").
realtime.session_id / realtime.subscribe_token
Optional[str] properties populated once the LiveKit room info arrives.
await realtime.disconnect()
Closes the LiveKit room and the internal HTTP session.
await RealtimeClient.subscribe(base_url, api_key, options)
Classmethod that connects to an existing session as a read-only viewer. Returns a SubscribeClient exposing is_connected(), get_connection_state(), disconnect(), and the same on(...) / off(...) event API.
SubscribeOptions:
token: str— subscribe token from the produceron_remote_stream: Callable[[rtc.RemoteVideoTrack], None]
Events
connection_change
Fires when the connection state changes. Callback signature: (state: ConnectionState) -> None.
error
Fires when an error occurs. Callback signature: (error: DecartSDKError) -> None.
generation_tick
Fires periodically during generation with billing info. Callback signature: (message: GenerationTickMessage) -> None. message.seconds is the running session duration.
Next Steps
Process API
Generate and transform media synchronously with the Process API
Examples
See complete example applications