backend-lehrer (11 files): - llm_gateway/routes/schools.py (867 → 5), recording_api.py (848 → 6) - messenger_api.py (840 → 5), print_generator.py (824 → 5) - unit_analytics_api.py (751 → 5), classroom/routes/context.py (726 → 4) - llm_gateway/routes/edu_search_seeds.py (710 → 4) klausur-service (12 files): - ocr_labeling_api.py (845 → 4), metrics_db.py (833 → 4) - legal_corpus_api.py (790 → 4), page_crop.py (758 → 3) - mail/ai_service.py (747 → 4), github_crawler.py (767 → 3) - trocr_service.py (730 → 4), full_compliance_pipeline.py (723 → 4) - dsfa_rag_api.py (715 → 4), ocr_pipeline_auto.py (705 → 4) website (6 pages): - audit-checklist (867 → 8), content (806 → 6) - screen-flow (790 → 4), scraper (789 → 5) - zeugnisse (776 → 5), modules (745 → 4) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
99 lines
3.1 KiB
Python
99 lines
3.1 KiB
Python
"""
|
|
Recording API - Pydantic Models & Configuration.
|
|
|
|
Data models for recording, transcription, and webhook endpoints.
|
|
"""
|
|
|
|
import os
|
|
from datetime import datetime
|
|
from typing import Optional, List
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ==========================================
|
|
# ENVIRONMENT CONFIGURATION
|
|
# ==========================================
|
|
|
|
MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT", "minio:9000")
|
|
MINIO_ACCESS_KEY = os.getenv("MINIO_ACCESS_KEY", "breakpilot")
|
|
MINIO_SECRET_KEY = os.getenv("MINIO_SECRET_KEY", "breakpilot123")
|
|
MINIO_BUCKET = os.getenv("MINIO_BUCKET", "breakpilot-recordings")
|
|
MINIO_SECURE = os.getenv("MINIO_SECURE", "false").lower() == "true"
|
|
|
|
# Default retention period in days (DSGVO compliance)
|
|
DEFAULT_RETENTION_DAYS = int(os.getenv("RECORDING_RETENTION_DAYS", "365"))
|
|
|
|
|
|
# ==========================================
|
|
# PYDANTIC MODELS
|
|
# ==========================================
|
|
|
|
class JibriWebhookPayload(BaseModel):
|
|
"""Webhook payload from Jibri finalize.sh script."""
|
|
event: str = Field(..., description="Event type: recording_completed")
|
|
recording_name: str = Field(..., description="Unique recording identifier")
|
|
storage_path: str = Field(..., description="Path in MinIO bucket")
|
|
audio_path: Optional[str] = Field(None, description="Extracted audio path")
|
|
file_size_bytes: int = Field(..., description="Video file size in bytes")
|
|
timestamp: str = Field(..., description="ISO timestamp of upload")
|
|
|
|
|
|
class RecordingCreate(BaseModel):
|
|
"""Manual recording creation (for testing)."""
|
|
meeting_id: str
|
|
title: Optional[str] = None
|
|
storage_path: str
|
|
audio_path: Optional[str] = None
|
|
duration_seconds: Optional[int] = None
|
|
participant_count: Optional[int] = 0
|
|
retention_days: Optional[int] = DEFAULT_RETENTION_DAYS
|
|
|
|
|
|
class RecordingResponse(BaseModel):
|
|
"""Recording details response."""
|
|
id: str
|
|
meeting_id: str
|
|
title: Optional[str]
|
|
storage_path: str
|
|
audio_path: Optional[str]
|
|
file_size_bytes: Optional[int]
|
|
duration_seconds: Optional[int]
|
|
participant_count: int
|
|
status: str
|
|
recorded_at: datetime
|
|
retention_days: int
|
|
retention_expires_at: datetime
|
|
transcription_status: Optional[str] = None
|
|
transcription_id: Optional[str] = None
|
|
|
|
|
|
class RecordingListResponse(BaseModel):
|
|
"""Paginated list of recordings."""
|
|
recordings: List[RecordingResponse]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
class TranscriptionRequest(BaseModel):
|
|
"""Request to start transcription."""
|
|
language: str = Field(default="de", description="Language code: de, en, etc.")
|
|
model: str = Field(default="large-v3", description="Whisper model to use")
|
|
priority: int = Field(default=0, description="Queue priority (higher = sooner)")
|
|
|
|
|
|
class TranscriptionStatusResponse(BaseModel):
|
|
"""Transcription status and progress."""
|
|
id: str
|
|
recording_id: str
|
|
status: str
|
|
language: str
|
|
model: str
|
|
word_count: Optional[int]
|
|
confidence_score: Optional[float]
|
|
processing_duration_seconds: Optional[int]
|
|
error_message: Optional[str]
|
|
created_at: datetime
|
|
completed_at: Optional[datetime]
|