Spaces:
Running
Running
Ryan Christian D. Deniega
Fix: Overhaul Facebook post detection to filtered comments using [role='feed'] strategy and improve button positioning
7e55328 | """ | |
| PhilVerify β Pydantic Request / Response Schemas | |
| Matches the structured JSON output format from the system spec. | |
| """ | |
| from __future__ import annotations | |
| from enum import Enum | |
| from typing import Optional | |
| from pydantic import BaseModel, HttpUrl, Field | |
| # ββ Enums βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class Verdict(str, Enum): | |
| CREDIBLE = "Credible" | |
| UNVERIFIED = "Unverified" | |
| LIKELY_FAKE = "Likely Fake" | |
| class Stance(str, Enum): | |
| SUPPORTS = "Supports" | |
| REFUTES = "Refutes" | |
| NOT_ENOUGH_INFO = "Not Enough Info" | |
| class Language(str, Enum): | |
| TAGALOG = "Tagalog" | |
| ENGLISH = "English" | |
| TAGLISH = "Taglish" | |
| UNKNOWN = "Unknown" | |
| class Sentiment(str, Enum): | |
| POSITIVE = "positive" | |
| NEGATIVE = "negative" | |
| NEUTRAL = "neutral" | |
| HIGH_POSITIVE = "high positive" | |
| HIGH_NEGATIVE = "high negative" | |
| class DomainTier(int, Enum): | |
| CREDIBLE = 1 | |
| SATIRE_OPINION = 2 | |
| SUSPICIOUS = 3 | |
| KNOWN_FAKE = 4 | |
| # ββ Request Models βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class TextVerifyRequest(BaseModel): | |
| text: str = Field(..., min_length=10, max_length=10_000, description="Raw text to verify") | |
| class URLVerifyRequest(BaseModel): | |
| url: HttpUrl = Field(..., description="URL of the news article or social media post") | |
| # ββ Nested Response Models ββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class EntitiesResult(BaseModel): | |
| persons: list[str] = [] | |
| organizations: list[str] = [] | |
| locations: list[str] = [] | |
| dates: list[str] = [] | |
| class Layer1Result(BaseModel): | |
| verdict: Verdict | |
| confidence: float = Field(..., ge=0.0, le=100.0, description="Confidence % from ML classifier") | |
| triggered_features: list[str] = Field( | |
| default_factory=list, | |
| description="Human-readable list of suspicious features detected", | |
| ) | |
| class EvidenceSource(BaseModel): | |
| title: str | |
| url: str | |
| similarity: float = Field(..., ge=0.0, le=1.0, description="Cosine similarity to input claim") | |
| stance: Stance | |
| domain_tier: DomainTier | |
| published_at: Optional[str] = None | |
| source_name: Optional[str] = None | |
| class Layer2Result(BaseModel): | |
| verdict: Verdict | |
| evidence_score: float = Field(..., ge=0.0, le=100.0) | |
| sources: list[EvidenceSource] = [] | |
| claim_used: Optional[str] = Field(None, description="Extracted claim sent to evidence search") | |
| # ββ Main Response βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class VerificationResponse(BaseModel): | |
| verdict: Verdict | |
| confidence: float = Field(..., ge=0.0, le=100.0) | |
| final_score: float = Field(..., ge=0.0, le=100.0) | |
| layer1: Layer1Result | |
| layer2: Layer2Result | |
| entities: EntitiesResult | |
| sentiment: str | |
| emotion: str | |
| language: Language | |
| domain_credibility: Optional[DomainTier] = None | |
| input_type: str = "text" | |
| processing_time_ms: Optional[float] = None | |
| extracted_text: Optional[str] = Field(None, description="Raw text extracted from the URL / image / video for transparency") | |
| # ββ History / Trends ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class HistoryEntry(BaseModel): | |
| id: str | |
| timestamp: str | |
| input_type: str | |
| text_preview: str | |
| verdict: Verdict | |
| confidence: float | |
| final_score: float | |
| class HistoryResponse(BaseModel): | |
| total: int | |
| entries: list[HistoryEntry] | |
| class TrendingEntity(BaseModel): | |
| entity: str | |
| entity_type: str # person | org | location | |
| count: int | |
| fake_count: int | |
| fake_ratio: float | |
| class TrendingTopic(BaseModel): | |
| topic: str | |
| count: int | |
| dominant_verdict: Verdict | |
| class VerdictDayPoint(BaseModel): | |
| date: str # YYYY-MM-DD | |
| credible: int = 0 | |
| unverified: int = 0 | |
| fake: int = 0 | |
| class TrendsResponse(BaseModel): | |
| top_entities: list[TrendingEntity] | |
| top_topics: list[TrendingTopic] | |
| verdict_distribution: dict[str, int] = Field( | |
| default_factory=dict, | |
| description="Counts per verdict: Credible, Unverified, Likely Fake", | |
| ) | |
| verdict_by_day: list[VerdictDayPoint] = Field( | |
| default_factory=list, | |
| description="Day-by-day verdict counts for the area chart (last N days)", | |
| ) | |
| # ββ Error βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class ErrorResponse(BaseModel): | |
| error: str | |
| detail: Optional[str] = None | |
| code: Optional[str] = None | |