Skip to content

Search API Reference

The main search functionality for finding specific flights.

SearchFlights

fli.search.flights.SearchFlights()

Flight search implementation using Google Flights' API.

This class handles searching for specific flights with detailed filters, parsing the results into structured data models.

Currently only supports one-way flights.

Initialize the search client for flight searches.

Source code in fli/search/flights.py
def __init__(self):
    """Initialize the search client for flight searches."""
    self.client = get_client()

BASE_URL = 'https://www.google.com/_/FlightsFrontendUi/data/travel.frontend.flights.FlightsFrontendService/GetShoppingResults' class-attribute instance-attribute

DEFAULT_HEADERS = {'content-type': 'application/x-www-form-urlencoded;charset=UTF-8'} class-attribute instance-attribute

client = get_client() instance-attribute

search(filters: SearchFlightsFilters) -> list[FlightResult] | None

Search for flights using the provided filters.

PARAMETER DESCRIPTION
filters

Search parameters including airports, dates, and preferences

TYPE: SearchFlightsFilters

RETURNS DESCRIPTION
list[FlightResult] | None

List of FlightResult objects containing flight details, or None if no results

RAISES DESCRIPTION
Exception

If the search fails or returns invalid data

Source code in fli/search/flights.py
def search(self, filters: SearchFlightsFilters) -> list[FlightResult] | None:
    """Search for flights using the provided filters.

    Args:
        filters: Search parameters including airports, dates, and preferences

    Returns:
        List of FlightResult objects containing flight details, or None if no results

    Raises:
        Exception: If the search fails or returns invalid data

    """
    search_filters = self._create_flight_search_data(filters)
    encoded_filters = search_filters.encode()

    try:
        response = self.client.post(
            url=self.BASE_URL,
            data=f"f.req={encoded_filters}",
            impersonate="chrome",
            allow_redirects=True,
        )
        response.raise_for_status()

        parsed = json.loads(response.text.lstrip(")]}'"))[0][2]
        if not parsed:
            return None

        encoded_filters = json.loads(parsed)
        flights_data = [
            item
            for i in [2, 3]
            if isinstance(encoded_filters[i], list)
            for item in encoded_filters[i][0]
        ]
        flights = [self._parse_flights_data(flight) for flight in flights_data]
        return flights

    except Exception as e:
        raise Exception(f"Search failed: {str(e)}") from e

SearchFlightsFilters

A simplified interface for flight search parameters.

fli.search.flights.SearchFlightsFilters

Bases: BaseModel

Simplified search filters for flight searches.

This model provides a simpler interface compared to the full FlightSearchFilters, focusing on the most common search parameters.

ATTRIBUTE DESCRIPTION
departure_airport

Origin airport

TYPE: Airport

arrival_airport

Destination airport

TYPE: Airport

departure_date

Date in YYYY-MM-DD format

TYPE: str

passenger_info

Passenger configuration (defaults to 1 adult)

TYPE: PassengerInfo

seat_type

Cabin class (defaults to economy)

TYPE: SeatType

stops

Maximum stops allowed (defaults to any)

TYPE: MaxStops

sort_by

Sort criteria (defaults to cheapest)

TYPE: SortBy

arrival_airport: Airport instance-attribute

departure_airport: Airport instance-attribute

departure_date: str instance-attribute

passenger_info: PassengerInfo = PassengerInfo(adults=1) class-attribute instance-attribute

seat_type: SeatType = SeatType.ECONOMY class-attribute instance-attribute

sort_by: SortBy = SortBy.CHEAPEST class-attribute instance-attribute

stops: MaxStops = MaxStops.ANY class-attribute instance-attribute

Search functionality for finding the cheapest dates to fly.

SearchDates

fli.search.dates.SearchDates()

Date-based flight search implementation.

This class provides methods to search for flight prices across a date range, useful for finding the cheapest dates to fly.

Initialize the search client for date-based searches.

Source code in fli/search/dates.py
def __init__(self):
    """Initialize the search client for date-based searches."""
    self.client = get_client()

BASE_URL = 'https://www.google.com/_/FlightsFrontendUi/data/travel.frontend.flights.FlightsFrontendService/GetCalendarGrid' class-attribute instance-attribute

DEFAULT_HEADERS = {'content-type': 'application/x-www-form-urlencoded;charset=UTF-8'} class-attribute instance-attribute

client = get_client() instance-attribute

__parse_price(item: list[list] | list | None) -> float | None staticmethod

Parse price data from the API response.

PARAMETER DESCRIPTION
item

Raw price data from the API response

TYPE: list[list] | list | None

RETURNS DESCRIPTION
float | None

Float price value if valid, None if invalid or missing

Source code in fli/search/dates.py
@staticmethod
def __parse_price(item: list[list] | list | None) -> float | None:
    """Parse price data from the API response.

    Args:
        item: Raw price data from the API response

    Returns:
        Float price value if valid, None if invalid or missing

    """
    try:
        if item and isinstance(item, list) and len(item) > 2:
            if isinstance(item[2], list) and len(item[2]) > 0:
                if isinstance(item[2][0], list) and len(item[2][0]) > 1:
                    return float(item[2][0][1])
    except (IndexError, TypeError, ValueError):
        pass

    return None

