Spaces:
Sleeping
Sleeping
| """ | |
| AQI Intelligence Engine — Central Configuration | |
| Supports local development and HuggingFace Spaces deployment. | |
| """ | |
| import os | |
| import torch | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| # Load local environment variables from .env file if it exists | |
| load_dotenv(dotenv_path=Path(__file__).parent / ".env") | |
| # ============================================================================= | |
| # Environment Detection | |
| # ============================================================================= | |
| IS_HF_SPACE = os.getenv("SPACE_ID") is not None | |
| ENV = os.getenv("ENV", "development") | |
| # ============================================================================= | |
| # ZeroGPU & Dynamic Device Configuration | |
| # ============================================================================= | |
| try: | |
| import spaces | |
| HAS_SPACES = True | |
| except ImportError: | |
| HAS_SPACES = False | |
| def get_device() -> str: | |
| """Dynamically return 'cuda' if CUDA/ZeroGPU is active, otherwise 'cpu'.""" | |
| return "cuda" if torch.cuda.is_available() else "cpu" | |
| def get_torch_dtype(): | |
| """Return torch.float16 for GPU or torch.float32 for CPU.""" | |
| return torch.float16 if get_device() == "cuda" else torch.float32 | |
| # Backward compatibility properties | |
| DEVICE = get_device() | |
| TORCH_DTYPE = get_torch_dtype() | |
| # ============================================================================= | |
| # Paths | |
| # ============================================================================= | |
| BASE_DIR = Path(__file__).parent | |
| MODELS_DIR = Path(os.getenv("MODELS_DIR", str(BASE_DIR / "models"))) | |
| MODELS_DIR.mkdir(parents=True, exist_ok=True) | |
| # HuggingFace cache — use /tmp on Spaces (writable), local dir otherwise | |
| HF_CACHE_DIR = Path("/tmp/hf_cache") if IS_HF_SPACE else MODELS_DIR / "hf_cache" | |
| HF_CACHE_DIR.mkdir(parents=True, exist_ok=True) | |
| os.environ["HF_HOME"] = str(HF_CACHE_DIR) | |
| os.environ["TRANSFORMERS_CACHE"] = str(HF_CACHE_DIR) | |
| # ============================================================================= | |
| # Model Identifiers (HuggingFace Hub) | |
| # ============================================================================= | |
| MODELS = { | |
| "timesfm": "google/timesfm-2.5-200m-pytorch", | |
| "florence2": "microsoft/Florence-2-base", | |
| "grounding_dino": "IDEA-Research/grounding-dino-tiny", | |
| "sam2": "facebook/sam2.1-hiera-small", | |
| } | |
| # ============================================================================= | |
| # Forecast Configuration | |
| # ============================================================================= | |
| FORECAST_CONFIG = { | |
| "max_context": 1024, # Max context length for TimesFM 2.5 | |
| "max_horizon": 128, # Max forecast horizon | |
| "horizon_24h": 24, # Steps for 24-hour forecast | |
| "horizon_48h": 48, # Steps for 48-hour forecast | |
| "horizon_72h": 72, # Steps for 72-hour forecast | |
| } | |
| # ============================================================================= | |
| # Vision Configuration | |
| # ============================================================================= | |
| VISION_CONFIG = { | |
| "florence2_max_tokens": 1024, | |
| "grounding_dino_box_threshold": 0.3, | |
| "grounding_dino_text_threshold": 0.25, | |
| "pollution_prompts": ( | |
| "smoke. fire. construction site. factory chimney. " | |
| "dust cloud. burning waste. heavy vehicles. industrial plant. " | |
| "brick kiln. open burning." | |
| ), | |
| } | |
| # ============================================================================= | |
| # SAM2 Configuration | |
| # ============================================================================= | |
| SAM2_CONFIG = { | |
| "points_per_batch": 32, | |
| "pred_iou_thresh": 0.7, | |
| "stability_score_thresh": 0.85, | |
| } | |
| # ============================================================================= | |
| # Data API Keys & URLs | |
| # ============================================================================= | |
| API_KEYS = { | |
| "openweather": os.getenv("OPENWEATHER_API_KEY", ""), | |
| "mappls": os.getenv("MAPPLS_API_KEY", ""), | |
| "sentinel_hub": os.getenv("SENTINEL_HUB_API_KEY", ""), | |
| "nasa_firms": os.getenv("NASA_FIRMS_API_KEY", ""), | |
| # CPCB (Central Pollution Control Board) — data.gov.in | |
| "cpcb_api_key": os.getenv("CPCB_API_KEY", "579b464db66ec23bdd000001cdd3946e44ce4aad7209ff7b23ac571b"), | |
| # Mappls (MapMyIndia) OAuth2 credentials | |
| "mappls_client_id": os.getenv("MAPPLS_CLIENT_ID", ""), | |
| "mappls_client_secret": os.getenv("MAPPLS_CLIENT_SECRET", ""), | |
| # Planet Insight Platform (replaces deprecated Sentinel Hub) | |
| "planet_api_key": os.getenv("SENTINEL_HUB_API_KEY", ""), # PLAK key | |
| "planet_client_id": os.getenv("PLANET_INSIGHT_CLIENT_ID", ""), | |
| "planet_client_secret": os.getenv("PLANET_INSIGHT_CLIENT_SECRET", ""), | |
| # TomTom | |
| "tomtom": os.getenv("TOMTOM_API_KEY", ""), | |
| # Provider selection | |
| "traffic_provider": os.getenv("TRAFFIC_PROVIDER", "mappls").lower(), | |
| } | |
| API_URLS = { | |
| "openweather_aqi": "http://api.openweathermap.org/data/2.5/air_pollution", | |
| "openweather_aqi_history": "http://api.openweathermap.org/data/2.5/air_pollution/history", | |
| "openweather_aqi_forecast": "http://api.openweathermap.org/data/2.5/air_pollution/forecast", | |
| "open_meteo": "https://api.open-meteo.com/v1/forecast", | |
| "open_meteo_historical": "https://archive-api.open-meteo.com/v1/archive", | |
| "overpass": "https://overpass-api.de/api/interpreter", | |
| "nasa_firms": "https://firms.modaps.eosdis.nasa.gov/api/area/csv", | |
| "worldpop": "https://www.worldpop.org/rest/data", | |
| # CPCB (data.gov.in) | |
| "cpcb_stations": "https://api.data.gov.in/resource/3b01bcb8-0b14-4abf-b6f2-c1bfd384ba69", | |
| # Planet Insight / Sentinel Hub APIs | |
| "sentinel_hub_auth": "https://services.sentinel-hub.com/auth/realms/main/protocol/openid-connect/token", | |
| "sentinel_hub_process": "https://services.sentinel-hub.com/api/v1/process", | |
| "sentinel_hub_catalog": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/search", | |
| "planet_data": "https://api.planet.com/data/v1", | |
| "planet_basemaps": "https://api.planet.com/basemaps/v1/mosaics", | |
| # TomTom | |
| "tomtom_traffic": "https://api.tomtom.com/traffic/services/4/flowSegmentData/absolute/10/json", | |
| } | |
| # ============================================================================= | |
| # Cache TTL Settings (in seconds) | |
| # ============================================================================= | |
| CACHE_TTL = { | |
| "aqi": 300, # 5 minutes | |
| "weather": 900, # 15 minutes | |
| "traffic": 120, # 2 minutes | |
| "satellite": 3600, # 1 hour | |
| "fire": 600, # 10 minutes | |
| "landuse": 86400, # 24 hours | |
| "population": 86400, # 24 hours | |
| "geospatial": 86400, # 24 hours | |
| "cpcb": 1800, # 30 minutes (CPCB stations update hourly) | |
| } | |
| # ============================================================================= | |
| # India AQI Breakpoints (NAQI Standard) | |
| # ============================================================================= | |
| AQI_BREAKPOINTS = { | |
| "good": (0, 50), | |
| "satisfactory": (51, 100), | |
| "moderate": (101, 200), | |
| "poor": (201, 300), | |
| "very_poor": (301, 400), | |
| "severe": (401, 500), | |
| } | |
| AQI_CATEGORIES = { | |
| "good": {"color": "#00B050", "risk": "minimal", "advisory": "Air quality is good. No precautions needed."}, | |
| "satisfactory": {"color": "#92D050", "risk": "low", "advisory": "Acceptable for most. Unusually sensitive may notice symptoms."}, | |
| "moderate": {"color": "#FFC000", "risk": "moderate", "advisory": "May cause breathing discomfort to sensitive groups."}, | |
| "poor": {"color": "#FF6600", "risk": "high", "advisory": "May cause breathing discomfort to people on prolonged exposure."}, | |
| "very_poor": {"color": "#FF0000", "risk": "very_high", "advisory": "May cause respiratory illness on prolonged exposure."}, | |
| "severe": {"color": "#800000", "risk": "critical", "advisory": "Serious health effects. Everyone may experience problems."}, | |
| } | |
| # ============================================================================= | |
| # Server Configuration | |
| # ============================================================================= | |
| SERVER_CONFIG = { | |
| "host": "0.0.0.0", | |
| "port": int(os.getenv("PORT", 7860)), | |
| "reload": ENV == "development", | |
| "workers": 1, # Single worker for model memory efficiency | |
| } | |