File size: 6,645 Bytes
3d9ba5b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
"""
Pydantic Schemas for Bilingual Summarization REST API
"""

from typing import List, Optional, Dict, Any, Union
from pydantic import BaseModel, Field


# --- Health & System Info ---
class HealthResponse(BaseModel):
    status: str = Field(..., example="healthy")
    version: str = Field(..., example="1.0.0")
    device: str = Field(..., example="cpu")
    cuda_available: bool = Field(..., example=False)
    loaded_checkpoints: Dict[str, bool] = Field(
        ...,
        example={"seq2seq_arabic": True, "seq2seq_english": True, "rich_seq2seq_ar": True}
    )


class ModelDetails(BaseModel):
    id: str
    name: str
    paradigm: str  # "extractive" or "abstractive"
    supported_languages: List[str]
    description: str
    checkpoint_available: Optional[bool] = None


class ModelsListResponse(BaseModel):
    total_models: int
    models: List[ModelDetails]


# --- Language Detection ---
class LanguageDetectionRequest(BaseModel):
    text: str = Field(..., description="Raw text string to detect language for", min_length=1)

    model_config = {
        "json_schema_extra": {
            "example": {
                "text": "اعلنت وكالة ناسا الفضائية عن خطط طموحة للعودة الى سطح القمر في اطار برنامج ارتيميس."
            }
        }
    }


class LanguageDetectionResponse(BaseModel):
    detected_language: str = Field(..., example="ar")
    language_name: str = Field(..., example="Arabic")
    confidence: float = Field(..., example=0.98)
    script_breakdown: Dict[str, float] = Field(
        ...,
        example={"arabic": 0.95, "latin": 0.05, "other": 0.0}
    )


# --- Tokenization & Preprocessing ---
class TokenizeRequest(BaseModel):
    text: str = Field(..., min_length=1)
    lang: str = Field("auto", description="Language: 'auto', 'ar', or 'en'")
    remove_stopwords: bool = Field(False, description="Filter out stop words")
    stem: bool = Field(False, description="Apply word stemming")

    model_config = {
        "json_schema_extra": {
            "example": {
                "text": "الذكاء الاصطناعي يُحدث ثورة في معالجة اللغات الطبيعية. هل يمكن تلخيص النصوص بدقة؟",
                "lang": "ar",
                "remove_stopwords": False,
                "stem": False
            }
        }
    }


class TokenizeResponse(BaseModel):
    detected_language: str = Field(..., example="ar")
    sentence_count: int = Field(..., example=2)
    word_count: int = Field(..., example=13)
    sentences: List[str]
    tokens: List[str]
    normalized_text: str


# --- Summarization ---
class SummarizeRequest(BaseModel):
    text: str = Field(..., min_length=1, description="Source document text to summarize")
    mode: str = Field("extractive", description="Paradigm: 'extractive', 'abstractive', or 'hybrid'")
    method: str = Field(
        "textrank",
        description="Algorithm: 'textrank', 'lsa', 'hybrid', 'seq2seq', 'transformer'"
    )
    lang: str = Field("auto", description="'auto', 'ar', or 'en'")
    sentences: int = Field(3, ge=1, le=50, description="Target number of sentences (for extractive)")
    ratio: Optional[float] = Field(None, ge=0.05, le=0.95, description="Compression ratio (e.g. 0.3 for 30%)")
    beam_width: int = Field(3, ge=1, le=8, description="Beam search width for Seq2Seq decoding")
    reference_summary: Optional[str] = Field(
        None,
        description="Optional gold-standard reference summary to automatically compute ROUGE & BLEU"
    )

    model_config = {
        "json_schema_extra": {
            "example": {
                "text": "اعلنت وكالة ناسا الفضائية الامريكية عن خطط طموحة للعودة الى سطح القمر في اطار برنامج ارتيميس حيث ستشمل البعثة اول امراة واول شخص من ذوي البشرة الداكنة يمشيان على سطح القمر ومن المقرر ان تنطلق البعثة قبل نهاية عام الفين وخمسة وعشرين.",
                "mode": "abstractive",
                "method": "seq2seq",
                "lang": "ar",
                "beam_width": 3,
                "reference_summary": "ناسا تعلن خطط العودة للقمر عبر برنامج ارتيميس قبل نهاية 2025"
            }
        }
    }


class SummaryMetrics(BaseModel):
    original_words: int
    summary_words: int
    compression_ratio: float
    reduction_percentage: float
    type_token_ratio: float
    rouge_1_f1: Optional[float] = None
    rouge_2_f1: Optional[float] = None
    rouge_l_f1: Optional[float] = None
    bleu_1: Optional[float] = None
    bleu_2: Optional[float] = None
    bleu_cumulative: Optional[float] = None


class SentenceScoreItem(BaseModel):
    sentence: str
    score: float

class SummarizeResponse(BaseModel):
    status: str = "success"
    detected_language: str
    mode: str
    method: str
    summary: str
    latency_ms: float
    metrics: SummaryMetrics
    selected_indices: Optional[List[int]] = None
    sentence_scores: Optional[List[SentenceScoreItem]] = None
    note: Optional[str] = None


# --- Evaluation Request & Response ---
class EvaluationRequest(BaseModel):
    original_text: str = Field(..., min_length=1)
    generated_summary: str = Field(..., min_length=1)
    reference_summary: Optional[str] = Field(None, description="Ground truth reference summary")
    lang: str = Field("auto", description="'auto', 'ar', or 'en'")

    model_config = {
        "json_schema_extra": {
            "example": {
                "original_text": "Global semiconductor shortages are easing according to the latest industry report with chip inventories returning to normal.",
                "generated_summary": "Semiconductor shortage eases as chip inventories return to normal levels.",
                "reference_summary": "Global chip shortage easing with inventories normalizing across industry.",
                "lang": "en"
            }
        }
    }


class EvaluationResponse(BaseModel):
    language: str
    compression_ratio: float
    reduction_percentage: float
    original_words: int
    summary_words: int
    type_token_ratio: float
    rouge_1: Optional[Dict[str, float]] = None  # {precision, recall, f1}
    rouge_2: Optional[Dict[str, float]] = None
    rouge_l: Optional[Dict[str, float]] = None
    bleu_1: Optional[float] = None
    bleu_2: Optional[float] = None
    bleu_3: Optional[float] = None
    bleu_4: Optional[float] = None
    bleu_cumulative: Optional[float] = None