Programmer’s Guide

Obtaining Help

via STK Programming Documentation

The STK Python API help documents the method/property definitions with syntax using the Python typing module. The following example method and property from the IAgStkObjectRoot interface show this syntax.

def GetObjectFromPath(self, ObjectPath:str) -> "IAgStkObject":

@property
def CurrentScenario(self) -> "IAgStkObject":

These examples show that interface methods and properties are methods called on an object ("self"). Input argument names (e.g. "ObjectPath") are shown for methods along with the type of the argument (in this example, Python str type). The return type is shown after the "->" operator and STK Object Model types (e.g. "IAgStkObject") are shown in quotes to help IDEs resolve the type names. The Python API programmer may call these methods and properties on an IAgStkObjectRoot object in the expected way. In the following example, an IAgStkObjectRoot object named "root" has already been created.

my_object = root.GetObjectFromPath('My Object Path')

my_scenario = root.CurrentScenario

Within Interactive Python

The Python help function can be used to display the documentation of modules, functions, classes, keywords etc. Below is an example printing the help for the class returned by the object model root current scenario property.

# Start new instance of STK Engine using the new API
from agi.stk12.stkengine import STKEngine
from agi.stk12.stkobjects import *
stk = STKEngine.StartApplication(noGraphics=False) # optionally, noGraphics = True

# Get the IAgStkObjectRoot interface
root = stk.NewObjectRoot()

# Create a new scenario
root.NewScenario('HelpDemo')

# Output the documentation for the class returned by the CurrentScenario property
print(help(root.CurrentScenario))

This produces the following output:

Help on AgScenario in module agi.stk12.stkobjects object:

class AgScenario(IAgScenario, IAgStkObject, IAgLifetimeInformation)
| Class defining the Scenario object.
|
| Method resolution order:
| AgScenario
| IAgScenario
| IAgStkObject
| IAgLifetimeInformation
| builtins.object
|
| Methods defined here:
|
| __init__(self, sourceObject=None)
| Initialize self. See help(type(self)) for accurate signature.
|
| ----------------------------------------------------------------------
| Methods inherited from IAgScenario:
|
| GetAccessBetweenObjectsByPath(self, objectPath1:str, objectPath2:str) -> 'IAgStkAccess'
| Returns the access object currently associated with the two STK objects specified using their paths. The paths can be fully-qualified or truncated.
|
| GetExistingAccesses(self) -> list
| Returns an array of existing accesses in the current scenario. The result is a two-dimensional array of triplets where each triplet contains the paths of two objects participating in the access and a flag indicating whether the access is computed.
|
| SetDirty(self) -> None
| Sets the flag indicating the scenario has been modified.
|
| SetTimePeriod(self, startTime:Any, stopTime:Any) -> None
-- More --

Module Mapping

The below table provides the corresponding library for each Python module.

library Module

STK Graphics Primitives

agi.stk12.graphics

STK Access Constraint Plugin

agi.stk12.plugins.accessconstraintplugin

STK Attribute Automation

agi.stk12.plugins.attrautomation

STK Communications and Radar foundation

agi.stk12.plugins.commrdrfoundation

STK Coordinate(VGT) plugins

agi.stk12.plugins.crdnplugin

STK Astrogator plugin

agi.stk12.plugins.gatorplugin

STK HPOP plugins

agi.stk12.plugins.hpopplugin

STK Astrogator plugins

agi.stk12.plugins.propagator

STK plugin

agi.stk12.plugins.stkplugin

STK Radar plugins

agi.stk12.plugins.stkradarplugin

STK Utilities plugin

agi.stk12.plugins.utplugin

STK Objects

agi.stk12.stkobjects

STK Aviator

agi.stk12.stkobjects.aviator

STK Aviator MATLAB

agi.stk12.stkobjects.aviator.matlab

STK Util

agi.stk12.stkutil

STK X

agi.stk12.stkx

STK UI Application

agi.stk12.uiapplication

STK UI Core

agi.stk12.uicore

STK Vector Geometry Tool

agi.stk12.vgt

STK Desktop

This section describes how to use the API with STK Desktop. The STKDesktop.StartApplication and STKDesktop.AttachToApplication methods are available to obtain the STKDesktopApplication class and begin interacting with STK through the the AgUiApplication API. From the application interface, the most common way to begin working with STK is to use the IAgStkObjectRoot interface which is accessible as the Root property of the STKDesktopApplication object.

Starting a new STK Desktop instance

