Guides / Connecting
Connecting
Configure a ZeliClient, open a session, and manage its lifecycle —
either as an async context manager or by hand.
Creating a client
A ZeliClient holds your configuration and event handlers. Point it at your
server with ClientOptions and describe the avatar with AvatarConfig.
from zeli import ZeliClient, AvatarConfig, ClientOptions
client = ZeliClient(
avatar_config=AvatarConfig(
avatar_id="presenter-male-1080",
voice_id="your-voice-id",
emotion_responsive=True,
),
options=ClientOptions(
server_url="http://your-server:8080",
connect_timeout=30.0,
),
)You can also pass just an avatar id as a shorthand:
client = ZeliClient(
avatar_id="presenter-male-1080",
options=ClientOptions(server_url="http://your-server:8080"),
)Pass either avatar_id or avatar_config,
not both — doing both raises ConfigurationError.
server_url is required.
Opening a session
connect() works two ways. As an async context manager (recommended), the session
is closed for you:
async with client.connect() as session:
print(session.session_id, session.avatar)
await session.wait_until_closed()Or awaited directly, when you want to manage the lifetime yourself:
session = await client.connect()
try:
...
finally:
await session.close()Session options
from zeli import SessionOptions
options = SessionOptions(
video_quality="high", # or "auto" to adapt to bandwidth
receive_video=True,
receive_audio=True,
)
async with client.connect(options) as session:
...Lifecycle
session.session_id— the server-issued id for the session.session.avatar— the concrete avatar the server resolved.session.is_active—Falseonce closed.await session.wait_until_closed()— blocks until the server closes the session, the media connection drops, or you callclose().
When the connection ends, the client emits
CONNECTION_CLOSED.
What happens under the hood
- The SDK negotiates a WebRTC connection via the server's
POST /connectendpoint (audio + video, receive-only). - It opens the control channel (a WebSocket) for commands and events.
- If the server predates the control gateway, the SDK falls back to plain
HTTP for
send_message;talk/ talk streams then require an upgraded server. Checksession.has_control_channelto detect this.