def get_browse_quotes(base_url: str, headers: dict, country: str, currency: str, locale_lang: str, airport_id_orig: str, airport_id_dest: str, outbound_date: str, max_retries: int, logger: logging.Logger) -> list: """ Runs Browse Quotes API call, which retrieves the cheapest quotes from Skyskanner cache prices """ stage_name = "CACHED_QUOTE" try_number = 0 url = f"{base_url}browsequotes/v1.0/{country}/{currency}/{locale_lang}/{airport_id_orig}/{airport_id_dest}/{outbound_date}" all_results = [] # rerun if response unsuccessful while True: response = requests.request("GET", url, headers=headers) result = json.loads(response.text) if response.status_code == 200 and len(result) != 0: logger.info(f'{stage_name} - Received result.') all_results.append(result) return all_results else: try_number += 1 retry(stage_name, try_number, max_retries, f"{response.status_code} - {response.content}", logger=logger)
def live_prices_pull_results(base_url: str, headers: dict, session_key: str, max_retries: int, logger: logging.Logger) -> list: """ Returns Live API results from the created session. """ stage_name = "PULL_RESULTS" try_number = 0 url = f"{base_url}pricing/uk2/v1.0/{session_key}?pageIndex=0&pageSize=20" querystring = {"pageIndex": "0", "pageSize": "100"} all_results = [] # rerun if response unsuccessful while True: response = requests.request("GET", url, headers=headers, params=querystring) result = json.loads(response.text) if response.status_code == 200: all_results.append(result) if result["Status"] == "UpdatesPending": # get next scope results logger.info( f"{stage_name} - Got response 'UpdatesPending'. Requesting more results after delay." ) timer(wait_time=10, logger=logger) # wait for all results to be updated continue logger.info( f'{stage_name} - Got response status - {result["Status"]}. ' f'Recorded {len(all_results)} result requests.') break else: try_number += 1 retry(stage_name, try_number, max_retries, f"{response.status_code} - {response.content}", logger=logger) return all_results
def record_json_to_mongodb(json_data: list, collection: pymongo.collection.Collection, max_retries: int, logger: logging.Logger) -> bool or None: """ Records JSON data to MongoDB """ stage_name = "MONGODB" try_number = 0 while True: result = collection.insert_many(json_data) if result.acknowledged: logger.info( f"{stage_name} - Recorded {len(json_data)} new results. " f"Overall documents count - {collection.count_documents({})}") logger.debug( f"{stage_name} - Newly recorded IDS: {', '.join([str(id) for id in result.inserted_ids])}" ) return True else: try_number += 1 err = f"{stage_name} - JSON was not recorded to DB, result is not acknowledged" retry(stage_name, try_number, max_retries, err, logger)
def live_prices_create_session(base_url: str, headers: dict, cabin_class: str, country: str, currency: str, locale_lang: str, origin_place: str, destination_place: str, outbound_date: str, adults_count: int, max_retries: int, logger: logging.Logger) -> str: """ Creates Live Pricing Service Session (it should be created before requesting price data).\n See detailed documentation -> https://skyscanner.github.io/slate/#flights-live-prices """ stage_name = "CREATE_SESSION" try_number = 0 url = f"{base_url}pricing/v1.0" payload = f"cabinClass={cabin_class}&country={country}¤cy={currency}" \ f"&locale={locale_lang}&originPlace={origin_place}&destinationPlace={destination_place}" \ f"&outboundDate={outbound_date}&adults={adults_count}" headers.setdefault('content-type', "application/x-www-form-urlencoded") # rerun if response unsuccessful while True: try: response = requests.request("POST", url, data=payload, headers=headers) logger.debug(f"{stage_name} - Full requested url: {url}/{payload}") response.raise_for_status() except requests.exceptions.HTTPError as err: try_number += 1 retry(stage_name, try_number, max_retries, err, logger=logger) else: session_key = response.headers["Location"].split("/")[-1] logger.info(f"{stage_name} - Session created successfully") return session_key
def get_airport_id(base_url: str, headers: dict, currency: str, locale_lang: str, search_city: str, search_country: str, max_retries: int, logger: logging.Logger, element_from_matched_list: int = 0) -> str: """ Gets 1st airport id by default for search city-country combination (1 city-country pair can have several airports). """ stage_name = "GET_PLACE_ID" try_number_resp = 0 try_number_n = 0 # get airport_id for search city-country pair url = f"{base_url}autosuggest/v1.0/{currency}/{currency}/{locale_lang}/" querystring = {"query": {search_city}} # rerun if response unsuccessful or can't extract n-th element while True: try: response = requests.request("GET", url, headers=headers, params=querystring) result = json.loads(response.text) except Exception as exc: try_number_resp += 1 retry(stage_name, try_number_resp, max_retries, exc, logger=logger) else: # get all airport ids location_airport_ids = [] for location_data in result['Places']: if location_data['CountryName'].lower( ) == search_country.lower(): location_airport_ids.append(location_data['PlaceId']) if not location_airport_ids: logger.critical( f"{stage_name} - Place_ids list is empty! Exiting the program." ) sys.exit() # return n-th elem try: airport_id = location_airport_ids[element_from_matched_list] except Exception as exc: try_number_n += 1 retry(stage_name, try_number_n, max_retries, exc, logger=logger) else: logger.debug( f"{stage_name} - Available codes for {search_city}-{search_country}: {location_airport_ids}." f" Going to use 1st element from the list.") logger.info( f"{stage_name} - {search_city}-{search_country} airport id - '{airport_id}'" ) return airport_id