Files
weather-alerts/docs/implementation_roadmap.md
2026-01-26 15:08:24 -06:00

4.7 KiB

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:

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:

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

python run.py

Cron Integration

Add to crontab for hourly checks:

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