Example #1
0
def api_get_airlines(api_url=api_url,
                     api_token=api_token,
                     tries=0,
                     timeout=api_timeout) -> typing.List[str]:
    """
    Call the REST API to get the list of available airlines

    :param api_url:
    :param api_token:
    :param tries:
    :param timeout:
    :param kwargs:
    :return:
    """
    global AIRLINES
    if not AIRLINES:
        headers = {'Authorization': f'Bearer {api_token}',
                   'Accept': 'application/json'}
        url = os.path.join(api_url, 'flights/airlines')
        logger.debug(f"Calling airlines REST API (url={url})")
        try:
            r = requests.get(url, headers=headers, timeout=timeout)
            r.raise_for_status()
            AIRLINES = r.json()['airlines']
            logger.info(f"flight airlines api call success in {r.elapsed.total_seconds():.3}s. Airlines: {AIRLINES}")
            return AIRLINES
        except requests.exceptions.ConnectTimeout:
            # REST API connection timeout is reached. Most likely we're sending too many requests and need to ease off
            # let's exponentially increase the timeout and retry until the max num of retires is reached
            logger.warning(f"REST API call to get airlines timed out. (timeout={timeout}")
            tries, timeout = tries + 1, timeout * 2
            if tries < api_max_retries:
                # sleep the current thread to back off from submitting too many requests
                logger.debug(f"thread sleep to back off from submitting too many REST API requests. sleep: {timeout}s")
                sleep(timeout)
                logger.warning(f"Increasing timeout to {timeout} and retrying. Retry number={tries}")
                return api_get_airlines(api_url, api_token, tries, timeout)
            else:
                logger.fatal("Max number of API retries is reached. Quiting.")
                sys.exit(1)
        except requests.ConnectionError:
            # if cannot establish connection with the REST API. Most likely the URL is incorrect or API Flask server
            # is not running
            logger.fatal(f"Could not establish connection to the REST API to get airlines (url={url})")
            sys.exit(1)
        except requests.exceptions.RequestException as err:
            logger.error("Unknown error while connecting to REST API to get airlines: {}".format(str(err)))
            return AIRLINES
    else:
        return AIRLINES
Example #2
0
def api_get_flights(airline: str,
                    flight_date: datetime,
                    api_url=api_url,
                    api_token=api_token,
                    tries=0,
                    timeout=api_timeout) -> typing.List[typing.Dict]:
    """
    Call REST API to get flight records for a given date

    :param airline: airline IATA code
    :param flight_date: flight date
    :param api_url: API base URL such as http://localhost:5000/
    :param api_token: OAuth Bearer token
    :param tries:
    :param timeout:
    :return: list of flight records as a dict
    """
    headers = {'Authorization': f'Bearer {api_token}',
               'Accept': 'application/json'}
    params = {'date': flight_date.strftime('%Y-%m-%d'),
              'airline': airline}
    url = os.path.join(api_url, 'flights/flights')
    try:
        r = requests.get(url, params=params, headers=headers, timeout=timeout)
        # raise exception if response returned an unsuccessful status code
        r.raise_for_status()
        # return flight records
        data = r.json()
        logger.debug(f"Flight API returned {data['records']} flights in {r.elapsed.total_seconds():.3}s")
        return copy(data['flights'])
    except requests.exceptions.ConnectTimeout:
        # REST API connection timeout is reached. Most likely we're sending too many requests and need to ease off
        # let's exponentially increase the timeout and retry until the max num of retires is reached
        logger.warning(f"REST API call to get flights timed out. (timeout={timeout}")
        tries, timeout = tries + 1, timeout * 2
        if tries < api_max_retries:
            # sleep the current thread to back off from submitting too many requests
            logger.debug(f"thread sleep to back off from submitting too many REST API requests. sleep: {timeout}s")
            sleep(timeout)
            logger.warning(f"Increasing timeout to {timeout} and retrying. Retry number={tries}")
            return api_get_flights(airline, flight_date, api_url, api_token, tries, timeout)
        else:
            logger.fatal("Max number of API retries is reached. Quiting.")
            sys.exit(1)
    except requests.ConnectionError:
        # if cannot establish connection with the REST API. Most likely the URL is incorrect or API Flask server
        # is not running
        logger.fatal(f"Could not establish connection to the REST API to get flights (url={url})")
        sys.exit(1)
    except requests.exceptions.HTTPError as err:
        logger.error("Flights API has a critical error: {}".format(str(err)))
        logger.error("No records returned by flights api")
        return []
    except requests.exceptions.RequestException as err:
        logger.error("Unknown error while connecting to REST API to get flights: {}".format(str(err)))
        logger.error("No records returned by flights api")
        return []