Data Science: International Space Station — pt.1

Igor Comune
5 min readJun 25, 2023

--

Source: NASA — Link.
  1. API Source.
  2. For codes of this post, check my GitHub’s repository.
  3. Visual Studio Code and Anaconda’s JupyterLab tools will be used to this analysis.

For all my posts, please click here.

The ISS

“It is a multinational collaborative project involving five participating space agencies: NASA (United States), Roscosmos (Russia), JAXA (Japan), ESA (Europe), and CSA (Canada). The ownership and use of the space station is established by intergovernmental treaties and agreements. The station serves as a microgravity and space environment research laboratory in which scientific research is conducted in astrobiology, astronomy, meteorology, physics, and other fields.” — Wikipedia

The Data Base

Well… there will be no data base…

It’s our duty to create a data base from scratch.

In order to create a data base, we’ll use local PostgreSQL as Database, and we’ll download data from an API (application programming interface) from https://wheretheiss.at/. This API returns us (near) real time data on ISS status as JSON format file. Let me show the example:

{'name': 'iss',
'id': 25544,
'latitude': 46.689167896277,
'longitude': 35.51509536384,
'altitude': 422.39287126794,
'velocity': 27594.173470412,
'visibility': 'daylight',
'footprint': 4519.6173354835,
'timestamp': 1633787189,
'daynum': 2459497.0739468,
'solar_lat': -6.4851436217594,
'solar_lon': 330.17907104013,
'units': 'kilometers'}

After the basic configuration the PostgreSQL and the analysis of the data from an API call I decide to create a basic table, so, it’s not optimize… all the fields will exactly the same:

-- creating the table

CREATE TABLE public.iss_table
(
name char (50) NOT NULL,
id char (50) NOT NULL,
latitude char (50) NOT NULL,
longitude char (50) NOT NULL,
altitude char (50) NOT NULL,
velocity char (50) NOT NULL,
visibility char (50) NOT NULL,
footprint char (50) NOT NULL,
"timestamp" char (50) NOT NULL,
daynum char (50) NOT NULL,
solar_lat char (50) NOT NULL,
solar_lon char (50) NOT NULL,
units char (50) NOT NULL
);

ALTER TABLE IF EXISTS public.iss_table
OWNER to postgres;

And checked if the table is ok:

select * from iss_table

Now we already know our data, we created a table to receive the data… the next 2 steps are:

  1. Download the data
  2. Insert the data into the table

Downloading the Data from the API

Using Python, I wrote a simple code that gets the data from the API in JSON format, extract its values and append it to an empty list which will be returned in the iss_api() function:

import requests

class Download:
def __init__(self) -> None:
"""
Initializes a Download object.
"""
pass

def iss_api(self):
"""
Makes an API request to retrieve information about the International Space Station (ISS).

Returns:
list: A list of values extracted from the API response.
"""
iss = requests.get('https://api.wheretheiss.at/v1/satellites/25544').json()
values = iss.values()

list_values = []
for value in values:
list_values.append(value)

return list_values

Well, class and function create, now we’re ready to send the data into our table.

Inserting the Data into the Table

In order to insert the data into our table was required to build a new code, which I called main.py.

import psycopg2
from time import sleep
from download_data import Download

class Postgre():
def __init__(self) -> None:
pass

def download_data():
# Calls the `iss_api` method from the `Download` class to download data
values = Download().iss_api()
return values

def db(self):
# Establishes a connection to the PostgreSQL database
hostname = "localhost"
username = "postgres"
password = "password"
database = "ISS"
schema = "public"

conn = psycopg2.connect(host=hostname,
user=username,
password=password,
dbname=database,
options=f'-c search_path={schema}')
cur = conn.cursor()

return cur, conn

def close_connection(self):
# Closes the database connection
cur, conn = Postgre.db()
cur.close()
conn.close()
print('Connection Closed!')

def insert_db(self):
# Retrieves data from the ISS API using the `download_data` method
values = Postgre.download_data()
print(values)

# Converts values to strings
value0 = str(values[0])
value1 = str(values[1])
value2 = str(values[2])
value3 = str(values[3])
value4 = str(values[4])
value5 = str(values[5])
value6 = str(values[6])
value7 = str(values[7])
value8 = str(values[8])
value9 = str(values[9])
value10 = str(values[10])
value11 = str(values[11])
value12 = str(values[12])

# Establishes a database connection
cur, conn = Postgre.db()

# Executes an SQL INSERT statement to insert values into the 'iss_table' table
cur.execute(f"INSERT INTO iss_table (name, id, latitude, longitude, altitude, velocity, visibility, footprint, timestamp, daynum, solar_lat, solar_lon, units) VALUES ('{value0}', '{value1}', '{value2}', '{value3}', '{value4}', '{value5}', '{value6}', '{value7}', '{value8}', '{value9}', '{value10}', '{value11}', '{value12}')")

# Commits the transaction
conn.commit()
print('Values successfully inserted into the iss_table')

# Closes the database connection
Postgre.close_connection()

if __name__ == '__main__':
# Loops indefinitely and inserts data into the database every 60 seconds
while True:
Postgre.insert_db()
sleep(60)

Let me explain how it works. The code begins by importing the necessary modules: psycopg2 for working with PostgreSQL databases and sleep from the time module for the delay between data insertions. It also imports the Download class from the download_data module.

  1. The download_data() method calls the iss_api() method from the Download class to retrieve data from the ISS API. The downloaded data is returned as a list of values.
  2. The db() method establishes a connection to the PostgreSQL database. It uses the provided connection parameters (hostname, username, password, database, schema) to connect to the database and returns the cursor (cur) and connection (conn) objects.
  3. The close_connection() method closes the database connection. It retrieves the cursor and connection objects by calling the db() method and then closes them. It also prints a message indicating that the connection has been closed.
  4. The insert_db() method is responsible for retrieving data from the ISS API, converting the values to strings, establishing a database connection, inserting the values into the iss_table table using an SQL INSERT statement, committing the transaction, and finally closing the connection. It also prints a success message after the data insertion.
  5. The if __name__ == '__main__': block ensures that the code inside it is only executed when the script is run directly. It contains a while loop that runs indefinitely, calling the insert_db() method and then pausing execution for 60 seconds using the sleep() function from the time module.
Image 1 — How main.py works

This is how our code is working:

Image 2— Code Diagram

The ‘main.py’ calls from ‘download_data.py’ (‘iss_api’ function), which sends a request to the ‘ISS API’ which sends us a JSON file.

The ‘download_code.py’ transforms the JSON into a list and send the list to ‘main.py’ and it sends a SQL Insert command to the iss_table in our DB.

To summarize, when the script is run, it repeatedly fetches data from the ISS API, inserts it into a PostgreSQL database, and waits for 60 seconds before repeating the process. The connection to the database is opened and closed for each insertion.

The Next Post

I’ll analyse the data from the ISS.

Stay tuned for more!

Igor Comune | LinkedIn

--

--

Igor Comune

An "under construction" Data Scientist with a love for numbers and analysis!