209 lines
5.2 KiB
Python
209 lines
5.2 KiB
Python
"""Pydantic models for the Transcription system."""
|
|
|
|
from pydantic import BaseModel, Field
|
|
from typing import Optional, List
|
|
from datetime import datetime
|
|
|
|
|
|
# --- Session Models ---
|
|
|
|
class TranscriptionSessionCreate(BaseModel):
|
|
user_id: str
|
|
title: Optional[str] = None
|
|
canvas_type: str = "teaching-canvas"
|
|
|
|
|
|
class TranscriptionSessionUpdate(BaseModel):
|
|
title: Optional[str] = None
|
|
ended_at: Optional[datetime] = None
|
|
timetable_period_id: Optional[str] = None
|
|
timetable_event_type: Optional[str] = None
|
|
timetable_event_label: Optional[str] = None
|
|
auto_tagged: Optional[bool] = None
|
|
llm_provider: Optional[str] = None
|
|
llm_model: Optional[str] = None
|
|
|
|
|
|
class TranscriptionSessionResponse(BaseModel):
|
|
id: str
|
|
user_id: str
|
|
title: Optional[str] = None
|
|
canvas_type: str
|
|
started_at: datetime
|
|
ended_at: Optional[datetime] = None
|
|
duration_seconds: Optional[int] = None
|
|
timetable_period_id: Optional[str] = None
|
|
timetable_event_type: Optional[str] = None
|
|
timetable_event_label: Optional[str] = None
|
|
auto_tagged: bool = False
|
|
llm_provider: Optional[str] = None
|
|
llm_model: Optional[str] = None
|
|
word_count: int = 0
|
|
segment_count: int = 0
|
|
metadata: dict = {}
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class SessionListResponse(BaseModel):
|
|
sessions: List[TranscriptionSessionResponse]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
# --- Segment Models ---
|
|
|
|
class TranscriptionSegmentCreate(BaseModel):
|
|
session_id: str
|
|
sequence_index: int
|
|
text: str
|
|
start_seconds: float
|
|
end_seconds: float
|
|
is_final: bool = True
|
|
speaker_label: Optional[str] = None
|
|
keyword_matches: Optional[List[str]] = None
|
|
|
|
|
|
class TranscriptionSegmentResponse(BaseModel):
|
|
id: str
|
|
session_id: str
|
|
sequence_index: int
|
|
text: str
|
|
start_seconds: float
|
|
end_seconds: float
|
|
is_final: bool = True
|
|
speaker_label: Optional[str] = None
|
|
keyword_matches: Optional[List[str]] = None
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# --- Canvas Event Models ---
|
|
|
|
class CanvasEventCreate(BaseModel):
|
|
session_id: Optional[str] = None
|
|
user_id: str
|
|
timestamp: Optional[datetime] = None
|
|
session_elapsed_seconds: Optional[float] = None
|
|
event_type: str
|
|
event_payload: dict = {}
|
|
canvas_snapshot_url: Optional[str] = None
|
|
tldraw_page_id: Optional[str] = None
|
|
tldraw_shape_ids: Optional[List[str]] = None
|
|
|
|
|
|
class CanvasEventResponse(BaseModel):
|
|
id: str
|
|
session_id: Optional[str] = None
|
|
user_id: str
|
|
timestamp: datetime
|
|
session_elapsed_seconds: Optional[float] = None
|
|
event_type: str
|
|
event_payload: dict = {}
|
|
canvas_snapshot_url: Optional[str] = None
|
|
tldraw_page_id: Optional[str] = None
|
|
tldraw_shape_ids: Optional[List[str]] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# --- Summary Models ---
|
|
|
|
class SummaryGenerateRequest(BaseModel):
|
|
summary_type: str # full_lesson, questions_asked, teaching_style, key_moments, segment
|
|
provider: str # anthropic, openai, ollama, openrouter, google
|
|
model: str
|
|
api_key: str # from frontend user settings, passed per-request
|
|
segment_range: Optional[List[Optional[int]]] = None # [start, end], null = all
|
|
include_canvas_snapshots: bool = False
|
|
|
|
|
|
class SummaryResponse(BaseModel):
|
|
id: str
|
|
session_id: str
|
|
user_id: str
|
|
summary_type: str
|
|
content: str
|
|
prompt_used: Optional[str] = None
|
|
llm_provider: str
|
|
llm_model: str
|
|
input_tokens: Optional[int] = None
|
|
output_tokens: Optional[int] = None
|
|
segment_range_start: Optional[int] = None
|
|
segment_range_end: Optional[int] = None
|
|
canvas_snapshot_urls: Optional[List[str]] = None
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# --- Keyword Watch Models ---
|
|
|
|
class KeywordWatchCreate(BaseModel):
|
|
user_id: str
|
|
keyword: str
|
|
match_type: str = "contains" # contains, exact, starts_with, regex
|
|
action: str = "log" # log, alert, canvas_shape, webhook
|
|
|
|
|
|
class KeywordWatchResponse(BaseModel):
|
|
id: str
|
|
user_id: str
|
|
keyword: str
|
|
match_type: str = "contains"
|
|
action: str = "log"
|
|
is_active: bool = True
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# --- Keyword Event Models ---
|
|
|
|
class KeywordEventCreate(BaseModel):
|
|
session_id: str
|
|
segment_id: Optional[str] = None
|
|
keyword_watch_id: Optional[str] = None
|
|
keyword_text: str
|
|
matched_in_text: str
|
|
session_elapsed_seconds: Optional[float] = None
|
|
|
|
|
|
class KeywordEventResponse(BaseModel):
|
|
id: str
|
|
session_id: str
|
|
segment_id: Optional[str] = None
|
|
keyword_watch_id: Optional[str] = None
|
|
keyword_text: str
|
|
matched_in_text: str
|
|
session_elapsed_seconds: Optional[float] = None
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# --- Export Models ---
|
|
|
|
class ExportFormat(BaseModel):
|
|
format: str # srt, txt, json
|
|
|
|
|
|
# --- Timetable Models ---
|
|
|
|
class CurrentPeriodResponse(BaseModel):
|
|
period_id: Optional[str] = None
|
|
event_type: Optional[str] = None
|
|
event_label: Optional[str] = None
|
|
start_time: Optional[datetime] = None
|
|
end_time: Optional[datetime] = None
|