Skip to content

Python Interpreter examples

Here you can see how we load and execute Python scripts inside a Sen process.

First make sure that you have the PYTHONPATH environment variable correctly set to point to our example scripts:

For bash:

export PYTHONPATH=$PYTHONPATH;$(pwd)/config/10_python/scripts

For fish:

set -xa PYTHONPATH $(pwd)/config/10_python/scripts

Hello Python

In this example we just show how to get a Python interpreter running inside a Sen component.

Run it with:

sen run config/10_python/1_python_hello.yaml
hello_python.py
# === hello_python.py ==================================================================================================
#                                               Sen Infrastructure
#                   Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
#                                    See the LICENSE.txt file for more information.
#                   © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
# ======================================================================================================================

import sen

# this is executed only once (at the start of the component execution)
def run():
    print(f"Python: run")
    print(f"Python: the config is: {sen.api.config}")
    print(f"Python: the app name is: {sen.api.appName}")


# this is executed every cycle
def update():
    print(f"Python: update (current time: {sen.api.time})")

# this is executed only once (at the end of the component execution)
def stop():
    print(f"Python: stop called")
1_python_hello.yaml
# $schema: ../base/schema.json
include:
  - ../base/shell.yaml

load:
  - name: py
    group: 3
    freqHz: 1
    module: hello_python

Inspecting objects

In this example we can see how to fetch objects coming from other components and print their properties.

Run it with:

sen run config/10_python/2_python_inspect_objects.yaml

This example contains the following files:

inspecting_objects.py
# === inspecting_objects.py ============================================================================================
#                                               Sen Infrastructure
#                   Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
#                                    See the LICENSE.txt file for more information.
#                   © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
# ======================================================================================================================

import sen

# to store the objects that we want to inspect
list = None


def run():
    global list  # refer to the global variable defined above

    list = sen.api.open("SELECT * FROM local.kernel")  # open it

    # register some callbacks to show changes in the list
    list.onAdded(lambda obj: print(f'Python: object added {obj}'))
    list.onRemoved(lambda obj: print(f'Python: object removed {obj}'))


def update():
    # refer to the global variable defined above
    global list

    print(f"Python: printing the list at: {sen.api.time})")
    print(list)

    print("Python: iterating over the objects in the list:")
    for obj in list:
        print(f"Python: * object {obj.name}")
        print(f"Python:   - class: {obj.className}")
        print(f"Python:   - id:    {obj.id}")
        print(f"Python:   - time:  {obj.lastCommitTime}")
2_python_inspect_objects.yaml
# $schema: ../base/schema.json
include:
  - ../base/shell.yaml

load:
  - name: py
    group: 3
    freqHz: 1
    module: inspecting_objects

Creating objects

In this example we ee how to create and publish objects using Python.

Run it with:

sen run config/10_python/3_python_create_objects.yaml

This example contains the following files:

creating_objects.py
# === creating_objects.py ==============================================================================================
#                                               Sen Infrastructure
#                   Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
#                                    See the LICENSE.txt file for more information.
#                   © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
# ======================================================================================================================

import sen

myObject = testBus = None

def run():
    global myObject, testBus  # refer to the globals defined above

    type = {
        "entityKind": 1,
        "domain": 2,
        "countryCode": 198,
        "category": 1,
        "subcategory": 3,
        "specific": 0,
        "extra": 0
    }

    id = {
        "entityNumber": 1,
        "federateIdentifier": {
            "siteID": 1,
            "applicationID": 1
        }
    }

    print(f"Python: creating and publishing the object")
    myObject = sen.api.make("aircrafts.DummyAircraft", "myAircraft", entityType=type, alternateEntityType=type, entityIdentifier = id)
    testBus = sen.api.getBus("my.tutorial")
    testBus.add(myObject)

def update():
    print(myObject)

def stop():
    global testBus, myObject  # refer to the globals defined above

    print("Python: deleting the object")
    testBus.remove(myObject)
    myObject = None
    testBus = None
3_python_create_objects.yaml
# $schema: ../base/schema.json
include:
  - ../base/shell.yaml

load:
  - name: py
    group: 3
    freqHz: 1
    module: creating_objects
    imports: [aircrafts]

Interacting with objects

Here we can see how to call methods on objects coming from other components.

Run it with:

sen run config/10_python/4_python_interact_with_objects.yaml

This example contains the following files:

interacting_with_objects.py
# === interacting_with_objects.py ======================================================================================
#                                               Sen Infrastructure
#                   Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
#                                    See the LICENSE.txt file for more information.
#                   © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
# ======================================================================================================================

import sen

# to store the object
obj = None


def run():
    global obj  # refer to the global variable defined above
    obj = sen.api.open("SELECT * FROM local.shell WHERE name = \"shell_impl\"")


def update():
    global obj  # refer to the global variable defined above
    print("Python: update")

    # if the object is present, do something with it
    if len(obj) != 0:
        print("Python: interacting with the object")
        obj[0].info("i16")  # print the info of the i16 type
        obj[0].ls()  # list the current objects in the terminal
        obj[0].history()  # show the current history

        print("Python: asking the process to shut down")
        obj[0].shutdown()  # trigger the process shutdown
4_python_interact_with_objects.yaml
# $schema: ../base/schema.json
include:
  - ../base/shell.yaml

load:
  - name: py
    group: 3
    freqHz: 1
    module: interacting_with_objects

Reacting to events and changes

Here we can see how to execute Python code when events are produced or properties change.

It relies on the "school" example to get some activity going.

Run it with:

sen run config/10_python/5_python_react_to_events.yaml

This example contains the following files:

reacting_to_events_and_changes.py
# === reacting_to_events_and_changes.py ================================================================================
#                                               Sen Infrastructure
#                   Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
#                                    See the LICENSE.txt file for more information.
#                   © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
# ======================================================================================================================

import sen

# to store the objects
teachers = None


def teacherDetected(teacher):
    teacher.onStressLevelPeaked(lambda args: print(f"Python: {teacher.name} stress level peaking to {args}"))
    teacher.onStatusChanged(lambda: print(f"Python: {teacher.name} status changed to {teacher.status}"))


def run():
    global teachers  # refer to the global variable defined above

    print("Python: run")

    # select the object and install some callbacks
    teachers = sen.api.open("SELECT school.Teacher FROM school.primary")
    teachers.onAdded(lambda obj: teacherDetected(obj))
5_python_react_to_events.yaml
# $schema: ../base/schema.json
include:
  - ../base/shell.yaml
  - ../4_school/1_school_two_classrooms_one_component.yaml

load:
  - name: py
    group: 3
    freqHz: 1
    module: reacting_to_events_and_changes

Using the interpreter from other components

Here we publish the interpreter object and can use it from within our shell component.

sen run config/10_python/6_python_interpreter.yaml

This example contains the following files:

6_python_interpreter.yaml
# $schema: ../base/schema.json
include:
  - ../base/shell.yaml

load:
  - name: shell
    open: [local.py]
  - name: py
    group: 3
    freqHz: 30
    bus: local.py

If you open the shell you can use the interpreter with something like this:

sen:enrique-debian/6_python_interpreter> local.py.interpreter.eval "2+2"
"4"

The eval function evaluates an expression and returns the result.

sen:enrique-debian/6_python_interpreter> local.py.interpreter.exec "x = 2"

The exec function executes statements.

sen:enrique-debian/6_python_interpreter> local.py.interpreter.eval "2+x"
"4"

The interpreter holds an internal state, so you can use it in your evaluations.