File size: 2,318 Bytes
e317d56 46cc63a e317d56 0f0ce9b e317d56 46cc63a e317d56 | 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 | """Pydantic request/response models for the API."""
from typing import Literal, Optional
from pydantic import BaseModel, Field, field_validator
class PredictRequest(BaseModel):
text: str = Field(..., min_length=1, max_length=5000)
threshold: float = Field(0.5, ge=0.0, le=1.0)
@field_validator("text")
@classmethod
def text_not_empty(cls, v: str) -> str:
if not v.strip():
raise ValueError("Text cannot be empty")
return v.strip()
class PredictResponse(BaseModel):
text: str
is_toxic: bool
probability: float = Field(..., ge=0.0, le=1.0)
status: Literal["Safe", "Toxic"]
mode: Literal["binary"] = "binary"
labels: list[str]
model_used: str
latency_ms: float
class BatchPredictRequest(BaseModel):
texts: list[str] = Field(..., min_length=1, max_length=100)
threshold: float = Field(0.5, ge=0.0, le=1.0)
class BatchPredictResponse(BaseModel):
results: list[PredictResponse]
total: int
toxic_count: int
latency_ms: float
class VideoRequest(BaseModel):
url: str
max_comments: int = Field(15, ge=1, le=200)
threshold: float = Field(0.5, ge=0.0, le=1.0)
class VideoResponse(BaseModel):
video_url: str
total_fetched: int
toxic_count: int
toxic_rate: float
results: list[PredictResponse]
source: Literal["youtube", "demo", "unavailable"] = "demo"
reason: Optional[str] = None
error: Optional[str] = None
class ModelStatusEntry(BaseModel):
name: str
available: bool
reason: Optional[str] = None
type: str = "unknown"
class ModelsStatusResponse(BaseModel):
models: list[ModelStatusEntry]
active: str
class SelectModelRequest(BaseModel):
model_name: str = Field(..., min_length=1)
class ModelInfo(BaseModel):
name: str
type: str
description: str
speed: str
accuracy: str
uptime_s: float
predictions_served: int
display_banner: Optional[str] = None
train_test_gap_pp: Optional[float] = None
recommended_threshold: Optional[float] = None
class SuggestedVideo(BaseModel):
id: str
title: str
channel_title: str
thumbnail_url: str
watch_url: str
embeddable: bool = True
class SuggestedVideosResponse(BaseModel):
videos: list[SuggestedVideo]
max_comments: int
|