Files
ciaovolo/flight-comparator
domverse cde496ad48
All checks were successful
Deploy / deploy (push) Successful in 11s
infra: fix CORS, add monitoring and dashboard labels
- Set ALLOWED_ORIGINS to production domain (fixes CORS for the web app)
- Add LOG_LEVEL=INFO to backend
- Add AutoKuma monitoring labels for Uptime Kuma auto-discovery
- Add Homepage dashboard labels (Productivity group)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:59:28 +01:00
..

Flight Airport Comparator CLI ✈️

A Python CLI tool that helps you find the best departure airport for your destination by comparing direct flights from all airports in a country.

NOW WITH WORKING FLIGHT DATA! Uses fast-flights v3.0rc1 with SOCS cookie integration to successfully bypass Google's consent page.

What It Does

Answers the question: "I want to fly to [DESTINATION]. Which airport in [COUNTRY] should I depart from — and when in the next 6 months does the best route open up?"

Key Features

  • 🌍 Multi-Airport Comparison: Automatically scans all airports in a country
  • 📅 Seasonal Scanning: Discover new routes and price trends across 6 months
  • Direct Flights Only: Filters out connections automatically
  • 🆕 New Route Detection: Highlights routes that appear in later months
  • 🎨 Beautiful Tables: Rich terminal output with color and formatting
  • 🚀 Fast & Concurrent: Parallel API requests for quick results
  • SOCS Cookie Integration: Bypasses Google consent page for real flight data!
  • 💾 Smart Caching: SQLite cache reduces API calls and prevents rate limiting

Installation

# Clone or download this repository
cd flight-comparator

# Install fast-flights v3.0rc1 (REQUIRED for working flight data)
pip install --upgrade git+https://github.com/AWeirdDev/flights.git

# Install other dependencies
pip install -r requirements.txt

# Build airport database (runs automatically on first use)
python airports.py

Requirements

  • Python 3.10+
  • fast-flights v3.0rc1 (install from GitHub, not PyPI)
  • Dependencies: click, rich, python-dateutil, primp

Quick Test

Verify it works with real flight data:

python test_v3_with_cookies.py

Expected output:

✅ SUCCESS! Found 1 flight option(s):
1. Ryanair
   Price: €89
   BER → BRI
   06:10 - 08:20 (130 min)

Usage

Basic Examples

Single date query:

python main.py --to JFK --country DE --date 2026-06-15

Seasonal scan (6 months):

python main.py --to JFK --country DE

Custom airport list:

python main.py --to JFK --from FRA,MUC,BER --date 2026-06-15

Dry run (preview without API calls):

python main.py --to JFK --country DE --dry-run

All Options

Options:
  --to TEXT                Destination airport IATA code (e.g., JFK) [required]
  --country TEXT           Origin country ISO code (e.g., DE, US)
  --date TEXT              Departure date YYYY-MM-DD. Omit for seasonal scan.
  --window INTEGER         Months to scan in seasonal mode (default: 6)
  --seat [economy|premium|business|first]
                           Cabin class (default: economy)
  --adults INTEGER         Number of passengers (default: 1)
  --sort [price|duration]  Sort order (default: price)
  --from TEXT              Comma-separated IATA codes (overrides --country)
  --top INTEGER            Max results per airport (default: 3)
  --output [table|json|csv]
                           Output format (default: table)
  --workers INTEGER        Concurrency level (default: 5)
  --dry-run                List airports and dates without API calls
  --help                   Show this message and exit.

Advanced Examples

Business class, sorted by duration:

python main.py --to SIN --country DE --date 2026-07-20 --seat business --sort duration

Seasonal scan with 12-month window:

python main.py --to LAX --country GB --window 12

Output as JSON:

python main.py --to CDG --country NL --date 2026-05-10 --output json

Force fresh queries (disable cache):

python main.py --to JFK --country DE --no-cache

Custom cache threshold (48 hours):

python main.py --to JFK --country DE --cache-threshold 48

