add livekit helper

This commit is contained in:
fbarril
2025-11-21 00:27:57 +00:00
parent 26918728df
commit ec8964425a
3 changed files with 102 additions and 1 deletions

View File

@@ -112,6 +112,7 @@ webrtc = [ "aiortc>=1.13.0,<2", "opencv-python>=4.11.0.86,<5" ]
websocket = [ "pipecat-ai[websockets-base]", "fastapi>=0.115.6,<0.122.0" ]
websockets-base = [ "websockets>=13.1,<16.0" ]
whisper = [ "faster-whisper~=1.1.1" ]
auth = [ "pyjwt>=2.10.1" ]
[dependency-groups]
dev = [

View File

@@ -0,0 +1,96 @@
#
# Copyright (c) 20242025, Daily
#
# SPDX-License-Identifier: BSD 2-Clause License
#
"""LiveKit REST Helpers.
Methods that wrap the LiveKit API for room management.
"""
import aiohttp
class LiveKitRESTHelper:
"""Helper class for interacting with LiveKit's REST API.
Provides methods for managing LiveKit rooms.
"""
def __init__(
self,
*,
api_key: str,
api_secret: str,
api_url: str = "https://your-livekit-host.com",
aiohttp_session: aiohttp.ClientSession,
):
"""Initialize the LiveKit REST helper.
Args:
api_key: Your LiveKit API key.
api_secret: Your LiveKit API secret.
api_url: LiveKit server URL (e.g. "https://your-livekit-host.com").
aiohttp_session: Async HTTP session for making requests.
"""
self.api_key = api_key
self.api_secret = api_secret
self.api_url = api_url.rstrip("/")
self.aiohttp_session = aiohttp_session
def _create_access_token(self, room_create: bool = True) -> str:
"""Create a signed access token for LiveKit API authentication.
Args:
room_create: Whether to grant roomCreate permission.
Returns:
Signed JWT access token.
"""
import time
import jwt
claims = {
"iss": self.api_key,
"sub": self.api_key,
"nbf": int(time.time()),
"exp": int(time.time()) + 60, # Token valid for 60 seconds
"video": {
"roomCreate": room_create,
},
}
return jwt.encode(claims, self.api_secret, algorithm="HS256")
async def delete_room_by_name(self, room_name: str) -> bool:
"""Delete a LiveKit room by name.
This will forcibly disconnect all participants currently in the room.
Args:
room_name: Name of the room to delete.
Returns:
True if deletion was successful.
Raises:
Exception: If deletion fails.
"""
token = self._create_access_token(room_create=True)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
async with self.aiohttp_session.post(
f"{self.api_url}/twirp/livekit.RoomService/DeleteRoom",
headers=headers,
json={"room": room_name},
) as r:
if r.status != 200:
text = await r.text()
raise Exception(f"Failed to delete room [{room_name}] (status: {r.status}): {text}")
return True

6
uv.lock generated
View File

@@ -4442,6 +4442,9 @@ assemblyai = [
asyncai = [
{ name = "websockets" },
]
auth = [
{ name = "pyjwt" },
]
aws = [
{ name = "aioboto3" },
{ name = "websockets" },
@@ -4721,6 +4724,7 @@ requires-dist = [
{ name = "pyaudio", marker = "extra == 'local'", specifier = "~=0.2.14" },
{ name = "pydantic", specifier = ">=2.10.6,<3" },
{ name = "pygobject", marker = "extra == 'gstreamer'", specifier = "~=3.50.0" },
{ name = "pyjwt", marker = "extra == 'auth'", specifier = ">=2.10.1" },
{ name = "pyloudnorm", specifier = "~=0.1.1" },
{ name = "python-dotenv", marker = "extra == 'runner'", specifier = ">=1.0.0,<2.0.0" },
{ name = "pyvips", extras = ["binary"], marker = "extra == 'moondream'", specifier = "~=3.0.0" },
@@ -4745,7 +4749,7 @@ requires-dist = [
{ name = "wait-for2", marker = "python_full_version < '3.12'", specifier = ">=0.4.1" },
{ name = "websockets", marker = "extra == 'websockets-base'", specifier = ">=13.1,<16.0" },
]
provides-extras = ["aic", "anthropic", "assemblyai", "asyncai", "aws", "aws-nova-sonic", "azure", "cartesia", "cerebras", "deepseek", "daily", "deepgram", "elevenlabs", "fal", "fireworks", "fish", "gladia", "google", "grok", "groq", "gstreamer", "heygen", "hume", "inworld", "krisp", "koala", "langchain", "livekit", "lmnt", "local", "mcp", "mem0", "mistral", "mlx-whisper", "moondream", "nim", "neuphonic", "noisereduce", "openai", "openpipe", "openrouter", "perplexity", "playht", "qwen", "rime", "riva", "runner", "sambanova", "sarvam", "sentry", "local-smart-turn", "local-smart-turn-v3", "remote-smart-turn", "silero", "simli", "soniox", "soundfile", "speechmatics", "strands", "tavus", "together", "tracing", "ultravox", "webrtc", "websocket", "websockets-base", "whisper"]
provides-extras = ["aic", "anthropic", "assemblyai", "asyncai", "aws", "aws-nova-sonic", "azure", "cartesia", "cerebras", "deepseek", "daily", "deepgram", "elevenlabs", "fal", "fireworks", "fish", "gladia", "google", "grok", "groq", "gstreamer", "heygen", "hume", "inworld", "krisp", "koala", "langchain", "livekit", "lmnt", "local", "mcp", "mem0", "mistral", "mlx-whisper", "moondream", "nim", "neuphonic", "noisereduce", "openai", "openpipe", "openrouter", "perplexity", "playht", "qwen", "rime", "riva", "runner", "sambanova", "sarvam", "sentry", "local-smart-turn", "local-smart-turn-v3", "remote-smart-turn", "silero", "simli", "soniox", "soundfile", "speechmatics", "strands", "tavus", "together", "tracing", "ultravox", "webrtc", "websocket", "websockets-base", "whisper", "auth"]
[package.metadata.requires-dev]
dev = [