mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 12:49:06 +00:00
incorporate daily api undocumented feature (#796)
Co-authored-by: Igor Loskutov <igor.loskutoff@gmail.com>
This commit is contained in:
@@ -18,6 +18,7 @@ from .requests import (
|
|||||||
|
|
||||||
# Response models
|
# Response models
|
||||||
from .responses import (
|
from .responses import (
|
||||||
|
FinishedRecordingResponse,
|
||||||
MeetingParticipant,
|
MeetingParticipant,
|
||||||
MeetingParticipantsResponse,
|
MeetingParticipantsResponse,
|
||||||
MeetingResponse,
|
MeetingResponse,
|
||||||
@@ -79,6 +80,7 @@ __all__ = [
|
|||||||
"MeetingParticipant",
|
"MeetingParticipant",
|
||||||
"MeetingResponse",
|
"MeetingResponse",
|
||||||
"RecordingResponse",
|
"RecordingResponse",
|
||||||
|
"FinishedRecordingResponse",
|
||||||
"RecordingS3Info",
|
"RecordingS3Info",
|
||||||
"MeetingTokenResponse",
|
"MeetingTokenResponse",
|
||||||
"WebhookResponse",
|
"WebhookResponse",
|
||||||
|
|||||||
@@ -121,7 +121,10 @@ class RecordingS3Info(BaseModel):
|
|||||||
|
|
||||||
class RecordingResponse(BaseModel):
|
class RecordingResponse(BaseModel):
|
||||||
"""
|
"""
|
||||||
Response from recording retrieval endpoint.
|
Response from recording retrieval endpoint (network layer).
|
||||||
|
|
||||||
|
Duration may be None for recordings still being processed by Daily.
|
||||||
|
Use FinishedRecordingResponse for recordings ready for processing.
|
||||||
|
|
||||||
Reference: https://docs.daily.co/reference/rest-api/recordings
|
Reference: https://docs.daily.co/reference/rest-api/recordings
|
||||||
"""
|
"""
|
||||||
@@ -135,7 +138,9 @@ class RecordingResponse(BaseModel):
|
|||||||
max_participants: int | None = Field(
|
max_participants: int | None = Field(
|
||||||
None, description="Maximum participants during recording (may be missing)"
|
None, description="Maximum participants during recording (may be missing)"
|
||||||
)
|
)
|
||||||
duration: int = Field(description="Recording duration in seconds")
|
duration: int | None = Field(
|
||||||
|
None, description="Recording duration in seconds (None if still processing)"
|
||||||
|
)
|
||||||
share_token: NonEmptyString | None = Field(
|
share_token: NonEmptyString | None = Field(
|
||||||
None, description="Token for sharing recording"
|
None, description="Token for sharing recording"
|
||||||
)
|
)
|
||||||
@@ -149,6 +154,25 @@ class RecordingResponse(BaseModel):
|
|||||||
None, description="Meeting session identifier (may be missing)"
|
None, description="Meeting session identifier (may be missing)"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def to_finished(self) -> "FinishedRecordingResponse | None":
|
||||||
|
"""Convert to FinishedRecordingResponse if duration is available and status is finished."""
|
||||||
|
if self.duration is None or self.status != "finished":
|
||||||
|
return None
|
||||||
|
return FinishedRecordingResponse(**self.model_dump())
|
||||||
|
|
||||||
|
|
||||||
|
class FinishedRecordingResponse(RecordingResponse):
|
||||||
|
"""
|
||||||
|
Recording with confirmed duration - ready for processing.
|
||||||
|
|
||||||
|
This model guarantees duration is present and status is finished.
|
||||||
|
"""
|
||||||
|
|
||||||
|
status: Literal["finished"] = Field(
|
||||||
|
description="Recording status (always 'finished')"
|
||||||
|
)
|
||||||
|
duration: int = Field(description="Recording duration in seconds")
|
||||||
|
|
||||||
|
|
||||||
class MeetingTokenResponse(BaseModel):
|
class MeetingTokenResponse(BaseModel):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from celery import shared_task
|
|||||||
from celery.utils.log import get_task_logger
|
from celery.utils.log import get_task_logger
|
||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
|
|
||||||
from reflector.dailyco_api import RecordingResponse
|
from reflector.dailyco_api import FinishedRecordingResponse, RecordingResponse
|
||||||
from reflector.db.daily_participant_sessions import (
|
from reflector.db.daily_participant_sessions import (
|
||||||
DailyParticipantSession,
|
DailyParticipantSession,
|
||||||
daily_participant_sessions_controller,
|
daily_participant_sessions_controller,
|
||||||
@@ -322,16 +322,38 @@ async def poll_daily_recordings():
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
recording_ids = [rec.id for rec in api_recordings]
|
finished_recordings: List[FinishedRecordingResponse] = []
|
||||||
|
for rec in api_recordings:
|
||||||
|
finished = rec.to_finished()
|
||||||
|
if finished is None:
|
||||||
|
logger.debug(
|
||||||
|
"Skipping unfinished recording",
|
||||||
|
recording_id=rec.id,
|
||||||
|
room_name=rec.room_name,
|
||||||
|
status=rec.status,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
finished_recordings.append(finished)
|
||||||
|
|
||||||
|
if not finished_recordings:
|
||||||
|
logger.debug(
|
||||||
|
"No finished recordings found from Daily.co API",
|
||||||
|
total_api_count=len(api_recordings),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
recording_ids = [rec.id for rec in finished_recordings]
|
||||||
existing_recordings = await recordings_controller.get_by_ids(recording_ids)
|
existing_recordings = await recordings_controller.get_by_ids(recording_ids)
|
||||||
existing_ids = {rec.id for rec in existing_recordings}
|
existing_ids = {rec.id for rec in existing_recordings}
|
||||||
|
|
||||||
missing_recordings = [rec for rec in api_recordings if rec.id not in existing_ids]
|
missing_recordings = [
|
||||||
|
rec for rec in finished_recordings if rec.id not in existing_ids
|
||||||
|
]
|
||||||
|
|
||||||
if not missing_recordings:
|
if not missing_recordings:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"All recordings already in DB",
|
"All recordings already in DB",
|
||||||
api_count=len(api_recordings),
|
api_count=len(finished_recordings),
|
||||||
existing_count=len(existing_recordings),
|
existing_count=len(existing_recordings),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@@ -339,7 +361,7 @@ async def poll_daily_recordings():
|
|||||||
logger.info(
|
logger.info(
|
||||||
"Found recordings missing from DB",
|
"Found recordings missing from DB",
|
||||||
missing_count=len(missing_recordings),
|
missing_count=len(missing_recordings),
|
||||||
total_api_count=len(api_recordings),
|
total_api_count=len(finished_recordings),
|
||||||
existing_count=len(existing_recordings),
|
existing_count=len(existing_recordings),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user