# Weather Alerts - Implementation Roadmap ## Overview This document captures the implementation plan and decisions for the weather alerts application. ## Architecture ### Directory Structure ``` weather_alerts/ ├── app/ │ ├── __init__.py │ ├── main.py # Entry point - orchestration │ ├── config/ │ │ ├── __init__.py │ │ ├── loader.py # Typed YAML config loader │ │ ├── settings.yaml # Main configuration │ │ └── settings.example.yaml # Example (no secrets) │ ├── models/ │ │ ├── __init__.py │ │ ├── weather.py # Weather data models │ │ ├── alerts.py # Alert rule/triggered alert models │ │ └── state.py # Deduplication state models │ ├── services/ │ │ ├── __init__.py │ │ ├── weather_service.py # VisualCrossing API client │ │ ├── notification_service.py # ntfy sender │ │ ├── rule_engine.py # Alert rule evaluation │ │ └── state_manager.py # Deduplication persistence │ └── utils/ │ ├── __init__.py │ ├── http_client.py # Centralized HTTP wrapper │ └── logging_config.py # Structlog setup ├── tests/ ├── data/ # State files (gitignored) ├── .env.example ├── .gitignore ├── requirements.txt └── run.py # Simple runner ``` ## Key Design Decisions ### 1. One-Shot Execution The application is designed for cron-based scheduling rather than internal scheduling. Each run: 1. Fetches current forecast 2. Evaluates rules 3. Sends new alerts 4. Exits ### 2. Secrets Management - API keys and tokens stored in environment variables only - `.env` file for local development (gitignored) - No secrets in YAML configuration ### 3. Atomic State Persistence State file writes use write-to-temp-then-rename pattern for crash safety: ```python fd, temp_path = tempfile.mkstemp(...) # Write to temp file os.replace(temp_path, actual_path) # Atomic rename ``` ### 4. Deduplication Strategy Alerts are deduplicated using the key format: `{alert_type}:{forecast_hour}` This allows: - Re-alerting for different forecast hours - Preventing duplicate alerts for the same condition/hour - Configurable deduplication window (default 24 hours) ### 5. Typed Throughout - Dataclasses for all data models - Type hints on all functions - Configuration loaded into typed dataclasses ### 6. Centralized HTTP Single `HttpClient` wrapper provides: - Consistent timeouts - Automatic retries with exponential backoff - Structured logging - Shared across services ## Alert Rules ### Temperature - **Low temperature**: Alert when forecast drops below threshold (default: 32°F) - **High temperature**: Alert when forecast exceeds threshold (default: 100°F) ### Precipitation - Alert when precipitation probability exceeds threshold (default: 70%) ### Wind - **Sustained wind**: Alert when speed exceeds threshold (default: 25 mph) - **Wind gusts**: Alert when gusts exceed threshold (default: 40 mph) ### Severe Weather - Forwards any severe weather alerts from the VisualCrossing API ## Execution Flow ``` 1. Load configuration (YAML + environment) 2. Configure logging (structlog) 3. Initialize services 4. Fetch weather forecast 5. Evaluate alert rules 6. Filter duplicate alerts 7. Send new alerts via ntfy 8. Record sent alerts 9. Purge old records 10. Save state 11. Exit (0=success, 1=error) ``` ## Dependencies | Package | Purpose | |---------|---------| | requests | HTTP client | | structlog | Structured logging | | python-dotenv | Environment variable loading | | PyYAML | Configuration parsing | | pytest | Testing | | responses | HTTP mocking for tests | ## Testing Run tests with: ```bash pytest tests/ -v ``` Test coverage: - Rule engine: Temperature, precipitation, wind, severe weather rules - Weather service: API parsing, error handling - State manager: Persistence, deduplication, purging ## Usage ### Setup 1. Copy `.env.example` to `.env` and fill in API keys 2. Copy `app/config/settings.example.yaml` to `app/config/settings.yaml` (optional customization) 3. Install dependencies: `pip install -r requirements.txt` ### Running ```bash python run.py ``` ### Cron Integration Add to crontab for hourly checks: ```cron 0 * * * * cd /path/to/weather_alerts && /path/to/python run.py >> /var/log/weather-alerts.log 2>&1 ``` ## Future Enhancements Potential additions if needed: - Additional alert types (UV index, humidity, etc.) - Multiple location support - Alert cooldown periods - Notification channels beyond ntfy - Web dashboard for status