Use the STKDesktop.StartApplication method to start a new STK application session. The StartApplication method has optional arguments as a convenience to set commonly used properties: set visible=True to start STK in visible mode, and set userControl=True if you wish STK to remain open after finishing your Python script.

[Python - STK API]
# Start new instance of STK using the new API
from agi.stk12.stkdesktop import STKDesktop
from agi.stk12.stkobjects import *
stk = STKDesktop.StartApplication(visible=True) #using optional visible argument

# Get the IAgStkObjectRoot interface
root = stk.Root

Attaching to a running instance of STK Desktop

Use the STKDesktop.AttachToApplication method to attach to a running STK desktop application. The AttachToApplication method has an optional argument to specify the Process ID (pid) if more than one STK application is running.

[Python - STK API]
# Get reference to running STK instance using the new API
from agi.stk12.stkdesktop import STKDesktop
from agi.stk12.stkobjects import *
stk = STKDesktop.AttachToApplication()

# Get the IAgStkObjectRoot interface
root = stk.Root

Finishing your work with STK Desktop

STKDesktopApplication provides a ShutDown method that is the recommended way to terminate the connection to STK and free up resources. Set the UserControl property on STKDesktopApplication or when calling StartApplication to set the application behavior after the call to ShutDown.

[Python - STK API]
# Get reference to running STK instance using the new API
from agi.stk12.stkdesktop import STKDesktop
from agi.stk12.stkobjects import *
stk = STKDesktop.StartApplication(userControl=False)

# Do work...
stk.ShutDown()

Advanced Topic: Marshalling Across Threads

STKDesktop.CreateThreadMarshaller (stk_object_to_marshal) was added in STK 12.2.0 to assist with marshalling STK objects between Python threads. Because the STK Object model is not inherently thread-safe, this helper is needed to safely execute commands from multiple threads.

As this is an advanced feature, it should only be used by experienced users when necessary.

If using this feature, you are responsible for properly synchronizing across threads. An example application of this (shown below) would be to marshal IAgStkObjectRoot to a new thread and call NewScenario, so that the Python application main thread is not blocked while the scenario is created.

STKDesktop.CreateThreadMarshaller returns agi.stk12.stkdesktop.ThreadMarshaller which has the methods InitializeThread, ReleaseThread, and GetMarshalledToCurrentThread. InitializeThread must be called on the destination thread before the marshalled object can be used.

GetMarshalledToCurrentThread is called to return a copy of the marshalled object that may be used on the current thread. ReleaseThread must be called before the destination thread exits.

Each ThreadMarshaller may be used only once - the same ThreadMarshaller may not be passed to multiple threads.

[Python - STK API]
import threading
from agi.stk12.stkdesktop import STKDesktop

def asynchronous_new_scenario(rootMarshaller):
rootMarshaller.InitializeThread()
root = rootMarshaller.GetMarshalledToCurrentThread()
print(f'Creating a new scenario from thread {threading.get_ident()}.')
root.NewScenario('MyScenario')
rootMarshaller.ReleaseThread()

if __name__=='__main__':
print(f'Starting STK from thread {threading.get_ident()}.')
stk = STKDesktop.StartApplication(visible=True, userControl=False)
root = stk.Root
rootMarshaller = STKDesktop.CreateThreadMarshaller(root)
t = threading.Thread(target=asynchronous_new_scenario, args=(rootMarshaller,), daemon=True)
t.start()
t.join()
print(f'Terminating example from thread {threading.get_ident()}.')
stk.ShutDown()

STK Engine

This section describes how to use the API with STK Engine. The STK Engine API is supported on both Windows and Linux, although some features such as events are still under development. STK Engine runs in-process in your Python script so unlike STK Desktop, only one instance of engine is possible, which is started using STKEngine.StartApplication, returning the STKEngineApplication class and giving access to the AgSTKXApplication API. Unlike STKDesktopApplication, the object model root is not a property and a new root object may be obtained from the NewObjectRoot method on the STKEngineApplication object.

Starting STK Engine

[Python - STK API]
# Start new instance of STK Engine using the new API
from agi.stk12.stkengine import STKEngine
from agi.stk12.stkobjects import *
stk = STKEngine.StartApplication(noGraphics=False) # optionally, noGraphics = True

# Get the IAgStkObjectRoot interface
root = stk.NewObjectRoot()

Finishing your work with STK Engine

STKEngineApplication provides a ShutDown method that is the recommended way to terminate the connection to STK and free up resources. After calling ShutDown, it is no longer valid to start a new engine application in the current process.

