Skip to main content

Google Flights price scraper. Search flights programmatically via the same RPC endpoints the web app uses.

Project description

swoop

Google Flights price scraper. Search flights programmatically using the same RPC endpoints the Google Flights web app uses.

from swoop import search

results = search("JFK", "LAX", "2026-06-01")
for flight in results.best:
    airline = ", ".join(flight.airline_names)
    print(f"${flight.price}{airline}")

Install

pip install swoop-flights

# With CLI (adds `swoop` command)
pip install swoop-flights[cli]

CLI

Search Google Flights directly from the terminal:

# Search flights
swoop search JFK LAX 2026-06-15

# Nonstop, sorted by price
swoop search JFK LAX 2026-06-15 --nonstop --sort cheapest

# Roundtrip, business class
swoop search JFK LAX 2026-06-15 -r 2026-06-22 --cabin business

# JSON output for piping
swoop search JFK LAX 2026-06-15 -o json -q | jq '.results[0].price_usd'

# CSV for spreadsheets
swoop search JFK LAX 2026-06-15 -o csv -q > flights.csv

# Look up a specific flight
swoop flight DL2300 -f JFK -t LAX -d 2026-06-15

# See fare tiers for search result #1
swoop book 1 JFK LAX 2026-06-15

# Filter by airline, time window
swoop search JFK LAX 2026-06-15 -a DL -a UA --depart-after 8 --depart-before 14

Output formats: table (default, colored), json, csv, brief. Use --help on any subcommand for all options.

Python API

One-way search

from swoop import search

results = search("SFO", "JFK", "2026-06-15")

# results.best  — top-ranked flights
# results.other — remaining flights
for flight in results.best:
    print(f"${flight.price}")
    print(f"  {flight.departure_airport}{flight.arrival_airport}")
    print(f"  {flight.airline_names}, {flight.stop_count} stops")
    print(f"  {flight.travel_time} min total")

Roundtrip search

results = search("SFO", "JFK", "2026-06-15", return_date="2026-06-22")
# Price in results is the roundtrip total

Cabin class and filters

from swoop import search, SORT_CHEAPEST

results = search(
    "LAX", "NRT", "2026-06-15",
    cabin="business",       # economy, premium-economy, business, first
    max_stops=0,            # nonstop only
    sort=SORT_CHEAPEST,     # cheapest first
    airlines=["NH", "JL"],  # filter to specific carriers
)

Time window filtering

results = search(
    "JFK", "LHR", "2026-06-15",
    earliest_departure=8,   # depart after 8am
    latest_departure=14,    # depart before 2pm
)

Booking details (fare options)

from swoop import search, get_booking_results

results = search("JFK", "LAX", "2026-06-15")
itinerary = results.best[0]

# Get fare tiers — just pass the itinerary
options = get_booking_results(itinerary)

for opt in options:
    print(f"${opt.price}{opt.brand_label} ({opt.fare_family})")

You can also pass a booking token string with explicit parameters:

options = get_booking_results(
    itinerary.booking_token,
    origin="JFK",
    destination="LAX",
    date="2026-06-15",
    selected_legs=[
        [
            flight.departure_airport,
            f"{flight.departure_date[0]}-{flight.departure_date[1]:02d}-{flight.departure_date[2]:02d}",
            flight.arrival_airport,
            None,
            flight.airline,
            flight.flight_number,
        ]
        for flight in itinerary.flights
    ],
)

Retry and timeout

# Retry up to 3 times on HTTP 429 (rate limit) with exponential backoff
results = search("JFK", "LAX", "2026-06-15", retries=3, timeout=90)

# Same for booking results
options = get_booking_results(itinerary, retries=2, timeout=60)

Flight details

Each Itinerary contains detailed segment data:

results = search("JFK", "LAX", "2026-06-15")
for itinerary in results.best:
    for flight in itinerary.flights:
        print(f"{flight.airline} {flight.flight_number}")
        print(f"  {flight.departure_airport}{flight.arrival_airport}")
        print(f"  Aircraft: {flight.aircraft}")
        print(f"  Legroom: {flight.legroom}")
        if flight.co2_grams:
            print(f"  CO₂: {flight.co2_grams}g")

    if itinerary.carbon_emissions:
        ce = itinerary.carbon_emissions
        print(f"  Route emissions: {ce.difference_percent}% vs typical")

    if results.price_range:
        print(f"  Price range: ${results.price_range.low}–${results.price_range.high}")

