Spaces:
Sleeping
Sleeping
| """Pydantic Schemas for API Request/Response Validation. | |
| Matches exact hackathon requirements: | |
| - Request: language, audioFormat, audioBase64 | |
| - Response: status, language, classification, confidenceScore, explanation | |
| """ | |
| from pydantic import BaseModel, Field, field_validator | |
| from typing import List, Optional, Dict | |
| import base64 | |
| # ============== REQUEST SCHEMAS ============== | |
| class VoiceDetectionRequest(BaseModel): | |
| """Request schema matching hackathon requirements exactly.""" | |
| language: str = Field( | |
| ..., | |
| description="Language of the audio: Tamil, English, Hindi, Malayalam, Telugu" | |
| ) | |
| audioFormat: str = Field( | |
| default="mp3", | |
| description="Audio format (always mp3 per requirements)" | |
| ) | |
| audioBase64: str = Field( | |
| ..., | |
| description="Base64 encoded MP3 audio file", | |
| min_length=100 | |
| ) | |
| def validate_base64(cls, v: str) -> str: | |
| """Validate that audio is valid Base64.""" | |
| try: | |
| decoded = base64.b64decode(v) | |
| if len(decoded) < 100: | |
| raise ValueError("Audio data too small") | |
| return v | |
| except Exception as e: | |
| raise ValueError(f"Invalid Base64 encoding: {str(e)}") | |
| def validate_language(cls, v: str) -> str: | |
| """Validate language is supported (case-insensitive).""" | |
| valid_languages = ['tamil', 'english', 'hindi', 'malayalam', 'telugu'] | |
| v_lower = v.lower() | |
| if v_lower not in valid_languages: | |
| raise ValueError(f"Language must be one of: Tamil, English, Hindi, Malayalam, Telugu") | |
| return v_lower | |
| def validate_audio_format(cls, v: str) -> str: | |
| """Validate audio format is mp3.""" | |
| if v.lower() != "mp3": | |
| raise ValueError("audioFormat must be 'mp3'") | |
| return v.lower() | |
| class Config: | |
| json_schema_extra = { | |
| "example": { | |
| "language": "Tamil", | |
| "audioFormat": "mp3", | |
| "audioBase64": "SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU2LjM2LjEwMAAAAAAA..." | |
| } | |
| } | |
| # ============== RESPONSE SCHEMAS ============== | |
| class VoiceDetectionResponse(BaseModel): | |
| """Success response matching hackathon requirements exactly.""" | |
| status: str = Field( | |
| default="success", | |
| description="Response status: success or error" | |
| ) | |
| language: str = Field( | |
| ..., | |
| description="Language of the audio" | |
| ) | |
| classification: str = Field( | |
| ..., | |
| description="AI_GENERATED or HUMAN" | |
| ) | |
| confidenceScore: float = Field( | |
| ..., | |
| ge=0, | |
| le=1, | |
| description="Confidence score between 0.0 and 1.0" | |
| ) | |
| explanation: str = Field( | |
| ..., | |
| description="Short reason for the decision" | |
| ) | |
| class Config: | |
| json_schema_extra = { | |
| "example": { | |
| "status": "success", | |
| "language": "Tamil", | |
| "classification": "AI_GENERATED", | |
| "confidenceScore": 0.91, | |
| "explanation": "Unnatural pitch consistency and robotic speech patterns detected" | |
| } | |
| } | |
| class ErrorResponse(BaseModel): | |
| """Error response matching hackathon requirements exactly.""" | |
| status: str = Field( | |
| default="error", | |
| description="Response status: error" | |
| ) | |
| message: str = Field( | |
| ..., | |
| description="Error message" | |
| ) | |
| class Config: | |
| json_schema_extra = { | |
| "example": { | |
| "status": "error", | |
| "message": "Invalid API key or malformed request" | |
| } | |
| } | |
| # ============== HEALTH CHECK SCHEMA (bonus, not required) ============== | |
| class HealthResponse(BaseModel): | |
| """Health check response.""" | |
| status: str = Field(default="healthy", description="Service health status") | |
| model_loaded: bool = Field(..., description="Whether ML model is loaded") | |
| version: str = Field(default="1.0.0", description="API version") | |