API - Python Examples
  • 13 Mar 2024
  • 5 Minutes to read
  • Contributors
  • Dark
    Light
  • PDF

API - Python Examples

  • Dark
    Light
  • PDF

Article summary

This article describes an example tool written in Python which can be used to access the Safety Pool Scenario Database (SPSD) API. The purpose of the tool is to provide working code which demonstrates how to use the API and which can be used as a basis for building your own tools for accessing the API to retrieve Scenarios, Test Suites, and Ontologies.

All of the code for the tool can be found in the following zip file.

Information
Before using the tool, you might find it helpful to read through this article which describes the Safety Poolâ„¢ Scenario Database (SPSD) Application Programming Interface (API).

Installing the tool

Firstly, make sure you have Python installed on your system.

  1. Download and unzip the attached file
  2. Run Main.py
  3. Insert your API Key (Refer to this article on how to generate the API Key)
  4. Once your API Key has been validated, you are able to run any of the functions in the image below

Note
The tool will automatically install the following modules: 'requests', 'inquirer v2.10.0', 'texttable v1.6.4' and 'colorama v0.4.5' which are required to run the tool.

How the tool works

This section explains in detail the authentication process and each of the functions available in the tool.

Authentication

For every request, the tool will request a Token from the Safety Pool API using your API Key. The generate_token() function in GenerateToken.py is used for processing this step. If the API key is valid (HTTP status code is 200) then it will return a 'Token', otherwise, it will return 'False' which means the API Key is not valid.

import requests
from requests.structures import CaseInsensitiveDict
from options import user_api_key

# This APIKey will hold the user Key 
APIKey = user_api_key()

def generate_token():
    
        headers = CaseInsensitiveDict()
        headers["Accept"] = "application/json"
        headers["User-Agent"] = "ServerTest"
        URLGenerateToken= "https://live.safetypooldb.ai/api/createtoken/" + APIKey
        req = requests.post(URLGenerateToken,headers=headers)

        if req.status_code == 200:
        
            TokenResult = req.json()
            Token=TokenResult['token']
            return Token
            
        else:
            Token = False
            return Token

List all Test Suites

Choosing this option will call the get_testsuites_list() function which can be found in TestSuitesList.py. It will present a table of all available Test Suites with their IDs, names, and the number of scenarios. 


To retrieve a Test Suite, you need to input the ID of the Test Suite. In the example above, choosing ID = 1 will retrieve all the scenarios (6 scenarios) in the 'Testing' Test Suite as in the screenshot below. The function GetScenariosByID() in GenerateScenarioFromTS.py processes this request. For all of the retrieved scenarios, the scenario definition will be saved in a folder called 'Generated SDL' using the WMG SDL format. For more about SDL please refer to this article. The file name used for each scenario will be its URN (Unique Reference Number) which corresponds with the URN field visible in the Scenario View in Safety Pool.


Each time the tool is started, the content in the 'Generated SDL' will be deleted. If you want to disable this and keep the previous SDLs, you need to comment out the function cleanupGeneratedSdl() in Main.py.

List all Test Suites in JSON format

You can also retrieve all Test Suites in JSON format. The function get_testsuites_json() in GenerateTSjson.py processes this.

Example of the python script used:

import requests
from requests.structures import CaseInsensitiveDict
from authentication.GenerateToken import generate_token
import json
from progressbar import *
from colorama import Fore, Back, Style
Token = generate_token()

# Get a list of testsuites in json format and saved it Generated Json
def get_testsuites_json():

    headers = CaseInsensitiveDict()
    headers["User-Agent"] = "ServerTest"
    headers["Authorization"] = "Bearer "+ Token
    GetSDLUrl = "https://live.safetypooldb.ai/api/testsuites/" 
    res = requests.get(GetSDLUrl, headers=headers)
    JsonResult = res.json()
    TestSuitesFileName = "TestSuites"
    json_string = json.dumps(JsonResult)

    # print(json_string)
    with open("Generated Json/"+TestSuitesFileName + ".json", "w") as f:
        f.write(json_string)
        print(Fore.GREEN+"The list of testsuites in josn format has been successfully created in the 'Generated Json' folder ")
        print(Style.RESET_ALL)

 The generated JSON will be placed in the folder 'Generated Json' - below is the sample output.

