Spaces:
Sleeping
Sleeping
| """Alert management endpoints""" | |
| from fastapi import APIRouter, HTTPException, Query, Path, Body | |
| from typing import List, Dict, Optional | |
| from datetime import datetime | |
| import uuid | |
| router = APIRouter() | |
| # In-memory storage | |
| alerts_db = {} | |
| alerts_list = [] | |
| async def get_alerts( | |
| active_only: bool = Query(True, description="Return only active alerts"), | |
| zone: Optional[str] = Query(None, description="Filter by zone"), | |
| level: Optional[str] = Query(None, description="Filter by alert level") | |
| ): | |
| """Get alerts""" | |
| alerts = [a for a in alerts_list if not active_only or a.get('active', True)] | |
| if zone: | |
| alerts = [a for a in alerts if a.get('zone') == zone] | |
| if level: | |
| alerts = [a for a in alerts if a.get('level') == level] | |
| return alerts | |
| async def get_active_alerts(): | |
| """Get currently active alerts""" | |
| return [a for a in alerts_list if a.get('active', False)] | |
| async def get_alert( | |
| alert_id: str = Path(..., description="Alert ID") | |
| ): | |
| """Get alert by ID""" | |
| if alert_id not in alerts_db: | |
| raise HTTPException(status_code=404, detail="Alert not found") | |
| return alerts_db[alert_id] | |
| async def create_alert( | |
| alert_data: Dict = Body(...) | |
| ): | |
| """Create new alert""" | |
| alert_id = str(uuid.uuid4()) | |
| alert = { | |
| "id": alert_id, | |
| "created_at": datetime.utcnow().isoformat(), | |
| "updated_at": datetime.utcnow().isoformat(), | |
| "active": True, | |
| "acknowledged": False, | |
| **alert_data | |
| } | |
| alerts_db[alert_id] = alert | |
| alerts_list.append(alert) | |
| return alert | |
| async def acknowledge_alert( | |
| alert_id: str = Path(...), | |
| user: str = Query(..., description="User acknowledging the alert") | |
| ): | |
| """Acknowledge an alert""" | |
| if alert_id not in alerts_db: | |
| raise HTTPException(status_code=404, detail="Alert not found") | |
| alerts_db[alert_id]["acknowledged"] = True | |
| alerts_db[alert_id]["acknowledged_by"] = user | |
| alerts_db[alert_id]["acknowledged_at"] = datetime.utcnow().isoformat() | |
| alerts_db[alert_id]["updated_at"] = datetime.utcnow().isoformat() | |
| return alerts_db[alert_id] | |
| async def resolve_alert( | |
| alert_id: str = Path(...) | |
| ): | |
| """Resolve/cancel an alert""" | |
| if alert_id not in alerts_db: | |
| raise HTTPException(status_code=404, detail="Alert not found") | |
| alerts_db[alert_id]["active"] = False | |
| alerts_db[alert_id]["resolved_at"] = datetime.utcnow().isoformat() | |
| alerts_db[alert_id]["updated_at"] = datetime.utcnow().isoformat() | |
| return alerts_db[alert_id] | |
| async def get_alert_statistics(): | |
| """Get alert statistics""" | |
| active = len([a for a in alerts_list if a.get('active', False)]) | |
| acknowledged = len([a for a in alerts_list if a.get('acknowledged', False)]) | |
| return { | |
| "total_alerts": len(alerts_list), | |
| "active_alerts": active, | |
| "acknowledged_alerts": acknowledged, | |
| "by_level": { | |
| "LOW": len([a for a in alerts_list if a.get('level') == 'LOW']), | |
| "MODERATE": len([a for a in alerts_list if a.get('level') == 'MODERATE']), | |
| "HIGH": len([a for a in alerts_list if a.get('level') == 'HIGH']), | |
| "SEVERE": len([a for a in alerts_list if a.get('level') == 'SEVERE']), | |
| "CATASTROPHIC": len([a for a in alerts_list if a.get('level') == 'CATASTROPHIC']) | |
| } | |
| } | |
| async def check_thresholds( | |
| zone: str = Query(..., description="Coastal zone"), | |
| chi: float = Query(..., description="CHI value") | |
| ): | |
| """Check if thresholds are crossed and create alert if needed""" | |
| # Determine alert level based on CHI | |
| if chi < 0.30: | |
| level = "LOW" | |
| message = f"Monitoring mode for {zone}" | |
| elif chi < 0.60: | |
| level = "MODERATE" | |
| message = f"Tsunami advisory for {zone}" | |
| elif chi < 0.80: | |
| level = "HIGH" | |
| message = f"Tsunami WARNING for {zone} - prepare evacuation" | |
| elif chi < 1.00: | |
| level = "SEVERE" | |
| message = f"SEVERE TSUNAMI THREAT for {zone} - EVACUATE IMMEDIATELY" | |
| else: | |
| level = "CATASTROPHIC" | |
| message = f"CATASTROPHIC TSUNAMI for {zone} - maximum impact expected" | |
| # Create alert if level is >= MODERATE | |
| if chi >= 0.30: | |
| alert = await create_alert({ | |
| "zone": zone, | |
| "chi": chi, | |
| "level": level, | |
| "message": message | |
| }) | |
| return { | |
| "alert_created": True, | |
| "threshold_crossed": True, | |
| "alert": alert | |
| } | |
| return { | |
| "alert_created": False, | |
| "threshold_crossed": False, | |
| "level": level, | |
| "message": message | |
| } | |