Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,6 @@ cython_debug/
# vscode project settings
.vscode

.DS_Store
.DS_Store

docs
25 changes: 24 additions & 1 deletion livekit-api/livekit/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""LiveKit API SDK"""
"""LiveKit Server APIs for Python

`pip install livekit-api`

Manage rooms, participants, egress, ingress, SIP, and Agent dispatch.

Primary entry point is `LiveKitAPI`.

See https://docs.livekit.io/reference/server/server-apis for more information.
"""

# flake8: noqa
# re-export packages from protocol
Expand All @@ -30,3 +39,17 @@
from .access_token import VideoGrants, SIPGrants, AccessToken, TokenVerifier
from .webhook import WebhookReceiver
from .version import __version__

__all__ = [
"LiveKitAPI",
"room_service",
"egress_service",
"ingress_service",
"sip_service",
"agent_dispatch_service",
"VideoGrants",
"SIPGrants",
"AccessToken",
"TokenVerifier",
"WebhookReceiver",
]
47 changes: 26 additions & 21 deletions livekit-api/livekit/api/agent_dispatch_service.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
import aiohttp
from typing import Optional
from livekit.protocol import agent_dispatch as proto_agent_dispatch
from livekit.protocol.agent_dispatch import (
CreateAgentDispatchRequest,
AgentDispatch,
DeleteAgentDispatchRequest,
ListAgentDispatchRequest,
ListAgentDispatchResponse,
)
from ._service import Service
from .access_token import VideoGrants

SVC = "AgentDispatchService"
"""@private"""


class AgentDispatchService(Service):
"""Manage agent dispatches. Service APIs require roomAdmin permissions.

An easier way to construct this service is via LiveKitAPI.agent_dispatch.
Recommended way to use this service is via `livekit.api.LiveKitAPI`:

```python
from livekit import api
lkapi = api.LiveKitAPI()
agent_dispatch = lkapi.agent_dispatch
```
"""

def __init__(
self, session: aiohttp.ClientSession, url: str, api_key: str, api_secret: str
):
super().__init__(session, url, api_key, api_secret)

async def create_dispatch(
self, req: proto_agent_dispatch.CreateAgentDispatchRequest
) -> proto_agent_dispatch.AgentDispatch:
async def create_dispatch(self, req: CreateAgentDispatchRequest) -> AgentDispatch:
"""Create an explicit dispatch for an agent to join a room.

To use explicit dispatch, your agent must be registered with an `agentName`.
Expand All @@ -36,12 +47,10 @@ async def create_dispatch(
"CreateDispatch",
req,
self._auth_header(VideoGrants(room_admin=True, room=req.room)),
proto_agent_dispatch.AgentDispatch,
AgentDispatch,
)

async def delete_dispatch(
self, dispatch_id: str, room_name: str
) -> proto_agent_dispatch.AgentDispatch:
async def delete_dispatch(self, dispatch_id: str, room_name: str) -> AgentDispatch:
"""Delete an explicit dispatch for an agent in a room.

Args:
Expand All @@ -54,17 +63,15 @@ async def delete_dispatch(
return await self._client.request(
SVC,
"DeleteDispatch",
proto_agent_dispatch.DeleteAgentDispatchRequest(
DeleteAgentDispatchRequest(
dispatch_id=dispatch_id,
room=room_name,
),
self._auth_header(VideoGrants(room_admin=True, room=room_name)),
proto_agent_dispatch.AgentDispatch,
AgentDispatch,
)

async def list_dispatch(
self, room_name: str
) -> list[proto_agent_dispatch.AgentDispatch]:
async def list_dispatch(self, room_name: str) -> list[AgentDispatch]:
"""List all agent dispatches in a room.

