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":
|
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')
|
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
|
This produces the following output:
Help on AgScenario in module agi.stk12.stkobjects object:
|
Module Mapping
The below table provides the corresponding library for each Python module.
library | Module |
---|---|
agi.stk12.graphics |
|
agi.stk12.plugins.accessconstraintplugin |
|
agi.stk12.plugins.attrautomation |
|
agi.stk12.plugins.commrdrfoundation |
|
agi.stk12.plugins.crdnplugin |
|
agi.stk12.plugins.gatorplugin |
|
agi.stk12.plugins.hpopplugin |
|
agi.stk12.plugins.propagator |
|
agi.stk12.plugins.stkplugin |
|
agi.stk12.plugins.stkradarplugin |
|
agi.stk12.plugins.utplugin |
|
agi.stk12.stkobjects |
|
agi.stk12.stkobjects.aviator |
|
agi.stk12.stkobjects.aviator.matlab |
|
agi.stk12.stkutil |
|
agi.stk12.stkx |
|
agi.stk12.uiapplication |
|
agi.stk12.uicore |
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
Exceptions
The table below describes the exceptions that are provided by the agi.stk12.utilities.exceptions module with the STK Python API.
Exception | Description |
---|---|
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 Interface | Parent Object |
---|---|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
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] | ||
---|---|---|
|
For the full implemented example of the property being defined for the IAgAccessConstraintPlugin interface, see the Code Samples folder.