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
You can use the Python help function 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 following 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.plugins.asplugin |
|
agi.stk12.plugins.searchplugin |
|
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:
Argument | Description |
---|---|
set visible=True | Start STK in visible mode |
set userControl=True | Keeps STK open after finishing a Python script |
grpc_server (bool, default=False) | Specify True to start STK on the current machine with the gRPC server active and connect to it using gRPC |
grpc_host (string, default = "0.0.0.0") | A valid DNS host name for the STK gRPC server |
grpc_port (init, default=40704) | A valid TCP port for the STK gRPC server |
[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 additional arguments to specify the Process ID (pid) if more than one STK application is running:
Argument | Description |
---|---|
pid (int, default = None) | The process ID for the STK Desktop instance to attach to. Not applicable if gRPC is used. |
grpc_server (bool, default = False) | Specify True to attach to a running STK gRPC server. |
grpc_host (string, default = "localhost") | A valid DNS host name for the STK gRPC server. "localhost" connects to the local server. |
grpc_port (init, default = 40704) | A valid TCP port for the STK gRPC server. |
[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 two or more threads.
As this is an advanced feature, and only experienced users should implement it, and then only when necessary.
When 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 two or more threads.
[Python - STK API] | ||
---|---|---|
|
STKRuntime
STKRuntime is an executable that serves STK Engine functionality vai gRPC. Use agi.stk12.stkruntime to start or attach to a running STKRuntime application. Once the STKRuntimeAPplication object is obtained, interact with STK, via IAgStkObjectRoot obtained from calling STKRuntimeApplication.NewObjectRoot(). Shutting down the remote STKRuntime process is possible by calling STKRuntimeApplication.ShutDown(), or using the userControl=False option when starting the application.
Starting a new STKRuntime instance
STKRuntime may be started on the local machine using STKRuntime.StartApplication(). While STKRuntime offers STK Engine functionality similar to the STKEngine module, there are a few key differences.
- STKEngine runs STK in-process with Python, whereas STKRuntime is out-of-process using gRPC to communicate.
- STKRuntime does not offer visualizations at this time.
Options | Description |
---|---|
grpc_host (string, default = "0.0.0.0") | A valid DNS host name for the STKRuntime gRPC server. |
grpc_port (int, default = 40704) | A valid TCP port for the STKRuntime gRPC server. |
userControl (bool, default = False) | Specify True to leave the STKRuntime application running (in the user's control) after Python exits. |
noGraphics (bool, default = True) | Disables graphics calculations within the STKRuntime application to improve performance and remove dependencies on graphics libraries. |
[STKRuntime Python - API] | ||
---|---|---|
|
Attaching to a running STKRuntime instance
To attach to a running STKRuntime application via gRPC, you can use STKRuntime.AttachToApplication(). To shut down the STK Runtime application, STKRuntimeApplication.ShutDown() must be called.
Option | Description |
---|---|
grpc_host (string, default = "localhost") | A valid DNS host name for the STKRuntime gRPC server. |
grpc_port (int, default = 40704) | A valid TCP port for the STKRuntime gRPC server. |
[STKRuntime Python - 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 AGI has not implemented some features, such as events. 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, 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 AGI support to learn more.
If directed by AGI Tech Support, you may override timer operations on Linux 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. You may use InteractivePython (3) in the interactive interpreter, and it will not use any signals nor require the tkinter mainloop. Use SigRt (5) to specify a different signal than SIGALRM. The default is SIGRTMIN, and you may change this to SIGRTMIN+X, where X is specified using a second environment variable STK_PYTHONAPI_TIMERTYPE5_SIGRTMIN_OFFSET=X. If SIGRTMIN+X > SIGRTMAX, you will get an exception.
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
[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] | ||
---|---|---|
|
Data Types for Data Analysis
This section describes data types you can use in the STK Python API for data analysis. These data types are standard data types used in popular Python data science and scientific computing libraries. These data types are available starting in the STK 12.6+.
NumPy arrays
You can convert a dataset collection in row format to a NumPy array. NumPy arrays are N-dimensional arrays with support for fast vector operations, indexing, and broadcasting. NumPy also offers a broad collection of standard mathematical functions used in scientific computing. The NumPy array is a widely supported data structure, in popular Python scientific computing and machine learning libraries.
The ToNumpyArray() method, called on IAgDrDataSetCollection, returns a data provider’s results dataset collection as a 2D NumPy array. This array has a shape equal to the total number of rows in the dataset collection and the total number of unique columns fields in the dataset collection. For example, if the computed All Region By Pass data provider results dataset collection contains 100 rows and 11 column fields, the ToNumpyArray() method would return a NumPy array of the entire result set and would have a shape of (100, 11), where 100 is the number of rows and 11 is the number of columns.
To use this functionality, you must have NumPy installed in your local Python development environment.
Here is an example of using NumPy arrays for flight profile data.
[Python - STK API] | ||
---|---|---|
|
The resulting flight data plot then looks like this:
For more information, see NumPy.
Pandas DataFrame
You can convert a dataset collection in row format as a Pandas DataFrame. DataFrames are the key to Pandas’ fast and efficient data manipulation and analysis functionality. They are a two-dimensional, tabular data structure with labeled indexing for rows and columns, where the columns can contain data of various data types. DataFrames supports powerful aggregation and transformation functionality, time series functionality, merging and joining operations of datasets, hierarchical indexing, vectorized operations, flexible reshaping functionality, and much more.
The ToPandasDataFrame() method called on IAgDrDataSetCollection, returns a data provider’s results dataset collection as Pandas DataFrame. The DataFrame row index length, equal to the total number of rows in the dataset collection and each column in the DataFrame, maps to a unique field name in the dataset collection. For example, if the computed Flight Profile by Time data provider results dataset collection contains 6000 rows and 100 fields column fields, the returned DataFrame will have a row index length of 6000 and 100 columns.
To use this functionality, you must have Pandas installed in your local Python development environment.
Here are four examples of using Pandas DataFrame.
Example 1: Convert All Regions By Pass data provider results to a Pandas DataFrame with a default numeric row index. The Python implementation would look like this:
[Python - STK API] | ||
---|---|---|
|
The ToPandasDataFrame() method supports setting a single column as the index. To create a hierarchical index or a composite index comprised of more than a single column, get your data provider’s results dataset collection as a Pandas DataFrame with the default numeric index, then update the index accordingly.
[Python - STK API] | ||
---|---|---|
|
Example 2: Compute descriptive statistics access measurements. The implementation in Python would be:
[Python - STK API] | ||
---|---|---|
|
This produces the following data table:
Example 3: Compute descriptive statistics access measurements grouped by Asset Name (Satellite Names). The Python implementation would be as follows:
[Python - STK API] | ||
---|---|---|
|
This produces the following data table:
Example 4: Plot a heat map of Duration By Asset (Satellite) for each access region. The Python implementation would be:
[Python - STK API] | ||
---|---|---|
|
This produces the following data map:
See Pandas for more information, including library documentation.
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 was 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. You can add or remove Event callbacks 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 following 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 you use the tkinter user interface library, 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. You can use these plugin points d 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. 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 called "ScaleFactor" that will be accessible from STK. If two or more instances of the above Calc Scalar plugin are instantiated, each instance will have its own unique value for the configuration property. AGI recommends 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. 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.
Hidden parameters for the Object Model
Parameter | Description |
---|---|
root | The STK Object Model root / starting point for the API. The usual way of getting the Object Model root via a Python script doesn't work here since you need the running root context. The parameter to use versionString = root.ExecuteCommand('GetStkVersion /') |
abortMCS | boolean, initial value is False. "Output value" i.e. STK reads this after the script executes. Set to true and the MCS sequence stops. |
iteration | integer number of the sequence iteration. "input only" i.e. STK doesn't read this back. e.g. if integer > 100: abortMCS=True |
gRPC Specific Features
The methods SetGrpcOptions
and NewGrpcCallBatcher
were added to STK Application interfaces: agi.stk12.stkruntime.STKRuntimeApplication
, agi.stk12.stkdesktop.STKDesktopApplication
, agi.stk12.stkengine.STKEngineApplication
. While gRPC is not available for use with STK Engine, the methods are provided for parity with the other two application interfaces.
gRPC Keyword Options
Keyword options are passed to the method SetGrpcOptions
in the form of a dictionary of keyword value pairs. The available options are:
Keyword | Value Type | Default | Description |
---|---|---|---|
release batch size | int | 12 | Release batching is a form of garbage-collection added to reduce the communication over the gRPC server. The destruction of any STK Object Model interface object results in a 'release' call. Batching these calls together for a certain number of object results in reduced communications to the server. Setting the value to one (1) disables this feature. |
collection iteration batch size | int | 100 | When iterating a collection using the syntax 'for object in collection:...', the values are requested in batches rather than as each iteration occurs to reduce the communication over the gRPC server. Setting the value to one (1) disables batching for collection iteration. |
disable batching | bool | False | Disables batching of all agi.stk12.utilities.grpcutilities.GrpcCallBatcher objects. Setting this value may be useful for debugging since call-batching results in asynchronous error messages. |
raise exceptions with STK Engine | bool | True | By default, calling agi.stk12.stkengine.STKEngineApplication.SetGrpcOptions or agi.stk12.stkengine.STKEngineApplication.NewGrpcCallBatcher raises an exception because these operations are not active with STK Engine. This option suppresses those exceptions. |
gRPC Call Batcher
Calling the application method NewGrpcCallBatcher
returns an object of type agi.stk12.utilities.grpcutilities.GrpcCallBatcher
. This feature is provided as an option to reduce the communication over the gRPC server in performance-critical applications. API calls may be batched together and sent to STK in one remote procedure call if no return value is needed from the calls.
Activating batching causes the normal API exception behavior to be altered. Exceptions from one command may appear asyncronously. Therefore, it is not recommended to use call batching while building and debugging, but rather as a performance optimization.
Only calls that do not return a value may be batched together, such as set-property requests and methods without a return value. Any method that has a return value (including get-property requests) automatically execute any previously batched commands before the method with a return value is executed.
Therefore, to reduce the number of remote API requests and improve performance, code must be organized to group together commands that do not have a return value. Call chaining interrupts a batch request because of the get-property command within the chain. e.g.:
[Python - STK API] | ||
---|---|---|
|
The above example won't be batched together because the call to CurrentScenario
gets the scenario via an API call. These commands may be batched by factoring out the call chaining. e.g.:
[Python - STK API] | ||
---|---|---|
|
This class may be used via the explicit commands or by using the with
statement to batch together the commands within the statement block. e.g.:
[Python - STK API] | ||
---|---|---|
|
gRPC Futures
gRPC Futures are included to expand the use cases of the gRPC Call Batcher and further reduce communication over the gRPC server in performance-critical applications. gRPC Futures are created in place of an API method call that returns some STK API interface. However, unless the method call, creating the future does not force execution of the call batch. Only when a return value is requested from the future does the future "bind" and force execution of the call batch. Futures are created with agi.stk12.utilities.grpcutilities.GrpcCallBatcher.create_future
.
To create a future, the method object, return type, and the method arguments are needed. The following example creates 100 facilities and adds them to a constellation, without causing the GrpcCallBatcher
to execute. All of the operations are sent to STK to be executed at the end of the snippet.
[Python - STK API] | ||
---|---|---|
|