Hi Guys,
Today, I’ll share a little different topic in Python compared to my last couple of posts, where I have demonstrated the use of Python in the field of machine learning & forecast modeling.
We’ll explore to create meaningful sample data points for Airlines & hotel reservations. At this moment, this industry is the hard-hit due to the pandemic. And I personally wish a speedy recovery to all employees who risked their lives to maintain the operation or might have lost their jobs due to this time.
I’ll be providing only major scripts & will show how you can extract critical data from their API.
However, to create the API, you need to register in Amadeus as a developer & follow specific steps to get the API details. You will need to register using the following link.
Step 1:

Once you provide the necessary details, you need to activate your account by clicking the email validation.
Step 2:
As part of the next step, you will be clicking the “Self-Service Workspace” option as marked in the green box shown above.
Now, you have to click “My apps“ & under that, you need to click – “Create new app” shown below –

Step 3:
You need to provide the following details before creating the API. Note that once you create – it will take 30 minutes to activate the API-link.

Step 4:
You will come to the next page once you click the “Create” button in the previous step.

For production, you need to create a separate key shown above.
You need to install the following packages –
pip install amadeus
And, the installation process is shown as –

pip install flatten_json
And, this installation process is shown as –

1. clsAmedeus (This is the API script, which will send the API requests & return JSON if successful.)
############################################## #### Written By: SATYAKI DE #### #### Written On: 05-Jul-2020 #### #### Modified On 05-Jul-2020 #### #### #### #### Objective: Main calling scripts. #### ############################################## from amadeus import Client, ResponseError import json from clsConfig import clsConfig as cf class clsAmedeus: def __init__(self): self.client_id = cf.config['CLIENT_ID'] self.client_secret = cf.config['CLIENT_SECRET'] self.type = cf.config['API_TYPE'] def flightOffers(self, origLocn, destLocn, departDate, noOfAdult): try: cnt = 0 # Setting Clients amadeus = Client( client_id=str(self.client_id), client_secret=str(self.client_secret) ) # Flight Offers response = amadeus.shopping.flight_offers_search.get( originLocationCode=origLocn, destinationLocationCode=destLocn, departureDate=departDate, adults=noOfAdult) ResJson = response.data return ResJson except Exception as e: print(e) x = str(e) ResJson = {'errorDetails': x} return ResJson def cheapestDate(self, origLocn, destLocn): try: # Setting Clients amadeus = Client( client_id=self.client_id, client_secret=self.client_secret ) # Flight Offers # Flight Cheapest Date Search response = amadeus.shopping.flight_dates.get(origin=origLocn, destination=destLocn) ResJson = response.data return ResJson except Exception as e: print(e) x = str(e) ResJson = {'errorDetails': x} return ResJson def listOfHotelsByCity(self, origLocn): try: # Setting Clients amadeus = Client( client_id=self.client_id, client_secret=self.client_secret ) # Hotel Search # Get list of Hotels by city code response = amadeus.shopping.hotel_offers.get(cityCode=origLocn) ResJson = response.data return ResJson except Exception as e: print(e) x = str(e) ResJson = {'errorDetails': x} return ResJson def listOfOffersBySpecificHotels(self, hotelID): try: # Setting Clients amadeus = Client( client_id=self.client_id, client_secret=self.client_secret ) # Get list of offers for a specific hotel response = amadeus.shopping.hotel_offers_by_hotel.get(hotelId=hotelID) ResJson = response.data return ResJson except Exception as e: print(e) x = str(e) ResJson = {'errorDetails': x} return ResJson def hotelReview(self, hotelID): try: # Setting Clients amadeus = Client( client_id=self.client_id, client_secret=self.client_secret ) # Hotel Ratings # What travelers think about this hotel? response = amadeus.e_reputation.hotel_sentiments.get(hotelIds=hotelID) ResJson = response.data return ResJson except Exception as e: print(e) x = str(e) ResJson = {'errorDetails': x} return ResJson def process(self, choice, origLocn, destLocn, departDate, noOfAdult, hotelID): try: # Main Area to call apropriate choice if choice == 1: resJson = self.flightOffers(origLocn, destLocn, departDate, noOfAdult) elif choice == 2: resJson = self.cheapestDate(origLocn, destLocn) elif choice == 3: resJson = self.listOfHotelsByCity(origLocn) elif choice == 4: resJson = self.listOfOffersBySpecificHotels(hotelID) elif choice == 5: resJson = self.hotelReview(hotelID) else: resJson = {'errorDetails': 'Invalid Options!'} # Converting back to JSON jdata = json.dumps(resJson) # Checking the begining character # for the new package # As that requires dictionary array # Hence, We'll be adding '[' if this # is missing from the return payload SYM = jdata[:1] if SYM != '[': rdata = '[' + jdata + ']' else: rdata = jdata ResJson = json.loads(rdata) return ResJson except ResponseError as error: x = str(error) resJson = {'errorDetails': x} return resJson
Let’s explore the key lines –
Creating an instance of the client by providing the recently acquired API Key & API-Secret.
# Setting Clients amadeus = Client( client_id=str(self.client_id), client_secret=str(self.client_secret) )
The following lines are used to fetch the API response for specific business cases. Different invocation of API retrieve different data –
# Flight Offers # Flight Cheapest Date Search response = amadeus.shopping.flight_dates.get(origin=origLocn, destination=destLocn)
The program will navigate to particular methods to invoke certain features –
# Main Area to call apropriate choice if choice == 1: resJson = self.flightOffers(origLocn, destLocn, departDate, noOfAdult) elif choice == 2: resJson = self.cheapestDate(origLocn, destLocn) elif choice == 3: resJson = self.listOfHotelsByCity(origLocn) elif choice == 4: resJson = self.listOfOffersBySpecificHotels(hotelID) elif choice == 5: resJson = self.hotelReview(hotelID) else: resJson = {'errorDetails': 'Invalid Options!'}
2. callAmedeusAPI (This is the main script, which will invoke the Amadeus API & return dataframe if successful.)
############################################## #### Written By: SATYAKI DE #### #### Written On: 05-Jul-2020 #### #### Modified On 05-Jul-2020 #### #### #### #### Objective: Main calling scripts. #### ############################################## from clsConfig import clsConfig as cf import clsL as cl import logging import datetime import clsAmedeus as cw import pandas as p import json # Newly added package from flatten_json import flatten # Disbling Warning def warn(*args, **kwargs): pass import warnings warnings.warn = warn # Lookup functions from # Azure cloud SQL DB var = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") def main(): try: # Declared Variable ret_1 = 0 textOrig = '' textDest = '' textDate = '' intAdult = 0 textHotelID = '' debug_ind = 'Y' res_2 = '' # Defining Generic Log File general_log_path = str(cf.config['LOG_PATH']) # Enabling Logging Info logging.basicConfig(filename=general_log_path + 'AmadeusAPI.log', level=logging.INFO) # Initiating Log Class l = cl.clsL() # Moving previous day log files to archive directory log_dir = cf.config['LOG_PATH'] curr_ver =datetime.datetime.now().strftime("%Y-%m-%d") tmpR0 = "*" * 157 logging.info(tmpR0) tmpR9 = 'Start Time: ' + str(var) logging.info(tmpR9) logging.info(tmpR0) print("Log Directory::", log_dir) tmpR1 = 'Log Directory::' + log_dir logging.info(tmpR1) print('Welcome to Amadeus Calling Program: ') print('-' * 60) print('Please Press 1 for flight offers.') print('Please Press 2 for cheapest date.') print('Please Press 3 for list of hotels by city.') print('Please Press 4 for list of offers by specific hotel.') print('Please Press 5 for specific hotel review.') input_choice = int(input('Please provide your choice:')) # Create the instance of the Amadeus Class x2 = cw.clsAmedeus() # Let's pass this to our map section if input_choice == 1: textOrig = str(input('Please provide the Origin:')) textDest = str(input('Please provide the Destination:')) textDate = str(input('Please provide the Depart Date:')) intAdult = int(input('Please provide the No Of Adult:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) elif input_choice == 2: textOrig = str(input('Please provide the Origin:')) textDest = str(input('Please provide the Destination:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) elif input_choice == 3: textOrig = str(input('Please provide the Origin:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) elif input_choice == 4: textHotelID = str(input('Please provide the Hotel Id:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) elif input_choice == 5: textHotelID = str(input('Please provide the Hotel Id:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) else: print('Invalid options!') retJson = {'errorDetails': 'Invalid Options!'} #print('JSON::') #print(retJson) # Converting JSon to Pandas Dataframe for better readability # Capturing the JSON Payload res_1 = json.dumps(retJson) res = json.loads(res_1) # Newly added JSON Parse package dic_flattened = (flatten(d) for d in res) df_ret = p.DataFrame(dic_flattened) # Removing any duplicate columns df_ret = df_ret.loc[:, ~df_ret.columns.duplicated()] print('Publishing sample result: ') print(df_ret.head()) # Logging Final Output l.logr('1.df_ret' + var + '.csv', debug_ind, df_ret, 'log') print("-" * 60) print() print('Finding Analysis points..') print("*" * 157) logging.info('Finding Analysis points..') logging.info(tmpR0) tmpR10 = 'End Time: ' + str(var) logging.info(tmpR10) logging.info(tmpR0) except ValueError as e: print(str(e)) print("Invalid option!") logging.info("Invalid option!") except Exception as e: print("Top level Error: args:{0}, message{1}".format(e.args, e.message)) if __name__ == "__main__": main()
Key lines from the above script –
# Create the instance of the Amadeus Class x2 = cw.clsAmedeus()
The above line will instantiate the newly written Amadeus class.
# Let's pass this to our map section if input_choice == 1: textOrig = str(input('Please provide the Origin:')) textDest = str(input('Please provide the Destination:')) textDate = str(input('Please provide the Depart Date:')) intAdult = int(input('Please provide the No Of Adult:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) elif input_choice == 2: textOrig = str(input('Please provide the Origin:')) textDest = str(input('Please provide the Destination:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) elif input_choice == 3: textOrig = str(input('Please provide the Origin:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) elif input_choice == 4: textHotelID = str(input('Please provide the Hotel Id:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) elif input_choice == 5: textHotelID = str(input('Please provide the Hotel Id:')) retJson = x2.process(input_choice, textOrig, textDest, textDate, intAdult, textHotelID) else: print('Invalid options!') retJson = {'errorDetails': 'Invalid Options!'}
The above lines will fetch the response based on the supplied inputs in the form of JSON.
# Converting JSon to Pandas Dataframe for better readability # Capturing the JSON Payload res_1 = json.dumps(retJson) res = json.loads(res_1)
Now, the above line will convert the return payload to JSON.
Sample JSON should look something like this –

Now, using this new package, our application will flatten the complex nested JSON.
# Newly added JSON Parse package dic_flattened = (flatten(d) for d in res) df_ret = p.DataFrame(dic_flattened)
The given lines will remove any duplicate column if it exists.
# Removing any duplicate columns df_ret = df_ret.loc[:, ~df_ret.columns.duplicated()]
Let’s explore the directory structure –

Let’s run our application –
We’ll invoke five different API’s (API related to different functionalities) & their business cases –
Run – Option 1:

So, if we want to explore some of the key columns, below is the screenshot for a few sample data –

Run – Option 2:

Some of the vital sample data –

Run – Option 3:

Sample relevant data for our analysis –

Run – Option 4:

Few relevant essential information –

Run – Option 5:

Finally, few sample records from the last option –

So, finally, we’ve done it. You will find that JSON package from this link.
During this challenging time, I would request you to follow strict health guidelines & stay healthy.
N.B.: All the data that are used here can be found in the public domain. We use this solely for educational purposes.
You must log in to post a comment.