EmoSphere / models.py
chariscait's picture
Add anger as 9th emotion label
827aee5 verified
"""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