Skip to content

Instantly share code, notes, and snippets.

@TheMuellenator
Forked from angelabauer/flight_data.py
Last active August 22, 2025 04:43
Show Gist options
  • Select an option

  • Save TheMuellenator/4d730d38818d935a9ce4ad9d7a817138 to your computer and use it in GitHub Desktop.

Select an option

Save TheMuellenator/4d730d38818d935a9ce4ad9d7a817138 to your computer and use it in GitHub Desktop.
class FlightData:
def __init__(self, price, origin_city, origin_airport, destination_city, destination_airport, out_date, return_date):
self.price = price
self.origin_city = origin_city
self.origin_airport = origin_airport
self.destination_city = destination_city
self.destination_airport = destination_airport
self.out_date = out_date
self.return_date = return_date
import requests
from flight_data import FlightData
TEQUILA_ENDPOINT = "https://tequila-api.kiwi.com"
TEQUILA_API_KEY = YOUR FLIGHT SEARCH API KEY
class FlightSearch:
def get_destination_code(self, city_name):
location_endpoint = f"{TEQUILA_ENDPOINT}/locations/query"
headers = {"apikey": TEQUILA_API_KEY}
query = {"term": city_name, "location_types": "city"}
response = requests.get(url=location_endpoint, headers=headers, params=query)
results = response.json()["locations"]
code = results[0]["code"]
return code
def check_flights(self, origin_city_code, destination_city_code, from_time, to_time):
headers = {"apikey": TEQUILA_API_KEY}
query = {
"fly_from": origin_city_code,
"fly_to": destination_city_code,
"date_from": from_time.strftime("%d/%m/%Y"),
"date_to": to_time.strftime("%d/%m/%Y"),
"nights_in_dst_from": 7,
"nights_in_dst_to": 28,
"one_for_city": 1,
"max_stopovers": 0,
"curr": "GBP"
}
response = requests.get(
url=f"{TEQUILA_ENDPOINT}/v2/search",
headers=headers,
params=query,
)
try:
data = response.json()["data"][0]
except IndexError:
print(f"No flights found for {destination_city_code}.")
return None
flight_data = FlightData(
price=data["price"],
origin_city=data["route"][0]["cityFrom"],
origin_airport=data["route"][0]["flyFrom"],
destination_city=data["route"][0]["cityTo"],
destination_airport=data["route"][0]["flyTo"],
out_date=data["route"][0]["local_departure"].split("T")[0],
return_date=data["route"][1]["local_departure"].split("T")[0]
)
print(f"{flight_data.destination_city}: £{flight_data.price}")
return flight_data
from datetime import datetime, timedelta
from data_manager import DataManager
from flight_search import FlightSearch
data_manager = DataManager()
sheet_data = data_manager.get_destination_data()
flight_search = FlightSearch()
ORIGIN_CITY_IATA = "LON"
if sheet_data[0]["iataCode"] == "":
for row in sheet_data:
row["iataCode"] = flight_search.get_destination_code(row["city"])
data_manager.destination_data = sheet_data
data_manager.update_destination_codes()
tomorrow = datetime.now() + timedelta(days=1)
six_month_from_today = datetime.now() + timedelta(days=(6 * 30))
for destination in sheet_data:
flight = flight_search.check_flights(
ORIGIN_CITY_IATA,
destination["iataCode"],
from_time=tomorrow,
to_time=six_month_from_today
)
@parkook

parkook commented Feb 7, 2024

Copy link
Copy Markdown

I found the problem; after I change the "max_stopovers" to 4, I got the data.

@Josip5521

Copy link
Copy Markdown

I don't understand how she just knows to get the ["route"] and ["local_departure"] from the data. I tried entering data = response.json() into the jsonviewer to see what key it has, but it gave me an error saying "invalid json variable". So how does she know what keys to get.

flight_data = FlightData( price=data["price"], origin_city=data["route"][0]["cityFrom"], origin_airport=data["route"][0]["flyFrom"], destination_city=data["route"][0]["cityTo"], destination_airport=data["route"][0]["flyTo"], out_date=data["route"][0]["local_departure"].split("T")[0], return_date=data["route"][1]["local_departure"].split("T")[0] )

I have same question LOL

@Josip5521

Copy link
Copy Markdown

Uploading Bez naslova.png…

Bez naslova1

Anyone knows what is wrong?

@Josip5521

Copy link
Copy Markdown

Bez naslova

Same thing is when i run main.py

@Aizad-eng

Copy link
Copy Markdown

