"""EmoSphere Data Models — Pydantic schemas for API request/response.""" from __future__ import annotations from enum import Enum from pydantic import BaseModel, Field # ── Emotion Labels ─────────────────────────────────────────────────── class EmotionLabel(str, Enum): JOY = "joy" SADNESS = "sadness" SURPRISE = "surprise" FEAR = "fear" DISGUST = "disgust" ANGER = "anger" NEUTRAL = "neutral" LOVE = "love" CALM = "calm" EMOTION_LABELS = list(EmotionLabel) EMOTION_EMOJI = { EmotionLabel.JOY: "😊", EmotionLabel.SADNESS: "😢", EmotionLabel.SURPRISE: "😲", EmotionLabel.FEAR: "😰", EmotionLabel.DISGUST: "😖", EmotionLabel.ANGER: "😠", EmotionLabel.NEUTRAL: "😐", EmotionLabel.LOVE: "🥰", EmotionLabel.CALM: "😌", } # ── Cultural Regions ───────────────────────────────────────────────── class CulturalRegion(str, Enum): UNIVERSAL = "universal" WESTERN = "western" EAST_ASIAN = "east_asian" SOUTH_ASIAN = "south_asian" MIDDLE_EASTERN = "middle_eastern" AFRICAN = "african" LATIN_AMERICAN = "latin_american" CULTURAL_ADJUSTMENT = { CulturalRegion.UNIVERSAL: 1.0, CulturalRegion.WESTERN: 1.0, CulturalRegion.EAST_ASIAN: 0.75, CulturalRegion.SOUTH_ASIAN: 1.1, CulturalRegion.MIDDLE_EASTERN: 1.15, CulturalRegion.AFRICAN: 1.1, CulturalRegion.LATIN_AMERICAN: 1.2, } # ── API Schemas ────────────────────────────────────────────────────── class EmotionScore(BaseModel): label: EmotionLabel score: float = Field(ge=0.0, le=1.0) confidence: float = Field(ge=0.0, le=1.0) class EmotionDetectionResult(BaseModel): dominant: EmotionLabel dominant_score: float scores: list[EmotionScore] modality: str confidence: float processing_time_ms: float cultural_region: CulturalRegion = CulturalRegion.UNIVERSAL class FaceDetectionRequest(BaseModel): """Request for face emotion detection from image.""" image_base64: str cultural_region: CulturalRegion = CulturalRegion.UNIVERSAL class VoiceDetectionRequest(BaseModel): """Request for voice emotion detection from audio.""" audio_base64: str sample_rate: int = 16000 cultural_region: CulturalRegion = CulturalRegion.UNIVERSAL class TextDetectionRequest(BaseModel): """Request for text emotion detection.""" text: str = Field(min_length=1, max_length=5000) cultural_region: CulturalRegion = CulturalRegion.UNIVERSAL class FusedDetectionResult(BaseModel): dominant: EmotionLabel dominant_score: float scores: list[EmotionScore] face_result: EmotionDetectionResult | None = None voice_result: EmotionDetectionResult | None = None text_result: EmotionDetectionResult | None = None posture_result: EmotionDetectionResult | None = None modality_weights: dict[str, float] confidence: float processing_time_ms: float class HealthResponse(BaseModel): status: str models_loaded: dict[str, bool] version: str