[
    {
        "testsuiteid": 1,
        "name": "Testing",
        "scenarios": [
            "45b3cae7-5ca6-450d-ad49-1141be15c24b",
            "928351c3-caad-439d-abe9-fad40e7b5377",
            "59c9bdfe-799a-4e1f-a15b-37846a45c0c6",
            "111fe686-3615-4a4f-b7a2-4bdd1a8ec3eb",
            "a29bf01b-7838-4c56-ac40-739c0b178500",
            "587d523c-4178-4e9c-aa85-a624cf76c9a3"
        ]
    },
    {
        "testsuiteid": 8,
        "name": "Roundabouts",
        "scenarios": [
            "8cc4780e-8478-4aab-8a42-6880a0813fba",
            "85818cb2-c0aa-4c17-af2e-2ead2200ffa9",
            "2751823c-c49c-42aa-b525-2c176b9da83f",
            "2f2f908e-16fb-4788-b379-a672ea7e9d51"
        ]
    },
    {
        "testsuiteid": 52,
        "name": "Test 7",
        "scenarios": []
    },
    {
        "testsuiteid": 53,
        "name": "Test 10",
        "scenarios": [
            "ccf96fcf-4b33-4dbb-87a2-c7c531435a65"
        ]
    },
    {
        "testsuiteid": 55,
        "name": "ODD",
        "scenarios": [
            "59c9bdfe-799a-4e1f-a15b-37846a45c0c6",
            "6f55b674-6d6e-452b-92ca-cc1ac8c74d3d"
        ]
    },
    {
        "testsuiteid": 76,
        "name": "Pedestrian Crossing",
        "scenarios": [
            "7a0c4365-7d22-400e-9c0a-aee341a3c99b",
            "556199ac-ac81-48d1-8cfc-7a833048c00d",
            "8e4a1b1d-a98d-41cc-a728-bb0fd3c8a3ba"
        ]
    }
]

Retrieve a single Scenario

This option allows you to retrieve a scenario by specifying the URN of the scenario. The retrieved scenario is then saved to the 'Generated SDL' folder in WMG SDL format. This process is performed by the function get_single_scenario() in GenerateSingleScenario.py. 

import requests
from requests.structures import CaseInsensitiveDict 
from authentication.GenerateToken import generate_token
from colorama import Fore, Back, Style
from progressbar import *

Token = generate_token()

# get single scenario based on the the scenario ID the user enters.

def get_single_scenario():
        valid_int = False
        while not valid_int: #loop until the user enters a valid int
                
                ScenarioID = input(Fore.BLUE+'\nEnter the scenario Id: ') 
                valid_int = True #if this point is reached, TestSuitID is a valid int
                print(Style.RESET_ALL)


                # Retrive Single Scenario
                headers = CaseInsensitiveDict()
                headers["User-Agent"] = "ServerTest"
                headers["Authorization"] = "Bearer "+ Token
                url = "https://live.safetypooldb.ai/api/scenarios/"+ ScenarioID
                resp = requests.get(url, headers=headers)    
                JsonResult= resp.json()

                # -------- Generate SDL File for single scenario  ---------


                # get the index of where the 'scenarioDefinition' is existed

                if resp.status_code == 200:
                        for i in progressbar(range(1), "Retrieving scenario '"+ScenarioID+"' in progress .... ", 30):
                                types = []
                                Index_SD = 0
                                for k, v in JsonResult["openlabel"]["tags"].items():
                                        types.append(v["type"])
                                        for i, j in enumerate(types):
                                                if j == 'scenarioDefinition':
                                                        Index_SD = i                      
                                ScenarioDefintion = JsonResult['openlabel']['tags'][str(Index_SD)]["tag_data"]["text"][0]["val"]

                                
                                f = open( "Generated SDL/"+ScenarioID + ".sdl", "w")
                                f.write(ScenarioDefintion)
                        print(Fore.GREEN+"The scenario '"+ScenarioID+"' has been successfully downloaded in the 'Generated SDL' folder ")
                elif resp.text =='"Restricted scenarios cannot be download"':
                        print("This scenario is restricted and cannot be download")
                else:
                        print("please check if the scenario id is correct")
        
      

Retrieve Ontologies

You can retrieve the ontologies used by Safety Pool by specifying the required ontology version. The function get_ontology()  will return the Safety Pool tagging ontology in Turtle format and save it in the 'Generated Ontology' folder.

Note
For every request, the tool will clean the folders Generated SDL and Generated Ontologies so if you want to keep retrieved data you should copy the data to another folder.

The folder clean-up functions are located in cleanup.py as shown below.

import glob
import os

# delete the content of the folders 'Generated SDL' and Generated Ontology for everyrequest
def cleanupGeneratedSdl():
    SDLpath = os.path.join('Generated SDL/*')
    tempPath = glob.glob(SDLpath)
    for t in tempPath:
        os.remove(t)
def cleanupGeneratedOntology():
    SDLpath = os.path.join('Generated Ontology/*')
    tempPath = glob.glob(SDLpath)
    for t in tempPath:
        os.remove(t)

If you want to keep the generated SDL and/or Ontologies files, you need to comment out the cleanupGeneratedSdl() and cleanupGeneratedOntology(from  Main.py.


Was this article helpful?