@Josip5521 There is no key-named "data" in your JSON response. First print the JSON response and analyze the JSON, see if there is a data key in it. It means that the API is not returning the data you intend to fetch because of parameters not being correct.

@zmunny

zmunny commented Mar 6, 2024

Copy link
Copy Markdown

I am still trying to get the iatacodes. What is the Tequila endpoint? I am getting 404 when I try.

@ozieaev

ozieaev commented Mar 6, 2024 via email

Copy link
Copy Markdown

@zmunny

zmunny commented Mar 7, 2024

Copy link
Copy Markdown

Thanks, man. So if it really is "[https://tequila-api.kiwi.com”] then it means my problem lies elsewhere. I'll check my f string and other parts to see if I'm calling the API correctly.

@ozieaev

ozieaev commented Mar 7, 2024 via email

Copy link
Copy Markdown

@zmunny

zmunny commented Mar 7, 2024

Copy link
Copy Markdown

ozieaev,
Yes, I tested my API key using postman and got 200. The endpoint is my current problem! I asked for help here and people have been nice. I hope it helps others that are having trouble:
https://discuss.python.org/t/angela-yu-100-days-of-code-the-tequila-endpoint-mystery/47740/9

@Jia-Jun-Sun

Copy link
Copy Markdown

does anyone know how to unsubscribe from this gist? I keep getting emails for this page and when I click the unsubscribe button on the email, it just brings me to this page, but there's no unsubscribe button.

@zmunny

zmunny commented Mar 7, 2024 •

Copy link
Copy Markdown

galaxy,
Lol, sorry I'm blowing up your spot. The unsub button is on the top right. If you're on a phone, I have no idea.

@biisuke

biisuke commented Mar 12, 2024 •

Copy link
Copy Markdown

I am constantly getting {"error_code":403,"message":"'apikey' header is required"}
this is what i do (of course with more code in between):

TEQUILA_ENDPOINT = "https://tequila-api.kiwi.com"
headers = {"apikey": API_KEY}

I know my api key is correct. I think it has to do with my acc. but not sure. I have created a Search & Book - Nomad solution

@Aizad-eng

Aizad-eng commented Mar 12, 2024 via email

Copy link
Copy Markdown

@Mas73rs

Mas73rs commented Mar 14, 2024

Copy link
Copy Markdown

Hello, Got this error on my end, any idea how to fix it ? { "status": "Bad Request", "error": "unknown partner provided - if you would like to cooperate with Kiwi.com, please register at tequila.kiwi.com" } Thanks,

Have you found the solution? I ran into the same problem.

@biisuke

biisuke commented Mar 15, 2024

Copy link
Copy Markdown

I am passing the headers in the request as follows:

response = requests.get(
url=f"{TEQUILA_ENDPOINT}/v2/search",
headers=headers,
params=query,
)

I have modified the headers as you said and still it doesnt work. I feel like something is wrong with my account. Has anyone else run into this problem?

@Mas73rs

Mas73rs commented Mar 15, 2024 •

Copy link
Copy Markdown

@biisuke

I am passing the headers in the request as follows:

response = requests.get( url=f"{TEQUILA_ENDPOINT}/v2/search", headers=headers, params=query, )

I have modified the headers as you said and still it doesnt work. I feel like something is wrong with my account. Has anyone else run into this problem?

I ran into the same problem, but as you can see in the snippet, I was passing my query as json instead of params. Changing that fixed the issue for me.

`def get_destination_code(self, city_name: str):

    location_endpoint = f'{self.tequila_endpoint}/locations/query'
    query = {'term': city_name,'location_types': 'city'}
    response = re.get(url=location_endpoint, headers=self.headers, json=query)
    return response`

@biisuke

biisuke commented Mar 15, 2024

Copy link
Copy Markdown

@Mas73rs
I have changed the params to json and now I get : HTTP error occurred (400): 400 Client Error: Bad Request for url: https://tequila-api.kiwi.com/locations/query

Can you tell me what your self.tequila_endpoint is?

@Mas73rs

Mas73rs commented Mar 17, 2024 •

Copy link
Copy Markdown

@biisuke

TEQUILA_ENDPOINT = 'https://api.tequila.kiwi.com'


class FlightSearch:
    def __init__(self):
        self.api_key = os.getenv('TEQUILA_API_KEY')
        self.headers = {'apikey': self.api_key}
def get_destination_code(self, city_name: str) -> str:
    location_endpoint = f'{TEQUILA_ENDPOINT}/locations/query'
    query = {'term': city_name, 'location_types': 'city'}
    response = re.get(url=location_endpoint, headers=self.headers, params=query)
    response.raise_for_status()
    location_data = response.json().get('locations', [])

    if location_data:
        return location_data[0].get('code', 'Unknown code')
    else:
        return 'Unknown code'