[Python - STK API]
# Get reference to running STK instance using the new API
from agi.stk12.stkengine import STKEngine
from agi.stk12.stkobjects import *
stk = STKEngine.StartApplication()

# Do work...
stk.ShutDown()

Advanced Topic: STK Engine Timer Loop

Timer loops are an advanced topic that most API users can ignore. Some features in STK rely on a timer loop to function properly, for example updating graphics windows in a globe control, flushing the log file messages, or establishing a Connect socket to STK Engine. There are different ways of establishing a timer loop in a Python main thread, and these ways have different trade-offs that may affect your application.

On Windows, currently the only way to activate a timer loop is to use the loops implicitly available in the interactive Python interpreter or in the Tkinter mainloop; one of these will need to be running to establish a Connect socket, for example.

On Linux, when graphics are active, it is assumed that globe or map controls will be used and so, the timer loop defaults to using the Tkinter mainloop, which will be running when using the tkinter-based controls. In no-graphics mode, signal-based timer loops are available. By default, STKEngine will use a timer loop that uses the SIGALRM signal. If this creates a conflict with your application, there is also an option to specify a SIGRT signal number to use. Contact support to learn more.

If directed by AGI Tech Support, timer operations on Linux may be overridden using the environment variable STK_PYTHONAPI_TIMERTYPE, by setting it to a numeric value relating to the enum agi.stk12.stkengine.STKEngineTimerType. The default value is SigAlarm (4) in no-graphics mode and TkinterMainloop (2) in graphics mode. InteractivePython (3) may be used in the interactive interpreter and will not use any signals nor require the tkinter mainloop. SigRt (5) is used to specify a different signal than SIGALRM; the default is SIGRTMIN and this may be changed to SIGRTMIN+X, where X is specified using a second environment variable STK_PYTHONAPI_TIMERTYPE5_SIGRTMIN_OFFSET=X. If SIGRTMIN+X > SIGRTMAX, an exception will be raised.

Tkinter Globe, Map and Gfx Analysis controls

This section shows how to use the API with the Tkinter GlobeControl, MapControl and GfxAnalysisControl classes. Refer to the STK X controls topic for a description of the controls. Refer to the Custom Application Samples table for a list of Python code samples demonstrating the use of the STK Python controls.

Create a Tkinter window with a globe control

[Python - STK API]
from tkinter import Tk, BOTH, LEFT
from agi.stk12.stkengine import *
from agi.stk12.stkengine.tkcontrols import GlobeControl, MapControl

stk = STKEngine.StartApplication(noGraphics=False)
root = stk.NewObjectRoot()
root.NewScenario("Example_Scenario")

window = Tk()

# Create the globe control and add it to the Tkinter window
globeControl = GlobeControl(window, width=640, height=400)
globeControl.pack(fill=BOTH, side=LEFT)

# Create the map control and add it to the Tkinter window
mapControl = MapControl(window, width=640, height=400)
mapControl.pack(fill=BOTH, side=LEFT)

window.mainloop()

root.CloseScenario()
stk.ShutDown()

Data Types

This section describes the more complex data types used with the STK Python API beyond the basic Python data types such as float, int, str, and bool.

Type Hints

Most argument and return types are specified using type hints with Python's typing library. In the case that more than one type is possible (such as an argument that may be a string or a float), typing.Any is used as the type hint. In those situations, consulting the documentation for that method is advised. Type hints that are STK interfaces may represent objects that are subclasses of that interface.

Enumerations

Enumeration classes are located in the STK Object Model modules (e.g. agi.stk12.stkobjects). Most inherit from Python's enum.IntEnum class while a few inherit from enum.IntFlag and may be combined using the | operator to select multiple options from within the enumeration.

[Python - STK API]
from agi.stk12.stkobjects import AgESTKObjectType
fac = ObjectRoot.CurrentScenario.Children.New(AgESTKObjectType.eFacility, "fac1")

from agi.stk12.graphics import AgEStkGraphicsCylinderFill

#AgEStkGraphicsCylinderFill inherits from IntFlag and may be combined
cyl_fill = AgEStkGraphicsCylinderFill.eStkGraphicsCylinderFillBottomCap | AgEStkGraphicsCylinderFill.eStkGraphicsCylinderFillTopCap

Arrays

Many methods in the STK API take as input or return arrays. In the Python API, array values are represented using the list class.

