| """ | |
| Pydantic Models for Request/Response | |
| """ | |
| from typing import Optional, Dict, Any, List | |
| from datetime import datetime | |
| from enum import Enum | |
| from pydantic import BaseModel, Field, validator | |
| class TaskStatus(str, Enum): | |
| """Task status enum""" | |
| PENDING = "pending" | |
| PROCESSING = "processing" | |
| COMPLETED = "completed" | |
| FAILED = "failed" | |
| class Level(int, Enum): | |
| """Public speaking level enum""" | |
| LEVEL_1 = 1 | |
| LEVEL_2 = 2 | |
| LEVEL_3 = 3 | |
| LEVEL_4 = 4 | |
| LEVEL_5 = 5 | |
| class VideoUploadRequest(BaseModel): | |
| """Video upload request model""" | |
| level: Level = Field(..., description="Public speaking level (1-5)") | |
| user_id: Optional[str] = Field(None, description="Optional user ID for tracking") | |
| class TaskCreateResponse(BaseModel): | |
| """Task creation response""" | |
| task_id: str = Field(..., description="Unique task identifier") | |
| status: TaskStatus = Field(default=TaskStatus.PENDING) | |
| message: str = Field(default="Task created successfully") | |
| created_at: datetime = Field(default_factory=datetime.utcnow) | |
| class TaskProgress(BaseModel): | |
| """Task progress information""" | |
| current_step: str = Field(..., description="Current processing step") | |
| percentage: float = Field(..., ge=0, le=100, description="Progress percentage") | |
| message: str = Field(..., description="Progress message") | |
| class IndicatorResult(BaseModel): | |
| """Individual indicator result""" | |
| score: Optional[float] = Field(None, description="Indicator score") | |
| raw_data: Dict[str, Any] = Field(default_factory=dict, description="Raw analysis data") | |
| detected: Optional[bool] = Field(None, description="Detection status (for boolean indicators)") | |
| class MainIndicators(BaseModel): | |
| """Main indicators for scoring""" | |
| tempo: Optional[IndicatorResult] = None | |
| artikulasi: Optional[IndicatorResult] = None | |
| kontak_mata: Optional[IndicatorResult] = None | |
| kesesuaian_topik: Optional[IndicatorResult] = None | |
| struktur_kalimat: Optional[IndicatorResult] = None | |
| class BonusIndicators(BaseModel): | |
| """Bonus indicators for additional points""" | |
| jeda: Optional[IndicatorResult] = None | |
| first_impression: Optional[IndicatorResult] = None | |
| face_expression: Optional[IndicatorResult] = None | |
| gesture: Optional[IndicatorResult] = None | |
| kata_pengisi: Optional[IndicatorResult] = None | |
| kata_tidak_senonoh: Optional[IndicatorResult] = None | |
| class VideoMetadata(BaseModel): | |
| """Video metadata information""" | |
| duration: float = Field(..., description="Video duration in seconds") | |
| fps: int = Field(..., description="Frames per second") | |
| resolution: str = Field(..., description="Video resolution (e.g., '1920x1080')") | |
| file_size: int = Field(..., description="File size in bytes") | |
| class AnalysisResult(BaseModel): | |
| """Complete analysis result - New clean format""" | |
| video_info: Dict[str, Any] = Field(..., description="Video information") | |
| analysis_results: Dict[str, Any] = Field(..., description="Analysis results for eye_contact, facial_expression, gesture") | |
| overall: Dict[str, Any] = Field(..., description="Overall summary with strengths and improvements") | |
| processing_time: float = Field(..., description="Total processing time in seconds") | |
| timestamp: datetime = Field(default_factory=datetime.utcnow) | |
| class TaskStatusResponse(BaseModel): | |
| """Task status response""" | |
| task_id: str | |
| status: TaskStatus | |
| progress: Optional[TaskProgress] = None | |
| result: Optional[AnalysisResult] = None | |
| error: Optional[str] = None | |
| created_at: datetime | |
| completed_at: Optional[datetime] = None | |
| class HealthResponse(BaseModel): | |
| """Health check response""" | |
| status: str = Field(default="healthy") | |
| version: str = Field(default="1.0.0") | |
| redis_connected: bool | |
| timestamp: datetime = Field(default_factory=datetime.utcnow) | |
| class ErrorResponse(BaseModel): | |
| """Error response model""" | |
| error: str = Field(..., description="Error message") | |
| detail: Optional[str] = Field(None, description="Detailed error information") | |
| timestamp: datetime = Field(default_factory=datetime.utcnow) | |