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",
)

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.

Metadata

Release files for farepy 0.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for farepy 0.1.8
File Size Uploaded
farepy-0.1.8.tar.gz 20.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for farepy 0.1.8
File Interpreter ABI Platform
farepy-0.1.8-py3-none-any.whl Python 3 none any Details

Total release size: 43.5 kB

Release files / farepy-0.1.8.tar.gz

Download URL farepy-0.1.8.tar.gz
Size 20.8 kB
Tags Source
SHA-256 checksum
How to use checksums
1a4ef48717c4a0d14702cec96e619568a6c44b9a673ecb00127d97a306b467cc
BLAKE2b-256 checksum
How to use checksums
81af0007f7e03c47788df07da9a0446bf1c9212e986a1675f6f979af1a6957fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}

Release files / farepy-0.1.8-py3-none-any.whl

Download URL farepy-0.1.8-py3-none-any.whl
Size 22.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
298c1ac7f07781aafe01fcfe91fc58ae867cf9165fdaa6c90d39b8c3f7094f81
BLAKE2b-256 checksum
How to use checksums
d5161c1a8478c1902770e1975980ef964ad5259afaaa33380027f391fb76d833
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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}

Release history Release notifications | RSS feed

0.1.10

2 release files

0.1.9

2 release files

This release

0.1.8 This release

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release 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