Args:
Expand All @@ -76,15 +83,15 @@ async def list_dispatch(
res = await self._client.request(
SVC,
"ListDispatch",
proto_agent_dispatch.ListAgentDispatchRequest(room=room_name),
ListAgentDispatchRequest(room=room_name),
self._auth_header(VideoGrants(room_admin=True, room=room_name)),
proto_agent_dispatch.ListAgentDispatchResponse,
ListAgentDispatchResponse,
)
return list(res.agent_dispatches)

async def get_dispatch(
self, dispatch_id: str, room_name: str
) -> Optional[proto_agent_dispatch.AgentDispatch]:
) -> Optional[AgentDispatch]:
"""Get an Agent dispatch by ID

Args:
Expand All @@ -97,11 +104,9 @@ async def get_dispatch(
res = await self._client.request(
SVC,
"ListDispatch",
proto_agent_dispatch.ListAgentDispatchRequest(
dispatch_id=dispatch_id, room=room_name
),
ListAgentDispatchRequest(dispatch_id=dispatch_id, room=room_name),
self._auth_header(VideoGrants(room_admin=True, room=room_name)),
proto_agent_dispatch.ListAgentDispatchResponse,
ListAgentDispatchResponse,
)
if len(res.agent_dispatches) > 0:
return res.agent_dispatches[0]
Expand Down
82 changes: 48 additions & 34 deletions livekit-api/livekit/api/egress_service.py
Original file line number Diff line number Diff line change
@@ -1,112 +1,126 @@
import aiohttp
from livekit.protocol import egress as proto_egress
from livekit.protocol.egress import (
RoomCompositeEgressRequest,
WebEgressRequest,
ParticipantEgressRequest,
TrackCompositeEgressRequest,
TrackEgressRequest,
UpdateLayoutRequest,
UpdateStreamRequest,
ListEgressRequest,
StopEgressRequest,
EgressInfo,
ListEgressResponse,
)
from ._service import Service
from .access_token import VideoGrants

SVC = "Egress"
"""@private"""


class EgressService(Service):
"""Client for LiveKit Egress Service API

Recommended way to use this service is via `livekit.api.LiveKitAPI`:

```python
from livekit import api
lkapi = api.LiveKitAPI()
egress = lkapi.egress
```

Also see https://docs.livekit.io/home/egress/overview/
"""

def __init__(
self, session: aiohttp.ClientSession, url: str, api_key: str, api_secret: str
):
super().__init__(session, url, api_key, api_secret)

async def start_room_composite_egress(
self, start: proto_egress.RoomCompositeEgressRequest
) -> proto_egress.EgressInfo:
self, start: RoomCompositeEgressRequest
) -> EgressInfo:
return await self._client.request(
SVC,
"StartRoomCompositeEgress",
start,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.EgressInfo,
EgressInfo,
)

async def start_web_egress(
self, start: proto_egress.WebEgressRequest
) -> proto_egress.EgressInfo:
async def start_web_egress(self, start: WebEgressRequest) -> EgressInfo:
return await self._client.request(
SVC,
"StartWebEgress",
start,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.EgressInfo,
EgressInfo,
)

async def start_participant_egress(
self, start: proto_egress.ParticipantEgressRequest
) -> proto_egress.EgressInfo:
self, start: ParticipantEgressRequest
) -> EgressInfo:
return await self._client.request(
SVC,
"StartParticipantEgress",
start,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.EgressInfo,
EgressInfo,
)

async def start_track_composite_egress(
self, start: proto_egress.TrackCompositeEgressRequest
) -> proto_egress.EgressInfo:
self, start: TrackCompositeEgressRequest
) -> EgressInfo:
return await self._client.request(
SVC,
"StartTrackCompositeEgress",
start,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.EgressInfo,
EgressInfo,
)

async def start_track_egress(
self, start: proto_egress.TrackEgressRequest
) -> proto_egress.EgressInfo:
async def start_track_egress(self, start: TrackEgressRequest) -> EgressInfo:
return await self._client.request(
SVC,
"StartTrackEgress",
start,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.EgressInfo,
EgressInfo,
)

async def update_layout(
self, update: proto_egress.UpdateLayoutRequest
) -> proto_egress.EgressInfo:
async def update_layout(self, update: UpdateLayoutRequest) -> EgressInfo:
return await self._client.request(
SVC,
"UpdateLayout",
update,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.EgressInfo,
EgressInfo,
)

async def update_stream(
self, update: proto_egress.UpdateStreamRequest
) -> proto_egress.EgressInfo:
async def update_stream(self, update: UpdateStreamRequest) -> EgressInfo:
return await self._client.request(
SVC,
"UpdateStream",
update,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.EgressInfo,
EgressInfo,
)

async def list_egress(
self, list: proto_egress.ListEgressRequest
) -> proto_egress.ListEgressResponse:
async def list_egress(self, list: ListEgressRequest) -> ListEgressResponse:
return await self._client.request(
SVC,
"ListEgress",
list,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.ListEgressResponse,
ListEgressResponse,
)

async def stop_egress(
self, stop: proto_egress.StopEgressRequest
) -> proto_egress.EgressInfo:
async def stop_egress(self, stop: StopEgressRequest) -> EgressInfo:
return await self._client.request(
SVC,
"StopEgress",
stop,
self._auth_header(VideoGrants(room_record=True)),
proto_egress.EgressInfo,
EgressInfo,
)
Loading
Loading