Skip to content

Python Connector

The Python connector gives an easy entry-point to use OKAPI software from within your own python code. We recommend using the package provided via PyPI (see below), as this is updated with every release of OKAPI and actively maintained. If you prefer building your own code, you find the complete source code of the connector on Github.

This complete section is split into the following sections:

  1. Getting started explains how to install and update the OKAPI package on your machine using PIP. And how to setup a python virtual environment.
  2. Using the connector explains the general features of the connector as well as a short introduction into the error handling.
  3. Interacting with the API gives you a script including an exemplary login, sending and getting of the request.

We suggest that you go through the items once to ensure that you do not miss any important information.

Getting started

Creating a virtual environment

It is good practice to always work in virtual environments. Following this practice helps you to avoid incompatibilities between different versions of packages required by your project. To create a virtual environment, choose a directory where you want to place it, and execute the venv module from Python (this works on Mac, Linux, and Windows):

python3 -m venv name-of-virtual-environment
This will create the directory name-of-virtual-environment which contains a copy of your Python intepreter, standard libraries, and supporting files and scripts. After creating the environment, you need to activate it to be able to use it. On Linux and Mac run:
source name-of-virtual-environment/bin/activate
On Windows, run

  tutorial-env\Scripts\activate.bat
  tutorial-env\Scripts\activate.ps1

It can happen that you receive the error parameter format not correct on Windows. In that case, open the activate.bat script, and replace delims=:" in the 4th line with delims=:." (note the ".").

Your virtual environment is now ready to be used. Note that it contains no packages, so you would have to install all packages required for your own project. At the end of your work, you should always deactivate the current virtual environment with

deactivate
For more details on setting up virtual environment, you can start from here.

Installing the connector using PIP

The connector has been designed to run with python3. Therefore, make sure that you are using python3 for all commands. Depending on your system configuration, python might point to python3 already, or not. So make sure you know what you are using. To install the OKAPI connector, run (if you are using the powershell on Windows, you might have to replace python3 with python.exe, and pip3 with pip3.exe):

pip3 install okapi-python-connector --no-cache-dir

You now have successfully installed the latest version of the okapi-python-connector. You always should make sure that the version of the python connector matches that of the OKAPI software. You can get the current version number (.e.g 2020.9.6) of the python connector using pkg_resources in python (again: you might have to change python3 into python3.exe on Windows):

python3 -c "import pkg_resources; print(pkg_resources.get_distribution('okapi-python-connector').version)"

Updating the connector using PIP

If you need to upgrade your python connector, run (use python.exe on windows):

pip3 install okapi-python-connector --upgrade

Alternatively, you can get the complete source code of the connector on Github.

Using the connector

After installing, you have to import the needed functions into your current code. For this you can create a python source file, e.g. predict-passes.py. Mind the .py suffix. You can edit the file using your favourite python IDE, for example VS Code or Pycharm. Please note that you download the entire code from below from GitHub.

Authentication

Authentication is achieved by calling the okapi_init function. An invocation will let you receive a JWT token from auth0:

okapi_login, error = okapi_init("https://api.okapiorbits.com/", "YOUR_EMAIL","YOUR_PASSWORD")

The function returns a dict okapi_login, which contains your JWT token needed to get server access and an error dict. The latter one contains three fields. They give an overview status as well as some further information. Make sure to always check against the error['status'] to catch your code in case something went wrong. It can contain the values FATAL, WARNING, INFO and NONE. In case of fatal errors, you should never use the result that might have been delivered. If you get a warning, you should check the reason for that. In most cases, it is nothing of concern. But especially if you get a warning together with an error['web_status'] of 202, it means that your process has been accepted, but is not fully processed yet. In that case, you should ask for the results short later again! Infos might be interesting to read, but do not indicate that something went wrong. If you get none, it means that no message was returned. error['message'] gives you extra information on the error that occurred, error['web_status'] returns the http status code from the last request. Knowing this one is very helpful, in case there are issues with the internet connectivity, authentication or our server. Here is one example how to check the error:

if (error.get('status','') == 'FATAL'):
    print(error)
    exit('Error.')

Interacting with the API

Once you have received your token, you are ready to run computations. To send a request, you have to prepare a json object containing the description of your request. In python, you can use dicts for that, which are formatted identically to json. A detailed description of the available endpoints and the datatypes you can send is given in the API documentation. If that is set up, you can create a request as follows:

result, error = okapi_send_request_and_wait_for_result(okapi_login, request_body, url_endpoint_requests, url_endpoint_results, max_poll_time)

You see that you have to provide the okapi_login, the request_body, which contains your request as dict, the endpoint_url_request and the endpoint_url_results, which are given in the API documentation for all functionalities available, as well as the max_poll_time. The latter determines how long you wait for the result (in seconds). The response contains the result of your computation. If your result could not been processed in the allowed time, you will receive an error. You probably noticed that this approach has one downside: You are blocking your code while something is running on an external machine. In many cases, you would not want that behaviour. For this, the connector provides different layers of abstraction: * you can send a computation request and wait for results (what we did here), * you can send a computation request and at a later point call a routine that waits for and gets the results, or * you can handle both steps yourself. In the example code below, you find simple implementations for all three cases.

For an easy start, you find a python script called tryout.py on GitHub. Make sure that you entered your email address and password in the call of the authentication routine. If you just need one first example, you can also use the following python script. It calculates the pass of a satellite over a groundstation.

#!/usr/bin/python

import time

from okapi_pkg import *

#
# Init --> Get a token to run the analyses
#
# For auth info: See www.okapiorbits.space or contact us. Standard url is: https://api.okapiorbits.com/
okapi_login, error = okapi_init(  https://api.okapiorbits.com/ ,
                                 < user account email as string > ,
                                 < user password as string > )

# check for the error status
if (error.get('status','') == 'FATAL'):
    print(error)
    exit('Error during authentification.')
# print(okapi_login)

#
# Pass predictions
#

#
# # Prepare your request
pass_pred_request_body = {
    "orbit":{
      "type": "tle.txt",
      "content": "1 25544U 98067A   18218.76369510  .00001449  00000-0  29472-4 0  9993\n2 25544  51.6423 126.6422 0005481  33.3092  62.9075 15.53806849126382"
    },
    "ground_location": {
      "type": "ground_loc.json",
      "content": {
        "altitude": 0.17012,
        "longitude": 10.07,
        "latitude": 50.2
      }
    },
    "time_window": {
      "type": "tw.json",
      "content": {
        "start": "2018-08-07T18:00:00.000Z",
        "end": "2018-08-08T00:00:00.000Z"
      }
    }
}

#
# # send different pass prediction pass prediction requests, use the bare functions to send and get results
#
# # send a request to use SGP4 for pass prediction
request_sgp4, error = okapi_send_request(okapi_login, pass_pred_request_body,
                                         'predict-passes/sgp4/requests')
if (error.get('status','') == 'FATAL'):
    print(error)
    exit()

# loop until the result has been fully processed. Alternatively, you could
# also just "sleep" for a while
counter = 0
while ((counter < 15) and (error.get('web_status','') == 202)):

  # get the result from SGP4
  result_sgp4, error = okapi_get_result(okapi_login, request_sgp4,
                                        'predict-passes/sgp4/results/{}/simple')

  if (error.get('status','') == 'FATAL'):
      print(error)
      exit()
  elif(error.get('status','') == 'WARNING'):
      print(error)

  counter = counter + 1

# print(result_sgp4)


#
# # First alternative: Send the result yourself, but use a dedicated function to wait for and get the result
#
# # send a request to use SGP4 for pass prediction
request_sgp4, error = okapi_send_request(okapi_login, pass_pred_request_body,
                                         'predict-passes/sgp4/requests')
if (error.get('status','') == 'FATAL'):
    print(error)
    exit()

# call the function to wait for and get the result
result_sgp4, error = okapi_wait_and_get_result(okapi_login, request_sgp4,
                                      'predict-passes/sgp4/results/{}/simple', 15)

if (error.get('status','') == 'FATAL'):
    print(error)
    exit()
elif(error.get('status','') == 'WARNING'):
    print(error)

# print(result_sgp4)

#
# # Third alternative: Use a function to send, wait-for and get the result. Note that this might block your code while running
#
# # send a request to use SGP4 for pass prediction
result_sgp4, error = okapi_send_request_and_wait_for_result(okapi_login, pass_pred_request_body,
                                      'predict-passes/sgp4/requests',
                                      'predict-passes/sgp4/results/{}/simple', 15)

if (error.get('status','') == 'FATAL'):
    print(error)
    exit()
elif(error.get('status','') == 'WARNING'):
    print(error)