deepfake_detection / app /api /schemas.py
VoiceGuard Bot
Deploy to Spaces
f68a33a
Raw
History Blame Contribute Delete
4.19 kB
"""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
)
@field_validator('audioBase64')
@classmethod
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)}")
@field_validator('language')
@classmethod
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
@field_validator('audioFormat')
@classmethod
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")