[Python - STK API]
from agi.stk12.stkdesktop import STKDesktop
from agi.stk12.stkutil import AgEExecMultiCmdResultAction
stk = STKDesktop.StartApplication()

connect_commands = ['GetStkVersion /', 'New / Scenario ExampleScenario'] #use a list of strings
command_results = stk.ExecuteMultipleCommands(commands, AgEExecMultiCmdResultAction.eContinueOnError)

STK Interfaces and Classes

The STK object model is comprised of programming interfaces that are implemented by Python classes located in the provided modules. With few exceptions, classes returned from API methods begin with "Ag" and will inherit from one or more interfaces (beginning with "IAg"). You may immediately access any method from the inherited interfaces without casting, although in some situations casting may help with your IDE auto-complete feature (see Refactoring comtypes QueryInterface calls for more information). These classes have a reference to an STK object; this reference will be removed upon calling del() on the Python class. Because these classes are references to STK objects, creating them directly from Python will not be successful; objects must be returned from STK API methods.

[Python - STK API]
from agi.stk12.stkobjects import AgFacility, AgESTKObjectType

try:
# this facility is not a valid STK reference
my_facility_attempt = AgFacility()
my_facility_attempt.HeightAboveGround = 123.4
except STKRuntimeError as e:
print(e)

# this facility represents a valid STK object
my_facility = AgFacility(ObjectRoot.CurrentScenario.Children.New(AgESTKObjectType.eFacility, "fac1"))
my_facility.HeightAboveGround = 123.4

Collections

Many of the interfaces in the STK API represent collections of items; such interfaces have the word "Collection" as part of their name. These classes have an "Item()" method that may be used to get an indexed item from the collection, but they also support Python indexing and iteration.

[Python - STK API]
from agi.stk12.stkdesktop import STKDesktop
from agi.stk12.stkutil import AgEExecMultiCmdResultAction
stk = STKDesktop.StartApplication()

connect_commands = ['GetStkVersion /', 'New / Scenario ExampleScenario']
command_results = stk.Root.ExecuteMultipleCommands(connect_commands, AgEExecMultiCmdResultAction.eContinueOnError)

first_message = command_results.Item(0)
also_first_message = command_results[0]
for message in command_results:
print(message.Count)

Multiple Return Values

Some methods in the API return multiple values rather than returning one list. The multiple values are returned as a tuple.

[Python - STK API]
(x, y, z) = my_facility.Position.QueryCartesian()

Colors

The agi.stk12.utilities.colors module contains the Color, ColorRGBA, and Colors classes used by the STK Python API. The Color class represents an opaque color constructed from RGB values in the range [0, 255]. ColorRGBA represents a variably-translucent, 4-channel color constructed from RGBA values in the range [0, 255]. ColorRGBA may not be used in methods expecting a 3-channel color. Colors contains an assortment of named colors as well as factory methods to create Color or ColorRGBA objects from RGB(A) values.

[Python - STK API]
from agi.stk12.utilities.colors import Color, Colors
fac = ObjectRoot.CurrentScenario.Children.New(AgESTKObjectType.eFacility, "fac1")

fac.Graphics.Color = Colors.Blue
fac.Graphics.Color = Color.FromRGB(127, 255, 212)
(r, g, b) = fac.Graphics.Color.GetRGB()

Certain methods require a list of 4-channel RGBA color values for defining per-vertex colors on a geometry. Such a list should be constructed in Python as a list of Color and/or ColorRGBA objects. Color objects always have alpha=255 (fully opaque), whereas alpha may be specified when using the ColorRGBA class. An example of these usages is provided below.

[Python - STK API]
from agi.stk12.stkdesktop import STKDesktop
from agi.stk12.utilities.colors import Color, Colors, ColorRGBA

stk = STKDesktop.StartApplication(visible=True, userControl = False)
root = stk.Root
root.NewScenario('test')
manager = root.CurrentScenario.SceneManager
point = manager.Initializers.PointBatchPrimitive.Initialize()
lla_pts = [ 39.88, -75.25, 0,
38.85, -77.04, 0,
37.37, -121.92, 0]
colors = [ Colors.Red,
ColorRGBA(Colors.Blue, 127),
Colors.FromRGBA(0, 255, 0, 127)]
point.SetCartographicWithColors('Earth', lla_pts, colors)

Exceptions

The table below describes the exceptions that are provided by the agi.stk12.utilities.exceptions module with the STK Python API.

ExceptionDescription

STKInitializationError

Raised in STKDesktop and STKEngine when unable to initialize or attach to STK.