How It Works

  1. Airport Resolution: Loads airports for your country from the OpenFlights dataset
  2. Date Resolution: Single date or generates monthly dates (15th of each month)
  3. Flight Search: Queries Google Flights via fast-flights for each airport × date
  4. Filtering: Keeps only direct flights (0 stops)
  5. Analysis: Detects new connections in seasonal mode
  6. Formatting: Presents results in beautiful tables, JSON, or CSV

Seasonal Scan Mode

When you omit --date, the tool automatically:

  • Queries one date per month (default: 15th) across the next 6 months
  • Detects routes that appear in later months but not earlier ones
  • Tags new connections with NEW indicator
  • Helps you discover seasonal schedule changes

This is especially useful for:

  • Finding when summer routes start
  • Discovering new airline schedules
  • Comparing price trends over time

Country Codes

Common country codes:

  • 🇩🇪 DE (Germany)
  • 🇺🇸 US (United States)
  • 🇬🇧 GB (United Kingdom)
  • 🇫🇷 FR (France)
  • 🇪🇸 ES (Spain)
  • 🇮🇹 IT (Italy)
  • 🇳🇱 NL (Netherlands)
  • 🇦🇺 AU (Australia)
  • 🇯🇵 JP (Japan)

[Full list of supported countries available in data/airports_by_country.json]

Architecture

flight-comparator/
├── main.py              # CLI entrypoint (Click)
├── date_resolver.py     # Date logic & new connection detection
├── airports.py          # Airport data management
├── searcher.py          # Flight search with concurrency
├── formatter.py         # Output formatting (Rich tables, JSON, CSV)
├── data/
│   └── airports_by_country.json  # Generated airport database
├── tests/               # Smoke tests for each module
└── requirements.txt

Caching System

The tool uses SQLite to cache flight search results, reducing API calls and preventing rate limiting.

How It Works

  • Automatic caching: All search results are saved to data/flight_cache.db
  • Cache hits: If a query was made recently, results are retrieved instantly from cache
  • Default threshold: 24 hours (configurable with --cache-threshold)
  • Cache indicator: Shows 💾 Cache hit: when using cached data

Cache Management

View cache statistics:

python cache_admin.py stats

Clean old entries (30+ days):

python cache_admin.py clean --days 30

Clear entire cache:

python cache_admin.py clear-all

CLI Options

  • --cache-threshold N: Set cache validity in hours (default: 24)
  • --no-cache: Force fresh API queries, ignore cache

Benefits

  • Instant results for repeated queries (0.0s vs 2-3s per query)
  • 🛡️ Rate limit protection: Avoid hitting Google's API limits
  • 💰 Reduced API load: Fewer requests = lower risk of being blocked
  • 📊 Historical data: Cache preserves price history

Configuration

Key constants in date_resolver.py:

SEARCH_WINDOW_MONTHS = 6   # Default seasonal scan window
SAMPLE_DAY_OF_MONTH = 15   # Which day to query each month

You can override the window at runtime with --window N.

Limitations

  • ⚠️ Relies on fast-flights scraping Google Flights (subject to rate limits and anti-bot measures)
  • ⚠️ EU users may encounter consent flow issues (use fallback mode, which is default)
  • ⚠️ Prices are as shown on Google Flights, not final booking prices
  • ⚠️ Seasonal scan queries only the 15th of each month as a sample
  • ⚠️ Large scans (many airports × months) can take 2-3 minutes

Performance

Single date scan:

  • ~20 airports: < 30s (with --workers 5)

Seasonal scan (6 months):

  • ~20 airports: 2-3 minutes
  • Total requests: 120 (20 × 6)

Testing

Run smoke tests for each module:

cd tests
python test_date_resolver.py
python test_airports.py
python test_searcher.py
python test_formatter.py

Troubleshooting

"fast-flights not installed"

pip install fast-flights

"Country code 'XX' not found"

  • Check the country code is correct (2-letter ISO code)
  • Verify it exists in data/airports_by_country.json

Slow performance

  • Reduce --window for seasonal scans
  • Increase --workers (but watch out for rate limiting)
  • Use --from with specific airports instead of entire country

No results found

  • Try a different date (some routes are seasonal)
  • Check the destination airport code is correct
  • Verify there actually are direct flights on that route

License

This tool is for personal use and research. Respect Google Flights' terms of service and rate limits.

Credits