- Python flight price monitor for BER↔EZE and other routes - Adapter pattern for extensibility (Kiwi/Tequila implemented) - OpenClaw alerting integration - Cron-friendly one-shot execution - Full logging of all checks - Graceful handling when API key not set Implements monkey-island/flight-monitor#2
4.4 KiB
Flight Price Monitor
Daily flight price monitor that checks configured routes and alerts when prices drop below threshold.
Features
- ✈️ Monitor multiple flight routes (BER→EZE, etc.)
- 🔔 OpenClaw alerts when prices drop below threshold
- 📊 Extensible adapter pattern for multiple price sources
- 📝 Full logging of all checks (hits and misses)
- 🔧 Cron-friendly one-shot execution
Setup
1. Install Dependencies
pip install -r requirements.txt
2. Get a Kiwi API Key
- Sign up at https://tequila.kiwi.com/portal/login
- Create an API key
- Set environment variable:
export KIWI_API_KEY="your-api-key-here"
Or create a .env file:
KIWI_API_KEY=your-api-key-here
3. Configure Routes
Edit config.json:
{
"routes": [
{
"origin": "BER",
"destination": "EZE",
"trip_type": "round_trip",
"threshold_eur": 700,
"duration_weeks": [2, 3, 4],
"preferred_months": [12, 1, 2, 3],
"monitor_year_round": true
}
],
"check_interval": "daily"
}
Config Fields:
origin,destination: IATA airport codesthreshold_eur: Alert if price drops below this (in EUR)duration_weeks: Trip lengths to search (in weeks)preferred_months: Months to prioritize (1-12)monitor_year_round:trueto search all months,falseto only searchpreferred_months
You can add multiple routes — the monitor will check them all.
4. Run
python monitor.py
Logs are written to monitor.log and stdout.
Scheduling (Cron)
To run daily at 6 AM:
crontab -e
Add:
0 6 * * * cd /path/to/flight-monitor && /usr/bin/python3 monitor.py
Or use OpenClaw cron (recommended):
openclaw cron add \
--schedule '0 6 * * *' \
--command 'cd /path/to/flight-monitor && python monitor.py' \
--name 'Flight Price Monitor'
Architecture
Adapter Pattern
The monitor uses an adapter pattern to support multiple price sources:
adapters/
base.py # Abstract FlightAdapter interface
kiwi.py # Kiwi/Tequila API implementation
Each adapter implements:
search_round_trip()— returns normalized resultsget_name()— adapter name
All results follow this schema:
{
"price_eur": float,
"airline": str,
"departure": datetime,
"return": datetime,
"link": str, # Booking URL
"source": str # Adapter name
}
Adding a New Adapter
- Create
adapters/my_adapter.py:
from adapters.base import FlightAdapter
class MyAdapter(FlightAdapter):
def get_name(self) -> str:
return "MySource"
def search_round_trip(self, origin, destination, departure_date, return_date, **kwargs):
# Your implementation here
# Must return list of normalized results (see schema above)
pass
- Register in
adapters/__init__.py:
from adapters.my_adapter import MyAdapter
__all__ = [..., "MyAdapter"]
- Update
monitor.pyto use your adapter:
adapter = MyAdapter()
You can also make the adapter configurable via config.json if needed.
Alerting
When a price drop is detected, the monitor sends an alert via OpenClaw:
openclaw system event --text "✈️ BER→EZE €650 on 2026-04-15 → 2026-04-29 (Lufthansa) — below €700! https://..." --mode now
This routes the alert to your configured OpenClaw channels (Telegram, Discord, Signal, etc.).
Logs
All checks are logged to monitor.log with timestamps:
2026-03-21 18:00:00 [INFO] === Flight Monitor Starting ===
2026-03-21 18:00:00 [INFO] Checking route BER→EZE (threshold: €700)
2026-03-21 18:00:01 [INFO] 2026-04-15 → 2026-04-29: €850 (Lufthansa)
2026-03-21 18:00:02 [INFO] 2026-05-01 → 2026-05-15: €620 (Air France)
2026-03-21 18:00:02 [INFO] Alert sent via OpenClaw
2026-03-21 18:00:03 [INFO] === Flight Monitor Complete ===
Troubleshooting
"KIWI_API_KEY environment variable not set"
- Set the
KIWI_API_KEYenv var (see Setup step 2) - The monitor will exit gracefully (not crash) if the key is missing
No results returned
- Check
monitor.logfor API errors - Verify your IATA codes are correct (e.g., "BER" not "Berlin")
- Try a broader date range (increase
duration_weeksorpreferred_months)
OpenClaw alert not sent
- Verify
openclawCLI is in PATH - Check OpenClaw is running:
openclaw status - Look for error messages in
monitor.log
License
MIT