STKInvalidCastError

Raised when attempting to cast an object to an unsupported interface or class type.

STKRuntimeError

Raised when an STK method call fails.

STKAttributeError

Raised when attempting to set an unrecognized attribute within the STK API.

Make sure the spelling and capitalization is correct.

Events

Support for events has been added in STK 12.2.0. Events can be accessed directly in applicable parent objects, as seen in the table below.

Event InterfaceParent Object

IAgStkObjectRootEvents

IAgStkObjectRoot

IAgSTKXApplicationEvents

agi.stk12.stkengine.STKEngineApplication

IAgUiAxVOCntrlEvents

agi.stk12.stkengine.tkcontrols.GlobeControl

IAgUiAx2DCntrlEvents

agi.stk12.stkengine.tkcontrols.MapControl

IAgStkGraphicsSceneEvents

IAgStkGraphicsScene

IAgStkGraphicsKmlGraphicsEvents

IAgStkGraphicsKmlGraphics

IAgStkGraphicsImageCollectionEvents

IAgStkGraphicsImageCollection

IAgStkGraphicsTerrainCollectionEvents

IAgStkGraphicsTerrainCollection

Events are accessed through the Subscribe() method on the parent object, which returns an event handler subscribed to events on the queried object. Event callbacks can be added or removed in the event handler using the "+=" and "-=" operators (these operators will change the callbacks that will get executed by the event but will not affect whether the handler remains subscribed). The event handler should be unsubscribed using the Unsubscribe() method when event handling is no longer needed. Refer to the below example for using IAgStkObjectRootEvents.

[Python - STK API]
from agi.stk12.stkengine import STKEngine
											
def onScenarioNewCallback(Path:str):
    print(f'Scenario {Path} has been created.')
											
stk = STKEngine.StartApplication()
root = stk.NewObjectRoot()
stkObjectRootEvents = root.Subscribe()
stkObjectRootEvents.OnScenarioNew += onScenarioNewCallback
root.NewScenario('ExampleScenario')
# callback should be executed now

# remove the callback from the handler
stkObjectRootEvents.OnScenarioNew -= onScenarioNewCallback

# all finished with events, unsubscribe
stkObjectRootEvents.Unsubscribe()
                                        

The STK Desktop application user interface might become unresponsive to user input when Python has event subscribers, and STK tries to call back into the Python interpreter to notify of an event. That callback relies on the Windows message loop to be dispatched. To work around this issue, Windows messages need to be dispatched through the Windows message queue. This can be accomplished in different ways depending on the type of Python script that is executing (console or user interface), and on the type of user interface library being used. For instance, if the tkinter user interface library is used, a simple way of accomplishing this with this library is to create a tkinter window while using the desktop application user interface. No action is needed if Python is used only for automation. The following script is an example showing this issue.

[Python - STK API]
from agi.stk12.stkdesktop import STKDesktop
from agi.stk12.stkobjects import AgESTKObjectType
											
def onStkObjectAddedCallback(Path:str):
    print(f'{Path} has been added.')
stk = STKDesktop.StartApplication(visible=True)
root = stk.Root
root.NewScenario('ExampleScenario')
stkObjectRootEvents = root.Subscribe()
stkObjectRootEvents.OnStkObjectAdded += onStkObjectAddedCallback
sc = root.CurrentScenario
											
#onStkObjectAddedCallback will be successfully called when the next line is executed
fac = sc.Children.New(AgESTKObjectType.eFacility, 'AGIHQ')
											
#Now switch control to the desktop application and create another facility.
#The user interface will become unresponsive.
											
#Now open a tkinter window that processing COM messages.
from tkinter import Tk
window = Tk()
window.mainloop()
#Switch control to the desktop application and create another facility.
#The user interface will be responsive and the event callback will be successful.
                                        

STK's Built-in Python Plugins

Starting in version 12.4, STK has multi-platform Python plugins available for some plugin points. These plugin points can be utilized by supplying STK with a Python script implementing the plugin interface. For more information about configuring Python plugins, visit the Python plugin documentation.

API Modules

Most plugins utilize interfaces in the STK API for getting data from and sending data to STK. Interfaces specific to plugins have been added to agi.stk12.plugins. Using the STK object model within a plugin is possible by obtaining the object root in the Init method of the plugin using IAgStkPluginSite.StkObjectRoot.

File structure

