File size: 3,356 Bytes
b4d33ac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
827aee5
b4d33ac
 
 
 
 
 
 
 
 
 
 
 
 
827aee5
b4d33ac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b6bb72a
b4d33ac
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
"""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