Tracking Celebrity Flights in Python!
Tags: python, programming, tutorial, beginners
Published: 2024-05-23 04:44:50

## Hello, everyone!

In this basic tutorial, I will be demonstrating how to develop a flight tracking program in Python. Let's go!

---

### How to Create a Flight Tracking Program in Python

This program will fetch real-time flight data from the Aviationstack API and track aircraft using their ICAO24 identification. I'll cover everything from setting up your environment to implementing the program, as this is a beginner-friendly tutorial. The complete code is available at [Horus on GitHub](https://github.com/6abd/horus), so feel free to leave a star or contribute in other ways.

---

### Prerequisites

Before we start, ensure you have the following:
- **Basic Python Knowledge**: Understanding of basic Python programming concepts.
- **Python Itself**: Python installed on your machine.
- **Required Libraries**: Requests and Colorama libraries for handling API requests, parsing data, and styling console output respectively.

---

### Setting Up the Environment

#### Python Installation
Download and install Python from the [official Python website](https://www.python.org/).

#### Installing Required Libraries
Install the necessary Python libraries using pip:
```bash
pip install requests colorama
```

---

### Understanding APIs

#### What is an API?
An API allows applications (like this one!) to communicate with external services/websites. In this case, we'll be using the Aviationstack and OpenSky APIs to fetch flight data.

#### Flight Tracking API Options
There are several APIs available for flight data. In this tutorial, we will use:
- **Aviationstack API**: For real-time flight data.
- **OpenSky Network API**: For tracking aircraft using their ICAO24 identification.

#### API Key Registration
Register on the [Aviationstack website](https://aviationstack.com/) to get your API key. OpenSky doesn't require a key for its free API.

---

### Fetching Flight Data

We will use the `requests` library to make API calls and fetch flight data.

---

### Implementing the Flight Tracking Program

Below are snippets of the key parts of the flight tracking program. For the complete code, refer to the [Horus GitHub repository](https://github.com/6abd/horus).

#### Formatting Templates
I have made output formatting templates using Colorama already (optimized for terminal use). Here they are for your convenience, they will be used throughout the code:
```python
from colorama import Fore # For text colour.

# Config (Prints).
text = (f"{Fore.WHITE}") # Change the colour of text output in the client side
dividers = (f"{Fore.LIGHTRED_EX}") # Changes the [], | and : in the client side
success = (f"{Fore.WHITE}[{Fore.GREEN}SUCCESS{Fore.WHITE}]") # Success output.
successfully = (f"{Fore.WHITE}[{Fore.GREEN}SUCCESSFULLY{Fore.WHITE}]") # Successfully output.
failed = (f"{Fore.WHITE}[{Fore.LIGHTRED_EX}FAILED{Fore.WHITE}]") # Failed output.
prompt = (f"{Fore.WHITE}[{Fore.YELLOW}»{Fore.WHITE}]") # Prompt output.
notice = (f"{Fore.WHITE}[{Fore.YELLOW}!{Fore.WHITE}]") # Notice output.
question =  (f"{Fore.WHITE}[{Fore.YELLOW}?{Fore.WHITE}]") # Alert output.
alert =  (f"{Fore.WHITE}[{Fore.LIGHTRED_EX}!{Fore.WHITE}]") # Alert output.
exited = (f"{Fore.WHITE}[{Fore.LIGHTRED_EX}EXITED{Fore.WHITE}]") # Execited output.
disconnected = (f"{Fore.WHITE}[{Fore.LIGHTRED_EX}DISCONNECTED{Fore.WHITE}]") # Disconnected output.
command = (f"\n[{Fore.YELLOW}>_{Fore.WHITE}]: ") # Always asks for a command on a new line.
```

#### Determining what to filter/search by
In order to allow the user to access the most applicable data to them, we should get input on what they would like to search by. This can be done by the following code:
```python
print(f'{notice} How would you like to filter flight data? (icao24, number, date, dep_iata, arr_iata or status) ')
option = input(f'{command}').lower()
```

#### Fetching Flight Data by different methods
The Aviationstack API allows users to filter flight data results by number. We can get that URL with requests, parse the data, and make dictionary calls for each piece of data we want. Then, we can print this in a readable way and add separators for each API search result. We need to have a different section of code for each filtering method, as some responses have different JSON structures than others. 

We can filter Aviationstack API's results by the following methods:
- **Flight Number**
- **Date**
- **Departure IATA**
- **Arrival IATA**
- **Flight Status**
- **ICAO24** ( Aircraft specific, my personal favorite :) )


The code for each method is shown below, with an if statement initiating each section based on input from before:

#### Fetching Flight Data by Flight Number
```python
if option == 'number':
    number = input(f"{question} Enter a flight number: ")
    data = requests.get(f"http://api.aviationstack.com/v1/flights?access_key={key}&flight_number={number}").json()['data']
    for i in range(0,len(data)):
        print(f"Airline Name: {data[i]['airline']['name']}")
        print(f"Flight Date: {data[i]['flight_date']}")
        print(f"Status: {data[i]['flight_status']}")
        print(f"Departure Airport: {data[i]['departure']['airport']}")
        print(f"Departure Timezone: {data[i]['departure']['timezone']}")
        print(f"Departure IATA/ICAO: {data[i]['departure']['iata']} | {data[i]['departure']['icao']}")
        print(f"Departure Terminal/Gate: {data[i]['departure']['terminal']}{data[i]['departure']['gate']}")
        print(f"Estimated Departure: {data[i]['departure']['estimated']}")
        print(f"Actual Departure: {data[i]['departure']['actual']}")
        print(f"Arrival Airport: {data[i]['arrival']['airport']}")
        print(f"Arrival Timezone: {data[i]['arrival']['timezone']}")
        print(f"Arrival IATA/ICAO: {data[i]['arrival']['iata']} | {data[i]['arrival']['icao']}")
        print(f"Arrival Terminal/Gate: {data[i]['arrival']['terminal']}{data[i]['arrival']['gate']}")
        print(f"Estimated Arrival: {data[i]['arrival']['estimated']}")
        print(f"Actual Arrival: {data[i]['arrival']['actual']}")
        print("-------------------------------------------------------------------")
```

#### Fetching Flight Data by Date
```python
if option == 'date':
    date = input(f"{question} Enter a flight date (YYYY-MM-DD): ")
    data = requests.get(f"http://api.aviationstack.com/v1/flights?access_key={key}&date={date}").json()['data']
    for i in range(0,len(data)):
        print(f"Airline Name: {data[i]['airline']['name']}")
        print(f"Flight Date: {data[i]['flight_date']}")
        print(f"Status: {data[i]['flight_status']}")
        print(f"Departure Airport: {data[i]['departure']['airport']}")
        print(f"Departure Timezone: {data[i]['departure']['timezone']}")
        print(f"Departure IATA/ICAO: {data[i]['departure']['iata']} | {data[i]['departure']['icao']}")
        print(f"Departure Terminal/Gate: {data[i]['departure']['terminal']}{data[i]['departure']['gate']}")
        print(f"Estimated Departure: {data[i]['departure']['estimated']}")
        print(f"Actual Departure: {data[i]['departure']['actual']}")
        print(f"Arrival Airport: {data[i]['arrival']['airport']}")
        print(f"Arrival Timezone: {data[i]['arrival']['timezone']}")
        print(f"Arrival IATA/ICAO: {data[i]['arrival']['iata']} | {data[i]['arrival']['icao']}")
        print(f"Arrival Terminal/Gate: {data[i]['arrival']['terminal']}{data[i]['arrival']['gate']}")
        print(f"Estimated Arrival: {data[i]['arrival']['estimated']}")
        print(f"Actual Arrival: {data[i]['arrival']['actual']}")
        print("-------------------------------------------------------------------")
```

#### Fetching Data by Departure IATA
```python
if option == 'dep_iata':
    dep_iata = input(f"{question} Enter a flight departure IATA: ")
    data = requests.get(f"http://api.aviationstack.com/v1/flights?access_key={key}&dep_iata={dep_iata}").json()['data']
    for i in range(0,len(data)):
        print(f"Airline Name: {data[i]['airline']['name']}")
        print(f"Flight Date: {data[i]['flight_date']}")
        print(f"Status: {data[i]['flight_status']}")
        print(f"Departure Airport: {data[i]['departure']['airport']}")
        print(f"Departure Timezone: {data[i]['departure']['timezone']}")
        print(f"Departure IATA/ICAO: {data[i]['departure']['iata']} | {data[i]['departure']['icao']}")
        print(f"Departure Terminal/Gate: {data[i]['departure']['terminal']}{data[i]['departure']['gate']}")
        print(f"Estimated Departure: {data[i]['departure']['estimated']}")
        print(f"Actual Departure: {data[i]['departure']['actual']}")
        print(f"Arrival Airport: {data[i]['arrival']['airport']}")
        print(f"Arrival Timezone: {data[i]['arrival']['timezone']}")
        print(f"Arrival IATA/ICAO: {data[i]['arrival']['iata']} | {data[i]['arrival']['icao']}")
        print(f"Arrival Terminal/Gate: {data[i]['arrival']['terminal']}{data[i]['arrival']['gate']}")
        print(f"Estimated Arrival: {data[i]['arrival']['estimated']}")
        print(f"Actual Arrival: {data[i]['arrival']['actual']}")
        print("-------------------------------------------------------------------")
```

#### Fetching Data by Arrival IATA
```python
if option == 'arr_iata':
    arr_iata = input(f"{question} Enter a flight arrival IATA: ")
    data = requests.get(f"http://api.aviationstack.com/v1/flights?access_key={key}&arr_iata={arr_iata}").json()['data']
    for i in range(0,len(data)):
        print(f"Airline Name: {data[i]['airline']['name']}")
        print(f"Flight Date: {data[i]['flight_date']}")
        print(f"Status: {data[i]['flight_status']}")
        print(f"Departure Airport: {data[i]['departure']['airport']}")
        print(f"Departure Timezone: {data[i]['departure']['timezone']}")
        print(f"Departure IATA/ICAO: {data[i]['departure']['iata']} | {data[i]['departure']['icao']}")
        print(f"Departure Terminal/Gate: {data[i]['departure']['terminal']}{data[i]['departure']['gate']}")
        print(f"Estimated Departure: {data[i]['departure']['estimated']}")
        print(f"Actual Departure: {data[i]['departure']['actual']}")
        print(f"Arrival Airport: {data[i]['arrival']['airport']}")
        print(f"Arrival Timezone: {data[i]['arrival']['timezone']}")
        print(f"Arrival IATA/ICAO: {data[i]['arrival']['iata']} | {data[i]['arrival']['icao']}")
        print(f"Arrival Terminal/Gate: {data[i]['arrival']['terminal']}{data[i]['arrival']['gate']}")
        print(f"Estimated Arrival: {data[i]['arrival']['estimated']}")
        print(f"Actual Arrival: {data[i]['arrival']['actual']}")
        print("-------------------------------------------------------------------")
```

#### Fetching Flight Data by Flight Status
```python
if option == 'status':
    status = input(f"{question} Enter a flight status (scheduled, active, landed, cancelled, incident, diverted): ")
    data = requests.get(f"http://api.aviationstack.com/v1/flights?access_key={key}&status={status}").json()['data']
    for i in range(0,len(data)):
        print(f"Airline Name: {data[i]['airline']['name']}")
        print(f"Flight Date: {data[i]['flight_date']}")
        print(f"Status: {data[i]['flight_status']}")
        print(f"Departure Airport: {data[i]['departure']['airport']}")
        print(f"Departure Timezone: {data[i]['departure']['timezone']}")
        print(f"Departure IATA/ICAO: {data[i]['departure']['iata']} | {data[i]['departure']['icao']}")
        print(f"Departure Terminal/Gate: {data[i]['departure']['terminal']}{data[i]['departure']['gate']}")
        print(f"Estimated Departure: {data[i]['departure']['estimated']}")
        print(f"Actual Departure: {data[i]['departure']['actual']}")
        print(f"Arrival Airport: {data[i]['arrival']['airport']}")
        print(f"Arrival Timezone: {data[i]['arrival']['timezone']}")
        print(f"Arrival IATA/ICAO: {data[i]['arrival']['iata']} | {data[i]['arrival']['icao']}")
        print(f"Arrival Terminal/Gate: {data[i]['arrival']['terminal']}{data[i]['arrival']['gate']}")
        print(f"Estimated Arrival: {data[i]['arrival']['estimated']}")
        print(f"Actual Arrival: {data[i]['arrival']['actual']}")
        print("-------------------------------------------------------------------")
```

#### Fetching Flight Data by ICAO24
This method of search is quite different, as we are using the Opensky API. There is also less available data, as it relates to the specified aircraft.
```python
if option == 'icao24':
    icao24 = input(f"{question} Enter a plane icao24: ")
    begin = input(f"{question} Enter a begin Unix timestamp for the flights interval: ")
    end = input(f"{question} Enter an end Unix timestamp for the flights interval: ")
    data = requests.get(f"https://opensky-network.org/api/flights/aircraft?icao24={icao24}&begin={begin}&end={end}").json()
    for i in range(0,len(data)):
        print(f"Aircraft Callsign: {data[i]['callsign']}")
        print(f"Departure Airport (Estimated): {data[i]['estDepartureAirport']}")
        print(f"Arrival Airport (Estimated): {data[i]['estArrivalAirport']}")
        print(f"Arrival Airport (Estimated): {data[i]['estArrivalAirport']}")
        print(f"First Seen: {data[i]['firstSeen']}")
        print(f"Last Seen: {data[i]['lastSeen']}")
        print("-------------------------------------------------------------------")
```

---

### Conclusion

This feature is a part of my OSINT / digital forensics project, Horus. For the complete code to this project visit the [Horus GitHub repository](https://github.com/6abd/horus). You can support Horus by leaving a star!

---

### References and Resources

- [Aviationstack API Documentation](https://aviationstack.com/documentation)
- [OpenSky Network API Documentation](https://opensky-network.org/apidoc/index.html)
- [Python Requests Library Documentation](https://docs.python-requests.org/en/latest/)
- [Colorama Library Documentation](https://pypi.org/project/colorama/)