The following example Calc Scalar plugin is used to highlight the structure of a Python plugin using the STK Python API. Note that while the file may have any name, the plugin class name is a requirement (e.g. CAgCrdnCalcScalarPythonPlugin). All methods defined in the plugin interface (e.g. IAgCrdnCalcScalarPythonPlugin) must be defined in the class.

[Python - STK API]
import typing
from agi.stk12.plugins.crdnplugin       import IAgCrdnCalcScalarPluginResultReg, IAgCrdnCalcScalarPluginResultReset, IAgCrdnCalcScalarPluginResultEval
from agi.stk12.plugins.utplugin         import IAgUtPluginConfig, AgEUtLogMsgType
from agi.stk12.plugins.attrautomation   import AgEAttrAddFlags
from agi.stk12.plugins.stkplugin        import AgStkPluginSite

# The class name may not be changed
class CAgCrdnCalcScalarPlugin(object):
    def __init__(self):
        self.scope = None
        self.site = None
        self.root = None
        self.ObjectTrajectoryCatesianX = None
        
        #plugin configuration properties - must be configured in GetPluginConfig for STK to use them
        self.scale_factor = 1.23

    # Define all methods in IAgCrdnCalcScalarPlugin
    def Init(self, site:"IAgUtPluginSite") -> bool:
        self.site = AgStkPluginSite(site)
        self.root = self.site.StkRootObject # Gain access to STK Object Model for use within the plugin script
        self.site.Message(AgEUtLogMsgType.eUtLogMsgInfo, f'{self.display_name} has been initialized by {self.site.SiteName}.')
        return True

    def Register(self, result:"IAgCrdnCalcScalarPluginResultReg") -> None:
        objPath = result.ObjectPath
        result.ShortDescription = "Component created on " + objPath

    def Reset(self, result:"IAgCrdnCalcScalarPluginResultReset") -> bool:
        #<MyObject>, <MySelf>, <MyParent>, <MyGrandParent> are valid keywords for sourceName
        self.ObjectTrajectoryCatesianX = result.CalcToolProvider.GetCalcScalar("Trajectory(CBF).Cartesian.X", "<MyObject>")
        return True

    def Evaluate(self, result:"IAgCrdnCalcScalarPluginResultEval") -> bool:
        if self.ObjectTrajectoryCatesianX is not None:
            (x, errFlag_x) = self.ObjectTrajectoryCatesianX.CurrentValue_Array(result)
            if errFlag_x is not None and errFlag_x!=0:
                result.SetValue(x*self.scale_factor)
                return True
        return False

    def Free(self) -> None:
        self.scope = None
        self.site = None
        self.root = None
        self.ObjectTrajectoryCatesianX = None
        
    def GetPluginConfig(self, pAttrBuilder:"IAgAttrBuilder") -> typing.Any:
        ''' Defining GetPluginConfig is only necessary if adding configuration properties accessible to STK '''
        if self.scope is None:
            self.scope = pAttrBuilder.NewScope()
            pAttrBuilder.AddDoubleDispatchProperty( self.scope, "ScaleFactor", "A double used to scale the plugin evaluation result", "scale_factor", AgEAttrAddFlags.eAddFlagNone )
        return self.scope
        
    def VerifyPluginConfig(self, pPluginCfgResult:"IAgUtPluginConfigVerifyResult") -> None:
        pass
                                        

Configuration

The above example specified a user configuration property - "ScaleFactor" - which will be accessible from STK. If multiple instances of the above Calc Scalar plugin are instantiated, each instance will have its own unique value for the configuration property. It is recommended that any name used for these configuration properties not include spaces because certain interfaces to the properties may not work correctly.

Adding Properties for Python Plugins

If a plugin interface defines a property (see IAgAccessConstraintPlugin for an example), the property must also be defined in the class. There are two ways the STK Python API supports the user in doing so.

The first way is to define the property as a member of the plugin class. In the example below, the property from the link above is seen being defined. Note that the name of the member matches the name of the property from the link as this is necessary for the STK Python API to retrieve its value.

[Properties - Example 1]
class CAgAccessConstraintPlugin(object):
    def __init__(self):
        self.DisplayName = 'PythonRangeExample'
                                        

The second way to define the property is using the @property decorator on a method with the property name. The return type must match the type defined by the property.

[Properties - Example 2]
class CAgAccessConstraintPlugin(object):

    @property
    def DisplayName(self) -> str:    
        return 'PythonRangeExample'
                                        

For the full implemented example of the property being defined for the IAgAccessConstraintPlugin interface, see the Code Samples folder.