search(filters: DateSearchFilters) -> list[DatePrice] | None

Search for flight prices across a date range and search parameters.

PARAMETER DESCRIPTION
filters

Search parameters including date range, airports, and preferences

TYPE: DateSearchFilters

RETURNS DESCRIPTION
list[DatePrice] | None

List of DatePrice objects containing date and price pairs, or None if no results

RAISES DESCRIPTION
Exception

If the search fails or returns invalid data

Source code in fli/search/dates.py
def search(self, filters: DateSearchFilters) -> list[DatePrice] | None:
    """Search for flight prices across a date range and search parameters.

    Args:
        filters: Search parameters including date range, airports, and preferences

    Returns:
        List of DatePrice objects containing date and price pairs, or None if no results

    Raises:
        Exception: If the search fails or returns invalid data

    """
    encoded_filters = filters.encode()

    try:
        response = self.client.post(
            url=self.BASE_URL,
            data=f"f.req={encoded_filters}",
            impersonate="chrome",
            allow_redirects=True,
        )
        response.raise_for_status()
        parsed = json.loads(response.text.lstrip(")]}'"))[0][2]
        if not parsed:
            return None

        data = json.loads(parsed)
        dates_data = [
            DatePrice(
                date=datetime.strptime(item[0], "%Y-%m-%d"),
                price=self.__parse_price(item),
            )
            for item in data[-1]
            if self.__parse_price(item)
        ]
        return dates_data

    except Exception as e:
        raise Exception(f"Search failed: {str(e)}") from e

DatePrice

fli.search.dates.DatePrice

Bases: BaseModel

Flight price for a specific date.

date: datetime instance-attribute

price: float instance-attribute

Examples

from fli.search import SearchFlights, SearchFlightsFilters
from fli.models import Airport, SeatType

# Create filters
filters = SearchFlightsFilters(
    departure_airport=Airport.JFK,
    arrival_airport=Airport.LAX,
    departure_date="2024-06-01",
    seat_type=SeatType.ECONOMY
)

# Search flights
search = SearchFlights()
results = search.search(filters)
from fli.search import SearchDates
from fli.models import DateSearchFilters, Airport

# Create filters
filters = DateSearchFilters(
    departure_airport=Airport.JFK,
    arrival_airport=Airport.LAX,
    from_date="2024-06-01",
    to_date="2024-06-30"
)

# Search dates
search = SearchDates()
results = search.search(filters)

HTTP Client

The underlying HTTP client used for API requests.

Client

fli.search.client.Client()

HTTP client with built-in rate limiting, retry and user agent impersonation functionality.

Initialize a new client session with default headers.

Source code in fli/search/client.py
def __init__(self):
    """Initialize a new client session with default headers."""
    self._client = requests.Session()
    self._client.headers.update(self.DEFAULT_HEADERS)

DEFAULT_HEADERS = {'content-type': 'application/x-www-form-urlencoded;charset=UTF-8'} class-attribute instance-attribute

__del__()

Clean up client session on deletion.

Source code in fli/search/client.py
def __del__(self):
    """Clean up client session on deletion."""
    if hasattr(self, "_client"):
        self._client.close()

get(url: str, **kwargs) -> requests.Response

Make a rate-limited GET request with automatic retries.

PARAMETER DESCRIPTION
url

Target URL for the request

TYPE: str

**kwargs

Additional arguments passed to requests.get()

DEFAULT: {}

RETURNS DESCRIPTION
Response

Response object from the server

RAISES DESCRIPTION
Exception

If request fails after all retries

Source code in fli/search/client.py
@sleep_and_retry
@limits(calls=10, period=1)
@retry(stop=stop_after_attempt(3), wait=wait_exponential(), reraise=True)
def get(self, url: str, **kwargs) -> requests.Response:
    """Make a rate-limited GET request with automatic retries.

    Args:
        url: Target URL for the request
        **kwargs: Additional arguments passed to requests.get()

    Returns:
        Response object from the server

    Raises:
        Exception: If request fails after all retries

    """
    try:
        response = self._client.get(url, **kwargs)
        response.raise_for_status()
        return response
    except Exception as e:
        raise Exception(f"GET request failed: {str(e)}") from e

post(url: str, **kwargs) -> requests.Response

Make a rate-limited POST request with automatic retries.

PARAMETER DESCRIPTION
url

Target URL for the request

TYPE: str

**kwargs

Additional arguments passed to requests.post()

DEFAULT: {}

RETURNS DESCRIPTION
Response

Response object from the server

RAISES DESCRIPTION
Exception

If request fails after all retries

Source code in fli/search/client.py
@sleep_and_retry
@limits(calls=10, period=1)
@retry(stop=stop_after_attempt(3), wait=wait_exponential(), reraise=True)
def post(self, url: str, **kwargs) -> requests.Response:
    """Make a rate-limited POST request with automatic retries.

    Args:
        url: Target URL for the request
        **kwargs: Additional arguments passed to requests.post()

    Returns:
        Response object from the server

    Raises:
        Exception: If request fails after all retries

    """
    try:
        response = self._client.post(url, **kwargs)
        response.raise_for_status()
        return response
    except Exception as e:
        raise Exception(f"POST request failed: {str(e)}") from e