Finding multi-stop flights using Neo4j & Python 🐍 Part #2

Fri, May 4, 2018 5-minute read

In this blog-post, I’d like to give you a first introduction on how we can search for flights using Python and the Kiwi API. Excited? Let’s get started💻🖱️.

This post is part of a series of posts. I highly recommend to also check out the previous post, in case you haven’t been following along from the start.

Finding the right API for our project, a bit of history

It’s actually quite a hard to find an API for travel-related projected that is both easy to interface and where the costs don’t break the bank. I’d been messing with flight search APIs for a few years now and noticed there are basically three different types. The deprecated ones: Over the time we saw many great APIs like QPX-Express API or Kayak. Momondo also had a sort of unofficial API which was extremely easy to interface, but doesn’t seem to be working anymore (plus anything automated strictly violates their terms of use, so don’t do it). And on the other hand, you have the legacy GDS operators with their bulky and clunky SOAP based APIs. The third option many people are still choosing these days is a screen scraping based approach like Miguel Arroyo’s Flight Scraper. The downside of this technique is that it requires almost constant maintenance.

My recommendation

One of the best remaining API’s out there are the Skyscanner and Kiwi (formerly known as Skypicker) API. Both APIs are well documented and even offer python wrappers. I’ll be using the Kiwi API, as their data seems more accurate and they are combining legacy carriers and low-cost carriers onto a single ticket, which is something Skyscanner still struggles with. The later was something I definitely wanted to have in my project, as it seems crucial if you want to travel really CHEAP. Another two reasons why I went for the Kiwi API is because it’s blazing fast and they have a partner key, which can be used for testing. If you want to Skyscanner you’ll have to apply for your own API-key right-away here: Link to Skyscanner.

Kiwi API Documentation

Searching for a flight using the API is really straight forward. First, you’ll have to set up the Python Wrapper. Once everything is in place we can start right away.

At first we need to create an instance of the Search class.

from kiwicom import kiwi
s = kiwi.Search()

And then we can start with passing our airports and dates to the search_flights function. In my example, I am searching for a flight from Frankfurt (FRA) to New York (JFK). Please note that the dates have to be specified in the format day/month/year, which is different from the US date format. We also have to specify a partner, which works similarly to an API key. For testing, we’re free to use picky.

res = s.search_flights(flyFrom='FRA', to='JFK', dateFrom='26/10/2018', dateTo='5/11/2018', partner='picky')

You might also want to add the parameter sort='price’, that way you’ll get the cheapest flights first. The limit-parameter can also be quite handy if you’re only interested in retrieving a few data sets rather than everything. For all the additional parameters check out their documentation. A word of caution: the way kiwi works is that it’s searching for a one-way flight by default. if you want to search for a return or multi-stop flight you’ll have to define each segment using separately, like this:

payload = {
"requests": [
{"to": "FRA", "flyFrom": "JFK", "dateFrom": "26/10/2018", "dateTo": "5/11/2018"},
{"to": "JFK", "flyFrom": "FRA", "dateFrom": "15/11/2018", "dateTo": "25/11/2018"}

res = s.search_flights_multi(json_data=payload)

The data returned by the API is a properly formed JSON with the following syntax.

"search_params": {
"to_type": "airport",
"flyFrom_type": "airport",
"seats": {
"infants": 0,
"passengers": 1,
"adults": 1,
"children": 0
"_results": 2,
"connections": [],
"currency": "EUR",
"currency_rate": 1,
"all_stopover_airports": [],
"data": [ ...],
"ref_tasks": [],
"refresh": [],
"del": null,
"all_airlines": [],
"time": 1

The actually interesting part lives within the data array. The data array is home to the information like the price, a deep link (the site where you can actually book the flight) and a lot of additional information like the distance, the operating airline and most importantly the segments of the journey (which we’ll need them later on). We can loop over the data fairly easily using Python’s “for in”-function.

res = res.json()
for r in res['data']:
    print '#'*20
    flight_number = ''
    for i, route in enumerate(r['route']):
        print("[{}] {}{}: {} -> {}, price: {} EUR, distance: {}").format(

In the snippet above I am also printing the individual legs of the journey, the total price and the total distance. The data for the individual legs are stored in the sub-array with the key route.

If everything is working as expected, your console output should look similar to this screenshot.

Kiwi API Flight Search limit to one flight. Search from Frankfurt to John F Kennedy.

That’s it for this brief introduction. In the nex post, I’ll introduce you to the concept of hidden city ticketing, why we are particularly interested in it, why it’s a really powerful tool. We’ll use what we’ve learned today to find hidden city flights the python way.

Cheers Alex