added event decorators
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Optional, Union
|
from functools import wraps
|
||||||
|
from typing import Any, Callable, Optional, Union
|
||||||
|
|
||||||
from fastapi import WebSocket
|
from fastapi import WebSocket
|
||||||
from pipecatcloud.agent import DailySessionArguments, WebsocketSessionArguments
|
from pipecatcloud.agent import DailySessionArguments, WebsocketSessionArguments
|
||||||
@@ -104,6 +105,19 @@ class PipecatCloudTransport(BaseTransport):
|
|||||||
This transport will instantiate one of the three underlying transports based on the
|
This transport will instantiate one of the three underlying transports based on the
|
||||||
session arguments provided to the constructor.
|
session arguments provided to the constructor.
|
||||||
|
|
||||||
|
Event handlers:
|
||||||
|
@event_handler("on_client_connected"): Called when a client connects. Maps to:
|
||||||
|
- FastAPIWebsocketTransport.event_handler("on_client_connected")
|
||||||
|
- SmallWebRTCTransport.event_handler("on_client_connected")
|
||||||
|
- DailyTransport.event_handler("on_first_participant_joined")
|
||||||
|
|
||||||
|
@event_handler("on_client_disconnected"): Called when a client disconnects. Maps to:
|
||||||
|
- FastAPIWebsocketTransport.event_handler("on_client_disconnected")
|
||||||
|
- SmallWebRTCTransport.event_handler("on_client_disconnected")
|
||||||
|
- DailyTransport.event_handler("on_participant_left")
|
||||||
|
|
||||||
|
Other event handlers are passed through directly to the underlying transport.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
session_args: Arguments for creating the session. The type of arguments determines
|
session_args: Arguments for creating the session. The type of arguments determines
|
||||||
which transport will be used.
|
which transport will be used.
|
||||||
@@ -113,6 +127,15 @@ class PipecatCloudTransport(BaseTransport):
|
|||||||
output_name: Optional name for the output transport.
|
output_name: Optional name for the output transport.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Event name mappings for each transport type
|
||||||
|
# Only include events that need to be mapped differently
|
||||||
|
_EVENT_MAPPINGS = {
|
||||||
|
DailyTransport: {
|
||||||
|
"on_client_connected": "on_first_participant_joined",
|
||||||
|
"on_client_disconnected": "on_participant_left",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
session_args: SessionArguments,
|
session_args: SessionArguments,
|
||||||
@@ -125,6 +148,7 @@ class PipecatCloudTransport(BaseTransport):
|
|||||||
logger.debug(f"SessionArguments: {session_args}")
|
logger.debug(f"SessionArguments: {session_args}")
|
||||||
|
|
||||||
params = params or PipecatCloudParams()
|
params = params or PipecatCloudParams()
|
||||||
|
self._pending_handlers = {}
|
||||||
|
|
||||||
# Create the appropriate transport based on session arguments type
|
# Create the appropriate transport based on session arguments type
|
||||||
if isinstance(session_args, WebsocketSessionArguments):
|
if isinstance(session_args, WebsocketSessionArguments):
|
||||||
@@ -159,6 +183,52 @@ class PipecatCloudTransport(BaseTransport):
|
|||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported session arguments type: {type(session_args)}")
|
raise ValueError(f"Unsupported session arguments type: {type(session_args)}")
|
||||||
|
|
||||||
|
# Register any handlers that were added before transport creation
|
||||||
|
for event_name, handlers in self._pending_handlers.items():
|
||||||
|
for handler in handlers:
|
||||||
|
self._register_handler(event_name, handler)
|
||||||
|
|
||||||
|
def _register_handler(self, event_name: str, handler: Callable[..., Any]) -> None:
|
||||||
|
"""Register a handler with the appropriate transport method."""
|
||||||
|
transport_type = type(self._transport)
|
||||||
|
|
||||||
|
# If the transport type has mappings and the event needs to be mapped
|
||||||
|
if (
|
||||||
|
transport_type in self._EVENT_MAPPINGS
|
||||||
|
and event_name in self._EVENT_MAPPINGS[transport_type]
|
||||||
|
):
|
||||||
|
mapped_event = self._EVENT_MAPPINGS[transport_type][event_name]
|
||||||
|
else:
|
||||||
|
# Pass through the event name directly if no mapping exists
|
||||||
|
mapped_event = event_name
|
||||||
|
|
||||||
|
self._transport.event_handler(mapped_event)(handler)
|
||||||
|
|
||||||
|
def event_handler(self, event_name: str) -> Callable[..., Any]:
|
||||||
|
"""Register an event handler.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
event_name: The name of the event to handle. Common events:
|
||||||
|
- "on_client_connected": Called when a client connects
|
||||||
|
- "on_client_disconnected": Called when a client disconnects
|
||||||
|
Other event names are passed through to the underlying transport.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A decorator that registers the handler function.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(handler: Callable[..., Any]) -> Callable[..., Any]:
|
||||||
|
if not hasattr(self, "_transport"):
|
||||||
|
# Store the handler to be registered when the transport is created
|
||||||
|
if event_name not in self._pending_handlers:
|
||||||
|
self._pending_handlers[event_name] = []
|
||||||
|
self._pending_handlers[event_name].append(handler)
|
||||||
|
else:
|
||||||
|
self._register_handler(event_name, handler)
|
||||||
|
return handler
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
async def start(self, frame):
|
async def start(self, frame):
|
||||||
"""Start the transport."""
|
"""Start the transport."""
|
||||||
await self._transport.start(frame)
|
await self._transport.start(frame)
|
||||||
|
|||||||
Reference in New Issue
Block a user