Daily's Python SDK provides everything needed to build real-time video, audio, and AI-powered voice agents with WebRTC infrastructure. It allows headless bots to connect to Daily rooms and process media and event data streams, supporting various use cases from virtual devices to transcription. The current version is 0.27.0, and the library maintains an active release cadence with frequent updates and new features.
Install & Compatibility
Where this runs
tested against v0.29.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.915 runs
build_error
glibcpy 3.10–3.915 runs
installs and imports cleanly · install 1.9s · import 0.000s · 57MB
54MB installed
● package 54MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
from daily import CallClient
from daily import EventHandler
from daily import LogLevel
from daily import CustomAudioSource
from daily import CustomVideoTrack
This quickstart initializes the Daily Python SDK, sets up a basic event handler to respond to participant events, creates a `CallClient`, and joins a Daily meeting room. It uses environment variables for the room URL and token for security and ease of configuration. The example includes graceful joining and leaving of a meeting.
import os
import time
import threading
from daily import Daily, CallClient, EventHandler, LogLevel
# Replace with your Daily room URL and token (optional)
DAILY_ROOM_URL = os.environ.get('DAILY_ROOM_URL', 'https://your-domain.daily.co/your-room')
DAILY_TOKEN = os.environ.get('DAILY_TOKEN', None)
class MyEventHandler(EventHandler):
def on_participant_joined(self, participant):
print(f"Participant joined: {participant['info']['userName']} (ID: {participant['id']})")
def on_participant_left(self, participant, reason):
print(f"Participant left: {participant['info']['userName']} (ID: {participant['id']}) - Reason: {reason}")
def on_joined_meeting(self, data, error):
if error:
print(f"Failed to join meeting: {error}")
self.join_event.set() # Signal completion even on error
else:
print("Successfully joined the meeting!")
self.join_event.set()
def on_error(self, error):
print(f"An error occurred in the Daily SDK: {error}")
def set_join_event(self, event):
self.join_event = event
def main():
# Initialize the Daily SDK with optional logging
Daily.init(log_level=LogLevel.INFO)
print("Daily SDK initialized.")
event_handler = MyEventHandler()
client = CallClient(event_handler=event_handler)
join_completion_event = threading.Event()
event_handler.set_join_event(join_completion_event)
print(f"Attempting to join room: {DAILY_ROOM_URL}")
client.join(
meeting_url=DAILY_ROOM_URL,
meeting_token=DAILY_TOKEN,
completion=event_handler.on_joined_meeting
)
# Wait for the join operation to complete
join_completion_event.wait(timeout=30) # Wait up to 30 seconds
if join_completion_event.is_set() and client.is_joined():
print("Client is active in the meeting. Waiting for 10 seconds...")
time.sleep(10) # Stay in the meeting for a short period
print("Leaving meeting...")
leave_completion_event = threading.Event()
client.leave(completion=lambda data, error: leave_completion_event.set())
leave_completion_event.wait(timeout=10)
print("Left meeting.")
else:
print("Failed to join meeting or timed out.")
client.release()
Daily.deinit()
print("Daily SDK deinitialized.")
if __name__ == "__main__":
main()
daily-python --version
Upgrade
Version history
Breaking-change detection hasn't run for this library yet.
Audit
Security & dependencies
CVE tracking and dependency tree are planned for a later release.