swara-api / app /models.py
Zakha123-cyber
Fix: Update AnalysisResult model to match new response format
5cb7758
"""
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)