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
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 []