Error handling

from swoop import search, SwoopHTTPError, SwoopRateLimitError, SwoopParseError

try:
    results = search("JFK", "LAX", "2026-06-15")
except SwoopRateLimitError:
    print("Rate limited — wait a few minutes")
except SwoopHTTPError as e:
    print(f"HTTP {e.status_code}")
except SwoopParseError as e:
    print(f"Parse error: {e}")

API reference

search(origin, destination, date, **kwargs)

Search Google Flights and return a SearchResult.

Parameter Type Default Description
origin str required Origin IATA code
destination str required Destination IATA code
date str required Departure date (YYYY-MM-DD)
return_date str | None None Return date for roundtrip
cabin str "economy" economy, premium-economy, business, first
adults int 1 Number of adults
max_stops int | None None None=any, 0=nonstop, 1=1 stop, 2=2 stops
sort int SORT_DEPARTURE_TIME Sort order constant
airlines list[str] | None None Filter by airline codes
include_basic_economy bool False Include basic economy fares
timeout int 90 HTTP timeout in seconds
retries int 0 Retries on HTTP 429 with exponential backoff

Returns SearchResult | None. None means no results found.

get_booking_results(itinerary_or_token, **kwargs)

Get fare options for a specific itinerary. Pass an Itinerary object directly, or a booking token string with explicit origin, destination, date, and selected_legs. Returns list[BookingOption] with price, brand_label, brand_code, fare_family, etc. BookingOption supports both attribute access (opt.price) and dict-style access (opt["price"], opt.get("price")).

Result types

  • SearchResultbest: list[Itinerary], other: list[Itinerary], price_range: PriceRange | None
  • Itinerary — Full itinerary with price, flights, layovers, travel_time, booking_token, carbon_emissions
  • Flight — Segment details: airline, flight_number, aircraft, legroom, co2_grams, amenities
  • Layover — Stop info: minutes, airports, is_overnight
  • CarbonEmissionsthis_flight_grams, typical_for_route_grams, difference_percent

Constants

Constant Value Description
SORT_TOP 1 Google's default ranking
SORT_CHEAPEST 2 Cheapest first
SORT_DEPARTURE_TIME 3 By departure time
SORT_ARRIVAL_TIME 4 By arrival time
SORT_DURATION 5 Shortest first

Pricing notes

Use itinerary.price to get the USD price as an integer.

By default, search() excludes basic economy fares so prices reflect Main Cabin. Pass include_basic_economy=True to include them:

results = search("JFK", "LAX", "2026-06-15", include_basic_economy=True)

How it works

Swoop uses Google Flights' internal GetShoppingResults and GetBookingResults RPC endpoints — the same ones the web app calls when you search for flights. Requests are serialized as nested JSON payloads and sent via HTTP POST with browser impersonation (via primp).

Responses are decoded from nested list structures into typed Python dataclasses.

Dependencies

  • primp — HTTP client with browser TLS impersonation
  • protobuf — Protocol buffer serialization
  • click — CLI framework (optional, [cli] extra)
  • rich — Terminal formatting (optional, [cli] extra)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

swoop_flights-0.2.0.tar.gz (33.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

swoop_flights-0.2.0-py3-none-any.whl (39.6 kB view details)

Uploaded Python 3

File details

Details for the file swoop_flights-0.2.0.tar.gz.

File metadata

  • Download URL: swoop_flights-0.2.0.tar.gz
  • Upload date:
  • Size: 33.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for swoop_flights-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2ee03533e866d2c2b4b64176b3cb649910cf76e1a025ae7e2e7eab933c8c64c3
MD5 3df34c0f771dfa19a407ee6e5051dda8
BLAKE2b-256 37f15ca9e0b63054fad05a6e1322a4fd7ace0693e46a8759066fb6ed024a5ee1

See more details on using hashes here.

File details

Details for the file swoop_flights-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: swoop_flights-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 39.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for swoop_flights-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 916875a2ab7c4d0999204ea9b60327504a109b092243caf11653fbfc701c98ac
MD5 3daba8840662e39cc084326c5a5e6223
BLAKE2b-256 28576995819ae206daaaba4d586ff64954bec7a06087172496f946014771a482

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page