Spaces:
Running
Running
File size: 5,173 Bytes
6c9b8f1 7e55328 6c9b8f1 b1c84b5 6c9b8f1 b1c84b5 6c9b8f1 | 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 | """
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
|