From 653e84321b66d2fdd1c84f5d8c3b32fe5b0310ad Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Fri, 31 Oct 2025 12:08:53 -0400 Subject: [PATCH] Add support for token properties in Daily util and development runner --- CHANGELOG.md | 7 ++++--- src/pipecat/runner/daily.py | 18 ++++++++++++++++-- src/pipecat/runner/run.py | 23 +++++++++++++++++++++-- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 881f52a7a..c62d5c5b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -164,9 +164,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - The development runner's `/start` endpoint now supports passing - `dailyRoomProperties` in the request body when `createDailyRoom` is true. - Properties are validated against the `DailyRoomProperties` type and passed to - Daily's room creation API. + `dailyRoomProperties` and `dailyMeetingTokenProperties` in the request body + when `createDailyRoom` is true. Properties are validated against the + `DailyRoomProperties` and `DailyMeetingTokenProperties` types respectively + and passed to Daily's room and token creation APIs. - `UserImageRawFrame` new fields `append_to_context` and `text`. The `append_to_context` field indicates if this image and text should be added to diff --git a/src/pipecat/runner/daily.py b/src/pipecat/runner/daily.py index 568d54381..87f6829bc 100644 --- a/src/pipecat/runner/daily.py +++ b/src/pipecat/runner/daily.py @@ -44,6 +44,8 @@ from loguru import logger from pydantic import BaseModel from pipecat.transports.daily.utils import ( + DailyMeetingTokenParams, + DailyMeetingTokenProperties, DailyRESTHelper, DailyRoomParams, DailyRoomProperties, @@ -84,6 +86,7 @@ async def configure( sip_num_endpoints: Optional[int] = 1, sip_codecs: Optional[Dict[str, List[str]]] = None, room_properties: Optional[DailyRoomProperties] = None, + token_properties: Optional["DailyMeetingTokenProperties"] = None, ) -> DailyRoomConfig: """Configure Daily room URL and token with optional SIP capabilities. @@ -106,6 +109,9 @@ async def configure( individual parameters. When provided, this overrides room_exp_duration and SIP-related parameters. If not provided, properties are built from the individual parameters as before. + token_properties: Optional DailyMeetingTokenProperties to customize the meeting + token. When provided, these properties are passed to the token creation API. + Note that room_name, exp, and is_owner will be set automatically. Returns: DailyRoomConfig: Object with room_url, token, and optional sip_endpoint. @@ -179,7 +185,10 @@ async def configure( # Create token and return standard format expiry_time: float = token_exp_duration * 60 * 60 - token = await daily_rest_helper.get_token(room_url, expiry_time) + token_params = None + if token_properties: + token_params = DailyMeetingTokenParams(properties=token_properties) + token = await daily_rest_helper.get_token(room_url, expiry_time, params=token_params) return DailyRoomConfig(room_url=room_url, token=token) # Create a new room @@ -221,7 +230,12 @@ async def configure( # Create meeting token token_expiry_seconds = token_exp_duration * 60 * 60 - token = await daily_rest_helper.get_token(room_url, token_expiry_seconds) + token_params = None + if token_properties: + token_params = DailyMeetingTokenParams(properties=token_properties) + token = await daily_rest_helper.get_token( + room_url, token_expiry_seconds, params=token_params + ) if sip_enabled: # Return SIP configuration object diff --git a/src/pipecat/runner/run.py b/src/pipecat/runner/run.py index 61de4d9d3..897d40fdc 100644 --- a/src/pipecat/runner/run.py +++ b/src/pipecat/runner/run.py @@ -555,6 +555,7 @@ def _setup_daily_routes(app: FastAPI): { "createDailyRoom": true, "dailyRoomProperties": { "start_video_off": true }, + "dailyMeetingTokenProperties": { "is_owner": true, "user_name": "Bot" }, "body": { "custom_data": "value" } } """ @@ -571,6 +572,7 @@ def _setup_daily_routes(app: FastAPI): create_daily_room = request_data.get("createDailyRoom", False) body = request_data.get("body", {}) daily_room_properties_dict = request_data.get("dailyRoomProperties", None) + daily_token_properties_dict = request_data.get("dailyMeetingTokenProperties", None) bot_module = _get_bot_module() @@ -585,7 +587,10 @@ def _setup_daily_routes(app: FastAPI): import aiohttp from pipecat.runner.daily import configure - from pipecat.transports.daily.utils import DailyRoomProperties + from pipecat.transports.daily.utils import ( + DailyMeetingTokenProperties, + DailyRoomProperties, + ) async with aiohttp.ClientSession() as session: # Parse dailyRoomProperties if provided @@ -598,7 +603,21 @@ def _setup_daily_routes(app: FastAPI): logger.error(f"Failed to parse dailyRoomProperties: {e}") # Continue without custom properties - room_url, token = await configure(session, room_properties=room_properties) + # Parse dailyMeetingTokenProperties if provided + token_properties = None + if daily_token_properties_dict: + try: + token_properties = DailyMeetingTokenProperties( + **daily_token_properties_dict + ) + logger.debug(f"Using custom token properties: {token_properties}") + except Exception as e: + logger.error(f"Failed to parse dailyMeetingTokenProperties: {e}") + # Continue without custom properties + + room_url, token = await configure( + session, room_properties=room_properties, token_properties=token_properties + ) runner_args = DailyRunnerArguments(room_url=room_url, token=token, body=body) result = { "dailyRoom": room_url,