Spaces:
Sleeping
Sleeping
Dhruva P Gowda
Deploy ShockMap MVP: High-fidelity UI overhaul, animated graph particles, live GDELT ingestion, and production scaffolding
f59a149 Download backend/app/data_loader.py from shield137/shockmap-api: direct link, hf CLI and curl.
- Browser
- Download file 5.21 kB
-
https://huggingface.co/spaces/shield137/shockmap-api/resolve/main/backend/app/data_loader.py
- Command line
-
hf download hf://spaces/shield137/shockmap-api/backend/app/data_loader.py
-
curl -L -o data_loader.py https://huggingface.co/spaces/shield137/shockmap-api/resolve/main/backend/app/data_loader.py
5.21 kB
| """ | |
| Service for loading seed data from JSON files and providing in-memory access. | |
| """ | |
| import json | |
| import logging | |
| import os | |
| from typing import List, Dict, Any, Optional | |
| from .models.drug import Drug, APINode | |
| from .models.alert import Alert, AlertSeverity | |
| from .models.graph import GraphEdge | |
| logger = logging.getLogger(__name__) | |
| class DataLoader: | |
| """ | |
| Handles the ingestion and validation of seed data files. | |
| Serves as the primary in-memory data store for the application. | |
| """ | |
| def __init__(self, seed_dir: str): | |
| self.seed_dir = seed_dir | |
| self._drugs: List[Drug] = [] | |
| self._apis: List[APINode] = [] | |
| self._dependencies: List[GraphEdge] = [] | |
| self._alerts: List[Alert] = [] | |
| self._epb_notices: List[Dict[str, Any]] = [] | |
| self._fda_alerts: List[Dict[str, Any]] = [] | |
| self._historical_disruptions: List[Dict[str, Any]] = [] | |
| self._policy_snippets: List[Dict[str, Any]] = [] | |
| self._china_provinces: List[Dict[str, Any]] = [] | |
| self._india_states: List[Dict[str, Any]] = [] | |
| def _load_json(self, filename: str) -> Any: | |
| """Helper to load a JSON file from the seed directory.""" | |
| path = os.path.join(self.seed_dir, filename) | |
| if not os.path.exists(path): | |
| raise RuntimeError(f"Required seed file missing: {path}") | |
| try: | |
| with open(path, "r", encoding="utf-8") as f: | |
| return json.load(f) | |
| except json.JSONDecodeError as e: | |
| raise RuntimeError(f"Failed to parse JSON file {path}: {str(e)}") | |
| def load_all(self): | |
| """ | |
| Loads all required seed files into memory and validates them against Pydantic models. | |
| This should be called during application startup. | |
| """ | |
| # Load and validate models | |
| self._drugs = [Drug(**item) for item in self._load_json("drugs.json")] | |
| self._apis = [APINode(**item) for item in self._load_json("apis.json")] | |
| self._dependencies = [GraphEdge(**item) for item in self._load_json("dependencies.json")] | |
| self._alerts = [Alert(**item) for item in self._load_json("alerts.json")] | |
| # Load raw data dictionaries | |
| self._epb_notices = self._load_json("epb_notices.json") | |
| self._fda_alerts = self._load_json("fda_alerts.json") | |
| self._historical_disruptions = self._load_json("historical_disruptions.json") | |
| self._policy_snippets = self._load_json("policy_snippets.json") | |
| self._china_provinces = self._load_json("china_provinces.json") | |
| self._india_states = self._load_json("india_states.json") | |
| logger.info( | |
| f"🚀 Loaded {len(self._drugs)} drugs, {len(self._apis)} APIs, " | |
| f"{len(self._dependencies)} edges, {len(self._alerts)} alerts, " | |
| f"{len(self._policy_snippets)} policy snippets, {len(self._china_provinces)} provinces." | |
| ) | |
| def get_drugs(self) -> List[Drug]: | |
| """Returns the full list of drugs.""" | |
| return self._drugs | |
| def get_drug(self, drug_id: str) -> Optional[Drug]: | |
| """Returns a specific drug by its ID.""" | |
| return next((d for d in self._drugs if d.id == drug_id), None) | |
| def get_apis(self) -> List[APINode]: | |
| """Returns the full list of API nodes.""" | |
| return self._apis | |
| def get_dependencies(self) -> List[GraphEdge]: | |
| """Returns the full list of graph edges (dependencies).""" | |
| return self._dependencies | |
| def get_alerts( | |
| self, | |
| severity: Optional[AlertSeverity] = None, | |
| drug_id: Optional[str] = None, | |
| limit: int = 50, | |
| offset: int = 0 | |
| ) -> List[Alert]: | |
| """ | |
| Filters and returns alerts with optional severity and drug filtering. | |
| Supports pagination via limit and offset. | |
| """ | |
| filtered = self._alerts | |
| if severity: | |
| filtered = [a for a in filtered if a.severity == severity] | |
| if drug_id: | |
| filtered = [a for a in filtered if drug_id in a.affected_drugs] | |
| return filtered[offset : offset + limit] | |
| def get_alert(self, alert_id: str) -> Optional[Alert]: | |
| """Returns a specific alert by its ID.""" | |
| return next((a for a in self._alerts if a.id == alert_id), None) | |
| def get_policy_snippets(self) -> List[Dict[str, Any]]: | |
| """Returns the list of parsed policy snippets.""" | |
| return self._policy_snippets | |
| def get_historical_disruptions(self) -> List[Dict[str, Any]]: | |
| """Returns historical disruption event logs.""" | |
| return self._historical_disruptions | |
| def get_epb_notices(self) -> List[Dict[str, Any]]: | |
| """Returns raw Hebei EPB notices.""" | |
| return self._epb_notices | |
| def get_fda_alerts(self) -> List[Dict[str, Any]]: | |
| """Returns raw FDA import/warning alerts.""" | |
| return self._fda_alerts | |
| def get_china_provinces(self) -> List[Dict[str, Any]]: | |
| """Returns the list of China provinces with coordinates.""" | |
| return self._china_provinces | |
| def get_india_states(self) -> List[Dict[str, Any]]: | |
| """Returns the list of India states with coordinates.""" | |
| return self._india_states | |