`

@Mas73rs

Mas73rs commented Mar 17, 2024 •

Copy link
Copy Markdown

@biisuke
Can I have a look at the code causing the error?
If you are trying to search for available flights then:
search_endpoint = f'{TEQUILA_ENDPOINT}/v2/search'

@zmunny

zmunny commented Mar 18, 2024 •

Copy link
Copy Markdown

Bros, I think I got it! This video helped me:
https://www.youtube.com/watch?v=usnkTZeZoT8&list=WL&index=5&t=1256s

What I learned:
Watch your Sheety endpoints and Google Sheets URLs carefully.
Watch the JSON formatting and camel case carefully.
Make sure your Tequila account is actually verified and ready to use.

Edit:
Watch the key : value pairs carefully.

The code here isn't crazy, but there are a lot of details to keep track of. Take one step at a time slowly and be methodical. Don't give up!

@biisuke

biisuke commented Mar 19, 2024 •

Copy link
Copy Markdown

Guys, I managed to fix it. Issue was with my acc. I think. Thank you all for the help

@biisuke

biisuke commented Mar 19, 2024

Copy link
Copy Markdown

I have now managed to fix this project. My only question is how do you run this program constantly? or once every 30 minutes? Do you run it on python anywhere?

@zmunny

zmunny commented Mar 19, 2024 via email

Copy link
Copy Markdown

@zmunny

zmunny commented Mar 22, 2024

Copy link
Copy Markdown

Guys, I managed to fix it. Issue was with my acc. I think. Thank you all for the help

Nice!!

@kriswen

kriswen commented Apr 8, 2024 •

Copy link
Copy Markdown

I don't understand how she just knows to get the ["route"] and ["local_departure"] from the data. I tried entering data = response.json() into the jsonviewer to see what key it has, but it gave me an error saying "invalid json variable". So how does she know what keys to get.
flight_data = FlightData( price=data["price"], origin_city=data["route"][0]["cityFrom"], origin_airport=data["route"][0]["flyFrom"], destination_city=data["route"][0]["cityTo"], destination_airport=data["route"][0]["flyTo"], out_date=data["route"][0]["local_departure"].split("T")[0], return_date=data["route"][1]["local_departure"].split("T")[0] )

I have same question LOL

it's in the search_api documentation' sample response https://tequila.kiwi.com/portal/docs/tequila_api/search_api
i guess it was originally in the api response, but they removed it ( and also forgot to update the documentation)?
I also didn't see the ["local_departure"] from the response data, so i used the ["dTime"] and convert the time format instead:

        flight_data = FlightData(
            from_city=data["route"][0]["cityFrom"],
            from_code=data["route"][0]["flyFrom"],
            to_city=data["route"][0]["cityTo"],
            to_code=data["route"][0]["flyTo"],
            # convert epoch time to human readable https://www.geeksforgeeks.org/convert-epoch-time-to-date-time-in-python/#google_vignette
            from_date=time.strftime("%d/%m/%Y", time.gmtime(data["route"][0]["dTime"])),
            to_date=time.strftime("%d/%m/%Y", time.gmtime(data["route"][1]["dTime"])),
            price=data["price"],
        )

@MarkoTomasevic7

Copy link
Copy Markdown

I also get error 403 for fetching flight prices (via search api), altough the part of my code that gets iata codes (via locations api) works. How can I solve this?

@weirdmo

weirdmo commented May 12, 2024

Copy link
Copy Markdown

there is no registration option in kiwi website i think they ditched free plan or am i doing something wrong? Anyone else experienced? is there an alternative?

@akashkchoudhary567

Copy link
Copy Markdown

current API "https://tequila-api.kiwi.com/v2/search" appears not to be free any longer This is the second API where I am getting the following error from some of the examples {"error_code":403,"message":"You don't have permission to access this resource"} event form the web site API that is the error I was also getting. Location to get code still worked.

Which is the second Api you are using for iata codes?

@Prithivi2807

Copy link
Copy Markdown

if i run the program through amendeus and sheety api the code is throws an error i have modified the API instead of Kiwi I used Amanda's flight files API because I'm not able to create the account in Kiwi I don't know the service will be stopped currently so if you guys have same error like me you are facing same error like me just let me know know i will attach this error and the ctepa if you add the another sheet it gives payment required error not able to complete this current project anyone facing same issues like me or some one found different api provider to build this just let me know.
Screenshot 2025-08-22 095824

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment