Skip to main content

farepy

Multi-source flight search with normalized results, caching, and batch support.

Query Google Flights, Ryanair, and more from a single Python function. Results are normalized into a common format so you can compare prices across sources without worrying about each API's quirks.

Install

pip install farepy[google_flights]   # Google Flights (recommended, broadest coverage)
pip install farepy[ryanair]          # Ryanair direct fares
pip install farepy[all]              # Everything

Usage

Search flights

from farepy import search_flights

# One-way, all available sources
result = search_flights("MRS-REK", "2026-07-01")

for offer in result["offers"][:5]:
    seg = offer["outbound"]["segments"][0]
    print(
        f"{offer['price']} {offer['currency']}  {offer['airlines']}  {seg['departure_time'][:16]}"
    )

Pick a source

# Google Flights only (covers virtually all European LCCs)
result = search_flights("DUB-STN", "2026-07-01", sources=["google_flights"])

# Ryanair direct API (accurate fare-only pricing, includes flight numbers)
result = search_flights("DUB-STN", "2026-07-01", sources=["ryanair"])

# Both in parallel
result = search_flights("DUB-STN", "2026-07-01", sources=["google_flights", "ryanair"])

Round-trip

result = search_flights("DUB-STN", "2026-07-01", return_date="2026-07-08")

for offer in result["offers"][:3]:
    out = offer["outbound"]["segments"][0]
    ret = offer["inbound"]["segments"][0] if offer["inbound"] else None
    print(
        f"{offer['price']} {offer['currency']}  out={out['departure_time'][:16]}",
        end="",
    )
    if ret:
        print(f"  ret={ret['departure_time'][:16]}", end="")
    print()

Filters

result = search_flights(
    "MRS-REK",
    "2026-07-01",
    currency="USD",
    adults=2,
    non_stop=True,
    outbound_departure_after="06:00",
    outbound_departure_before="14:00",
)

Batch search

Search multiple routes and dates in one call. Combinations run sequentially to respect API rate limits; caching avoids re-querying repeated combinations.

from farepy import batch_search

results = batch_search(
    legs=["MRS-REK", "CDG-KEF"],
    departure_dates=["2026-07-01", "2026-07-02"],
    return_dates=["2026-07-08"],
)
# Returns one SearchResult dict per combination (4 in this case)

Or from a text file:

from farepy import batch_from_file

results = batch_from_file("""
# route        depart       return
MRS-REK  2026-07-01  2026-07-08
CDG-KEF  2026-07-15  2026-07-22
DUB-STN  2026-08-01
""")

Cache

Results are cached locally for 24 hours by default (in ~/.local/share/farepy/cache/).

from farepy import list_cached_searches, get_cached_result, clear_cache

# See what's cached
for entry in list_cached_searches():
    print(
        f"{entry['origin']}-{entry['destination']}  {entry['departure_date']}  ({entry['num_offers']} offers)"
    )

# Retrieve a cached result
result = get_cached_result(entry["cache_id"])

# Clear everything
clear_cache()

Disable caching per-search with use_cache=False, or adjust the TTL:

result = search_flights("MRS-REK", "2026-07-01", use_cache=False)
result = search_flights("MRS-REK", "2026-07-01", cache_ttl_hours=1)

Check available sources

from farepy import available_sources

for s in available_sources():
    status = "ready" if s["available"] else "not installed"
    print(f"  {s['name']}: {status}")

Sources

Source Coverage Install Notes
google_flights ~All airlines via Google Flights pip install farepy[google_flights] Protobuf API, no browser needed, broadest coverage
ryanair Ryanair only pip install farepy[ryanair] Direct fare finder API, includes flight numbers
kayak ~All airlines via Kayak pip install farepy[kayak] Experimental, requires Playwright + Chromium

Data model

Every source returns results normalized into the same structure:

SearchResult
  request: SearchRequest     # what was searched
  offers: [FlightOffer]      # sorted by price
  sources_queried: [str]     # which sources responded
  sources_failed: {str: str} # source -> error message
  searched_at: str            # ISO 8601 timestamp

FlightOffer
  source: str                # "google_flights" | "ryanair" | "kayak"
  outbound: Itinerary
  inbound: Itinerary | None  # None for one-way
  price: float
  currency: str
  airlines: [str]

Itinerary
  segments: [Segment]
  duration_minutes: int | None

Segment
  departure_airport: str     # IATA code
  arrival_airport: str       # IATA code
  departure_time: str        # ISO 8601
  arrival_time: str          # ISO 8601 (empty if unavailable)
  carrier: str
  carrier_name: str | None
  flight_number: str | None
  duration_minutes: int | None

Results are returned as plain dicts (via dataclasses.asdict), so they serialize to JSON directly.

Download files

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

Source Distribution

farepy-0.1.6.tar.gz (18.4 kB view details)

Uploaded Source

Built Distribution

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

farepy-0.1.6-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file farepy-0.1.6.tar.gz.

File metadata

  • Download URL: farepy-0.1.6.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for farepy-0.1.6.tar.gz
Algorithm Hash digest
SHA256 96ba6c05b3db3c1218746bd87b3ea73809e464ad6412084a42fcb7df0cd4420e
MD5 d8998ed8bcbddb0c97d1ed8680830065
BLAKE2b-256 9f9ff9ac1a3fb1ecb388779b9667f6ee40ee784070e58637a056b8f1afaf30b6

See more details on using hashes here.

File details

Details for the file farepy-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: farepy-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for farepy-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 787c6c877ac0a2576fa5f77abf4128770cc7b0b5e3b3a1013bae11da0702e3c6
MD5 45b10cae6aa3ea9c4087197d001fd7b7
BLAKE2b-256 399209b6e4a2fb11c179bf7948ad69fcbff1f66ff9c7c389d1f49128be917a1d

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page