from pydantic import BaseModel, HttpUrl
from datetime import datetime
from typing import List, Optional
# --- Base Schemas ---
class LocationBase(BaseModel):
"""
Base schema for a single geocoded location.
"""
entity_name: Optional[str] = None
latitude: float
longitude: float
entity_type: Optional[str] = None
geocoder_source: Optional[str] = None
class Config:
from_attributes = True # Allows Pydantic to read ORM objects
class ArticleBase(BaseModel):
"""
Base schema for an article being processed.
"""
title: Optional[str] = None
link: Optional[str] = None
summary: Optional[str] = None
published_date: Optional[datetime] = None
source_name: Optional[str] = None
class Config:
from_attributes = True
# --- API Response Schemas ---
class ArticleInDB(ArticleBase):
"""
Schema for an article when retrieved from the DB (includes ID).
"""
id: int
is_processed: bool = False
processing_error: Optional[str] = None
# --- Event Schema (The main output for the map) ---
class EventLocation(BaseModel):
"""
Simplified location schema used in the final Event output.
This represents the cluster point on the map.
"""
latitude: float
longitude: float
entity_name: Optional[str] = None
class Config:
from_attributes = True
class Event(BaseModel):
"""
The final representation of a news event to be displayed on the map.
This structure is optimized for the front-end (MapView.jsx).
NOTE: In the prototype, one Article will map to one Event for simplicity.
Later, this will be used for clustered news (many Articles -> one Event).
"""
id: int
title: Optional[str] = None
link: Optional[str] = None
summary: Optional[str] = None
published_date: Optional[datetime] = None
source_name: Optional[str] = None
priority: Optional[str] = "medium" # low, medium, high, critical
# Sentiment Analysis fields
sentiment_score: Optional[float] = 0.0 # -1 to 1
sentiment_label: Optional[str] = "neutral" # positive, neutral, negative
# The primary location for the event marker
location: Optional[EventLocation] = None
# (Optional future feature: list of all articles in the cluster)
# articles: List[ArticleBase] = []
class Config:
from_attributes = True