Python SDK for the Estuary real-time AI conversation platform
Project description
Estuary Python SDK
Python SDK for the Estuary real-time AI conversation platform. Supports text chat, streaming voice (WebSocket and LiveKit WebRTC), vision, and memory.
Installation
pip install estuary-sdk
Install with optional extras:
pip install estuary-sdk[audio] # Microphone recording + speaker playback
pip install estuary-sdk[livekit] # LiveKit WebRTC voice
pip install estuary-sdk[all] # Everything
Or with PDM:
pdm install # Core only
pdm install -G audio # + audio
pdm install -G livekit # + LiveKit
pdm install -G all # Everything
Requires Python 3.11+.
Getting Your Credentials
To use the SDK you need an API key and a character ID from the Estuary Dashboard:
- Sign up or log in at app.estuary-ai.com
- Create a character — go to Characters and click Create Character. Configure your character's name, personality, and voice, then save.
- Copy the character ID — on the character's page, copy the UUID shown under the character name (or from the URL).
- Generate an API key — go to Settings → API Keys and click Create Key. Copy the key (it starts with
est_).
Use these values for api_key and character_id in the examples below.
Quick Start
import asyncio
from estuary_sdk import EstuaryClient, EstuaryConfig, BotResponse
async def main():
config = EstuaryConfig(
server_url="https://api.estuary-ai.com",
api_key="est_...",
character_id="your-character-uuid",
player_id="player-1",
)
async with EstuaryClient(config) as client:
client.on("bot_response", lambda r: print(r.text, end="" if not r.is_final else "\n"))
await client.connect()
client.send_text("Hello!")
await asyncio.sleep(5) # Wait for response
asyncio.run(main())
Voice
Continuous Mode
Audio streams continuously. The server uses VAD (voice activity detection) to detect turn boundaries.
from estuary_sdk import VoiceMode
await client.start_voice(VoiceMode.CONTINUOUS)
# Send raw PCM16 audio (16-bit signed, mono, 16kHz)
await client.send_audio(pcm_bytes)
await client.stop_voice()
Push-to-Talk
You control when audio is captured and when the turn ends.
await client.start_voice(VoiceMode.PUSH_TO_TALK)
await client.start_recording()
await client.send_audio(pcm_bytes)
await client.stop_recording() # Triggers end-of-turn
await client.stop_voice()
With Microphone (requires audio extra)
from estuary_sdk.audio import AudioRecorder, AudioPlayer
recorder = AudioRecorder(on_audio=client.send_audio)
player = AudioPlayer()
client.on("bot_voice", player.enqueue)
await client.start_voice()
await recorder.start()
Streaming Responses
Bot responses stream token-by-token. Use is_final to detect the complete message.
def on_bot_response(response: BotResponse):
if response.is_final:
print(f"[{response.message_id}] {response.text}")
else:
print(response.text, end="", flush=True)
client.on("bot_response", on_bot_response)
Memory
The REST memory API is available after connect() via client.memory.
# Search memories
results = await client.memory.search("favorite color")
# List with filters
memories = await client.memory.get_memories(memory_type="preference", limit=20)
# Other endpoints
stats = await client.memory.get_stats()
facts = await client.memory.get_core_facts()
timeline = await client.memory.get_timeline(group_by="week")
graph = await client.memory.get_graph()
Real-time memory extraction events:
from estuary_sdk import MemoryUpdatedEvent
def on_memory(event: MemoryUpdatedEvent):
print(f"Extracted {event.memories_extracted} memories")
client.on("memory_updated", on_memory)
CLI Tester
An interactive chat program is included for quick testing:
python examples/chat.py --api-key [API_KEY] --character-id [CHARACTER_ID]
Or via PDM:
pdm run chat --api-key [API_KEY] --character-id [CHARACTER_ID]
| Flag | Short | Default | Description |
|---|---|---|---|
--api-key |
-k |
required | API key |
--character-id |
-c |
required | Character UUID |
--server-url |
-s |
https://api.estuary-ai.com |
Server URL |
--player-id |
-p |
python-sdk-tester |
Player ID |
--debug |
-d |
off | Verbose logging |
--text-only |
-t |
off | Suppress voice responses |
In-chat commands: /quit, /voice, /stop, /memories, /help
Configuration
EstuaryConfig fields:
| Field | Type | Default | Description |
|---|---|---|---|
server_url |
str |
required | Server URL |
api_key |
str |
required | API key |
character_id |
str |
required | Character UUID |
player_id |
str |
required | Player identifier |
audio_sample_rate |
int |
16000 |
Audio sample rate (Hz) |
auto_reconnect |
bool |
True |
Auto-reconnect on disconnect |
max_reconnect_attempts |
int |
5 |
Max reconnection attempts |
reconnect_delay |
float |
1.0 |
Initial reconnect delay (seconds) |
debug |
bool |
False |
Enable debug logging |
voice_transport |
str |
"websocket" |
"websocket", "livekit", or "auto" |
realtime_memory |
bool |
False |
Enable realtime memory updates |
Events
| Event | Payload | Description |
|---|---|---|
connected |
SessionInfo |
Connected and authenticated |
disconnected |
str |
Disconnected (reason) |
reconnecting |
int |
Reconnection attempt number |
connection_state_changed |
ConnectionState |
State transition |
bot_response |
BotResponse |
Streaming text response |
bot_voice |
BotVoice |
Audio chunk (base64) |
stt_response |
SttResponse |
Speech-to-text result |
interrupt |
InterruptData |
Bot response interrupted |
quota_exceeded |
QuotaExceededData |
Usage quota hit |
camera_capture_request |
CameraCaptureRequest |
Server requests a camera image |
voice_started |
— | Voice session started |
voice_stopped |
— | Voice session stopped |
memory_updated |
MemoryUpdatedEvent |
New memories extracted |
livekit_connected |
str |
LiveKit room name |
livekit_disconnected |
— | LiveKit disconnected |
error |
Exception |
Error occurred |
auth_error |
str |
Authentication failed |
Register listeners with client.on(), client.once(), or client.off():
client.on("bot_response", handle_response) # Persistent listener
client.once("connected", handle_first_connect) # One-time listener
client.off("bot_response", handle_response) # Remove listener
Both sync and async callbacks are supported.
Error Handling
from estuary_sdk import EstuaryError, ErrorCode
try:
await client.connect()
except EstuaryError as e:
print(e.code) # ErrorCode enum
print(e.details) # Optional extra info
Error codes:
| Code | Description |
|---|---|
CONNECTION_FAILED |
Could not connect to server |
AUTH_FAILED |
Authentication rejected |
CONNECTION_TIMEOUT |
Connection timed out |
QUOTA_EXCEEDED |
Usage quota exceeded |
VOICE_NOT_SUPPORTED |
Voice not supported |
VOICE_ALREADY_ACTIVE |
Voice session already running |
VOICE_NOT_ACTIVE |
No active voice session |
LIVEKIT_UNAVAILABLE |
LiveKit dependency not installed |
NOT_CONNECTED |
Not connected to server |
REST_ERROR |
REST API request failed |
UNKNOWN |
Unknown error |
Optional Dependencies
| Extra | Packages | Purpose |
|---|---|---|
audio |
sounddevice, numpy | Microphone capture + speaker playback |
livekit |
livekit | LiveKit WebRTC voice transport |
all |
All of the above | Everything |
dev |
pytest, black, isort, flake8, mypy | Development tools |
Development
cd estuary-python-sdk
pdm install -G dev
pdm run test # pytest
pdm run format # black
pdm run lint # flake8
pdm run sort-imports # isort
pdm run typecheck # mypy (strict)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file estuary_sdk-0.2.5.tar.gz.
File metadata
- Download URL: estuary_sdk-0.2.5.tar.gz
- Upload date:
- Size: 51.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6fd253934536eb8cdeac666ba206ae3ebf448b8a609277fcc714efbf164dd26a
|
|
| MD5 |
18b1120fb4dba199b9b7be7f4847f1b7
|
|
| BLAKE2b-256 |
8c97d65e054ff321e30704fb64f2d65dc62ab3d83508e3df271f6272c2ea0494
|
File details
Details for the file estuary_sdk-0.2.5-py3-none-any.whl.
File metadata
- Download URL: estuary_sdk-0.2.5-py3-none-any.whl
- Upload date:
- Size: 37.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8d868120a77fa2293ea40e1ccff4a6f5327dc155aa6f2340b23b643be5fa4f7
|
|
| MD5 |
95c03fcbcd506bac0a6cb4f0196e6b67
|
|
| BLAKE2b-256 |
b094c09a1ba27603544796159dfed00b262ae5b5d05cb2bdf88c23d2b0b9d043
|