pntos-api 2.1.0.post0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pntos/__init__.py +3 -0
- pntos/api/__init__.py +79 -0
- pntos/api/plugins/__init__.py +1 -0
- pntos/api/plugins/common.py +1046 -0
- pntos/api/plugins/controller.py +99 -0
- pntos/api/plugins/fusion.py +572 -0
- pntos/api/plugins/fusion_strategy.py +306 -0
- pntos/api/plugins/inertial.py +414 -0
- pntos/api/plugins/initialization.py +278 -0
- pntos/api/plugins/logging.py +68 -0
- pntos/api/plugins/orchestration.py +253 -0
- pntos/api/plugins/platform_integration.py +81 -0
- pntos/api/plugins/preprocessor.py +88 -0
- pntos/api/plugins/registry.py +46 -0
- pntos/api/plugins/state_modeling.py +581 -0
- pntos/api/plugins/transport.py +50 -0
- pntos/api/plugins/ui.py +43 -0
- pntos/api/plugins/utility.py +17 -0
- pntos/py.typed +0 -0
- pntos_api-2.1.0.post0.dev0.dist-info/METADATA +21 -0
- pntos_api-2.1.0.post0.dev0.dist-info/RECORD +24 -0
- pntos_api-2.1.0.post0.dev0.dist-info/WHEEL +5 -0
- pntos_api-2.1.0.post0.dev0.dist-info/licenses/LICENSE +177 -0
- pntos_api-2.1.0.post0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Python API of pntOS."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from .common import CommonPlugin, LoggingLevel
|
|
6
|
+
from .controller import ControllerPlugin
|
|
7
|
+
from .fusion import FusionPlugin
|
|
8
|
+
from .fusion_strategy import FusionStrategyPlugin
|
|
9
|
+
from .inertial import InertialPlugin
|
|
10
|
+
from .initialization import InitializationPlugin
|
|
11
|
+
from .orchestration import OrchestrationPlugin
|
|
12
|
+
from .platform_integration import PlatformIntegrationPlugin
|
|
13
|
+
from .preprocessor import PreprocessorPlugin
|
|
14
|
+
from .registry import RegistryPlugin
|
|
15
|
+
from .state_modeling import StateModelingPlugin
|
|
16
|
+
from .transport import TransportPlugin
|
|
17
|
+
from .ui import UiPlugin
|
|
18
|
+
from .utility import UtilityPlugin
|
|
19
|
+
|
|
20
|
+
PluginType = (
|
|
21
|
+
type[ControllerPlugin]
|
|
22
|
+
| type[FusionPlugin]
|
|
23
|
+
| type[FusionStrategyPlugin]
|
|
24
|
+
| type[InertialPlugin]
|
|
25
|
+
| type[InitializationPlugin]
|
|
26
|
+
| type['LoggingPlugin']
|
|
27
|
+
| type[OrchestrationPlugin]
|
|
28
|
+
| type[PlatformIntegrationPlugin]
|
|
29
|
+
| type[PreprocessorPlugin]
|
|
30
|
+
| type[RegistryPlugin]
|
|
31
|
+
| type[StateModelingPlugin]
|
|
32
|
+
| type[TransportPlugin]
|
|
33
|
+
| type[UiPlugin]
|
|
34
|
+
| type[UtilityPlugin]
|
|
35
|
+
)
|
|
36
|
+
"""
|
|
37
|
+
An union of all the types of plugins.
|
|
38
|
+
|
|
39
|
+
Can be used by the logging plugin to print which plugin the message originated from.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class LoggingPlugin(CommonPlugin, ABC):
|
|
44
|
+
"""
|
|
45
|
+
Logging plugin.
|
|
46
|
+
|
|
47
|
+
A plugin for logging out data to an arbitrary sink (e.g. console, file,
|
|
48
|
+
network, etc.).
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def log(
|
|
53
|
+
self,
|
|
54
|
+
source_plugin_type: PluginType,
|
|
55
|
+
source_plugin_identifier: str,
|
|
56
|
+
level: LoggingLevel,
|
|
57
|
+
message: str,
|
|
58
|
+
) -> None:
|
|
59
|
+
"""
|
|
60
|
+
Log a string to the logging plugin's sink.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
source_plugin_type (PluginType): Information on the plugin that sent the logout.
|
|
64
|
+
source_plugin_identifier (str): Information on the plugin that sent the logout.
|
|
65
|
+
level (LoggingLevel): The event severity.
|
|
66
|
+
message (str): The string contents to be logged.
|
|
67
|
+
"""
|
|
68
|
+
pass
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"""Python API of pntOS."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from aspn23 import AspnBase, TypeTimestamp
|
|
6
|
+
|
|
7
|
+
from pntos.api import CommonPlugin, Message
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MessageStreamConfig(ABC):
|
|
11
|
+
"""
|
|
12
|
+
Message stream configuration.
|
|
13
|
+
|
|
14
|
+
This class configures the buffering, delay, and sorting characteristics of
|
|
15
|
+
messages that are streamed into the :class:`pntos.api.OrchestrationPlugin`. The pntOS system
|
|
16
|
+
will deliver messages to the orchestration plugin as it receives them.
|
|
17
|
+
However, there is a fundamental tradeoff between latency and those messages
|
|
18
|
+
being in-order. In particular, to guarantee that messages are sorted by
|
|
19
|
+
timestamp, it is necessary to build a buffer and delay delivery, such that
|
|
20
|
+
a sorting function may be applied. This structure allows the plugin to
|
|
21
|
+
choose which messages are buffered and which are not.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def sequenced_stream_add(
|
|
26
|
+
self, message_type: type[AspnBase], source_identifier: str | None = None
|
|
27
|
+
) -> None:
|
|
28
|
+
"""
|
|
29
|
+
Request messages are streamed in sorted timestamp ordering.
|
|
30
|
+
|
|
31
|
+
Request messages of the given ``message_type`` and optional ``source_identifier`` are
|
|
32
|
+
streamed in sorted timestamp ordering.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
message_type (type[AspnBase])
|
|
36
|
+
source_identifier (str | None, optional)
|
|
37
|
+
"""
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
def sequenced_stream_remove(
|
|
42
|
+
self, message_type: type[AspnBase], source_identifier: str | None = None
|
|
43
|
+
) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Request messages are no longer streamed in sorted timestamp ordering.
|
|
46
|
+
|
|
47
|
+
Request messages of the given ``message_type`` and optional ``source_identifier`` are no
|
|
48
|
+
longer streamed in sorted timestamp ordering. This will remove a type that was previously
|
|
49
|
+
added in a call to :meth:`sequenced_stream_add`, or remove individual messages from the
|
|
50
|
+
entire list of messages that was added with a previous call to :meth:`sequenced_stream_all`.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
message_type (type[AspnBase])
|
|
54
|
+
source_identifier (str | None, optional)
|
|
55
|
+
"""
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
@abstractmethod
|
|
59
|
+
def sequenced_stream_all(self, enable: bool) -> None:
|
|
60
|
+
"""
|
|
61
|
+
Request all messages are streamed in sorted timestamp ordering.
|
|
62
|
+
|
|
63
|
+
Note that the ability to do this reliably will depend on the length of the buffer used by
|
|
64
|
+
the :class:`pntos.api.Mediator`.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
enable (bool)
|
|
68
|
+
"""
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
@abstractmethod
|
|
72
|
+
def immediate_stream_add(
|
|
73
|
+
self, message_type: type[AspnBase], source_identifier: str | None = None
|
|
74
|
+
) -> None:
|
|
75
|
+
"""
|
|
76
|
+
Request messages are streamed immediately.
|
|
77
|
+
|
|
78
|
+
Request messages of the given ``message_type`` and optional ``source_identifier`` are
|
|
79
|
+
streamed immediately without delay, buffering, or sorting.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
message_type (type[AspnBase])
|
|
83
|
+
source_identifier (str | None, optional)
|
|
84
|
+
"""
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
@abstractmethod
|
|
88
|
+
def immediate_stream_remove(
|
|
89
|
+
self, message_type: type[AspnBase], source_identifier: str | None = None
|
|
90
|
+
) -> None:
|
|
91
|
+
"""
|
|
92
|
+
Request messages are no longer streamed immediately.
|
|
93
|
+
|
|
94
|
+
Request messages of the given ``message_type`` and optional ``source_identifier`` are no
|
|
95
|
+
longer streamed immediately. This will remove a type that was previously added in a call to
|
|
96
|
+
:meth:`immediate_stream_add`, or remove individual messages from the entire list of messages
|
|
97
|
+
that was added with a previous call to :meth:`immediate_stream_all`.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
message_type (type[AspnBase])
|
|
101
|
+
source_identifier (str | None, optional)
|
|
102
|
+
"""
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
@abstractmethod
|
|
106
|
+
def immediate_stream_all(self, enable: bool) -> None:
|
|
107
|
+
"""
|
|
108
|
+
Request all messages are streamed immediately without delay, buffering, or sorting.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
enable (bool)
|
|
112
|
+
"""
|
|
113
|
+
pass
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class OrchestrationPlugin(CommonPlugin, ABC):
|
|
117
|
+
"""
|
|
118
|
+
Orchestration plugin.
|
|
119
|
+
|
|
120
|
+
The pntOS orchestration plugin is responsible for orchestrating one or more fusion engines,
|
|
121
|
+
state model providers and other plugins in order to perform sensor fusion. The orchestration
|
|
122
|
+
plugin is sent (sorted, buffered) ASPN messages from the :class:`pntos.api.ControllerPlugin`, and is
|
|
123
|
+
responsible for computing a solution for the system, as well as estimating any other quantities
|
|
124
|
+
of interest.
|
|
125
|
+
|
|
126
|
+
In order to achieve this task, the orchestration plugin may be passed a set of other plugins
|
|
127
|
+
during the call to :meth:`~OrchestrationPlugin.init_orchestration_plugin`. If so, the
|
|
128
|
+
orchestration plugin then, as the name suggests, configures and orchestrates these plugins to
|
|
129
|
+
work together to perform sensor fusion.
|
|
130
|
+
|
|
131
|
+
Example:
|
|
132
|
+
For example, the orchestration plugin may set up a fusion engine it received in the call to
|
|
133
|
+
:meth:`~OrchestrationPlugin.init_orchestration_plugin`, then add state blocks or measurement
|
|
134
|
+
processors to that fusion engine from a :class:`pntos.api.StateModelingPlugin` it also received, and
|
|
135
|
+
process inertial data from an :class:`pntos.api.InertialPlugin` it received. The
|
|
136
|
+
:meth:`~OrchestrationPlugin.request_solutions` function will be called by the system when
|
|
137
|
+
pntOS needs to know the current filtering solutions. Other quantities which need to be
|
|
138
|
+
estimated by the orchestration engine can be returned to the system by registry updates.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
@abstractmethod
|
|
142
|
+
def init_orchestration_plugin(
|
|
143
|
+
self, plugins: list[CommonPlugin] | None, stream_config: MessageStreamConfig
|
|
144
|
+
) -> None:
|
|
145
|
+
"""
|
|
146
|
+
Initial data structures needed by the orchestration plugin.
|
|
147
|
+
|
|
148
|
+
This function will be called by the system after the :meth:`pntos.api.CommonPlugin.init_plugin` but before
|
|
149
|
+
any other call to an :class:`pntos.api.OrchestrationPlugin` function.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
plugins (list[CommonPlugin] | None): A set of plugins which should be used by the orchestration
|
|
153
|
+
plugin. For example, the plugins list may include a :class:`pntos.api.StandardFusionEngine`,
|
|
154
|
+
which the orchestration plugin can use to perform fusion of sensor data received.
|
|
155
|
+
The list may also include a :class:`pntos.api.StateModelingPlugin`, which the orchestration
|
|
156
|
+
plugin can use to extract the algorithms needed for parsing sensor data into the
|
|
157
|
+
data model a fusion engine needs. If the orchestration plugin does not require any
|
|
158
|
+
plugins, ``None`` may be passed.
|
|
159
|
+
stream_config (MessageStreamConfig): A set of configuration options that the
|
|
160
|
+
orchestration plugin can use to indicate to the :class:`pntos.api.ControllerPlugin` how it
|
|
161
|
+
would prefer delivery of messages. When the orchestration plugin receives the
|
|
162
|
+
``stream_config`` struct, it should call the functions on it to set up how messages
|
|
163
|
+
will be delivered to it. If it does not, the order of messages' arrival will be
|
|
164
|
+
unspecified and at the discretion of the :class:`pntos.api.ControllerPlugin`.
|
|
165
|
+
"""
|
|
166
|
+
pass
|
|
167
|
+
|
|
168
|
+
@abstractmethod
|
|
169
|
+
def process_pntos_message(self, message: Message, sequenced: bool) -> None:
|
|
170
|
+
"""
|
|
171
|
+
Deliver a new message from an external to pntOS source into the orchestration plugin.
|
|
172
|
+
|
|
173
|
+
The plugin should utilize this sensor data contained in message by passing it into a fusion
|
|
174
|
+
engine.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
message (Message): The :class:`pntos.api.Message` to be delivered to the
|
|
178
|
+
:class:`pntos.api.OrchestrationPlugin` from the :class:`pntos.api.ControllerPlugin`. From here the
|
|
179
|
+
:class:`pntos.api.OrchestrationPlugin` may use it directly or route it to other plugins (like
|
|
180
|
+
the :class:`pntos.api.FusionPlugin`, :class:`pntos.api.InertialPlugin`, or
|
|
181
|
+
:class:`pntos.api.InitializationPlugin`).
|
|
182
|
+
sequenced (bool): ``False`` if ``message`` was the last received :class:`pntos.api.Message`
|
|
183
|
+
or ``True`` if it was delayed by buffering. See :class:`pntos.api.MessageStreamConfig` for
|
|
184
|
+
more details.
|
|
185
|
+
"""
|
|
186
|
+
pass
|
|
187
|
+
|
|
188
|
+
@property
|
|
189
|
+
@abstractmethod
|
|
190
|
+
def filter_description_list(self) -> list[str]:
|
|
191
|
+
"""
|
|
192
|
+
Get a list of strings describing the filters available in this :class:`pntos.api.OrchestrationPlugin`.
|
|
193
|
+
|
|
194
|
+
One of these description strings may be used when calling :meth:`request_solutions`. For
|
|
195
|
+
consistency, these strings should adhere to the following conventions:
|
|
196
|
+
|
|
197
|
+
- Strings should be upper case and have words and acronyms separated by underscores
|
|
198
|
+
(``UPPER_SNAKE_CASE``).
|
|
199
|
+
- Strings should contain the substring ``BEST`` when they represent the primary solution.
|
|
200
|
+
- Strings should contain the substring ``DEAD_RECKONING`` when they represent a solution
|
|
201
|
+
suitable for estimating relative motion or rotation over a period of time. This solution
|
|
202
|
+
may drift more than ``BEST`` solutions, as the goal is to allow a user to get an estimate
|
|
203
|
+
of the relative motion between different times. In the calculation of this solution, some
|
|
204
|
+
sensor measurement might be excluded. For example, a system with an IMU might provide a
|
|
205
|
+
``DEAD_RECKONING`` solution which is the solution from its free-running inertial
|
|
206
|
+
mechanization, with resets disabled during the time intervals between ``solution_times``
|
|
207
|
+
(but resets applied before all of the ``solution_times``).
|
|
208
|
+
- This substring should contain the string-equivalent to the corresponding ASPN message
|
|
209
|
+
class name, converted to UPPER_SNAKE_CASE, followed by the string ``_ESTIMATE``. This
|
|
210
|
+
allows the user to perform substring matching without a risk of getting a false positive
|
|
211
|
+
match from a type whose string would be a subset of another type.
|
|
212
|
+
|
|
213
|
+
Example:
|
|
214
|
+
For example, if the primary solution is an ASPN PVA then the string
|
|
215
|
+
``MY_BEST_ASPN_MEASUREMENT_POSITION_VELOCITY_ATTITUDE_ESTIMATE`` would fulfill the
|
|
216
|
+
convention.
|
|
217
|
+
|
|
218
|
+
These conventions allow the user to identify their desired type of solution using substring
|
|
219
|
+
matching.
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
list[str]: A list of strings describing the filters available in this
|
|
223
|
+
:class:`pntos.api.OrchestrationPlugin`.
|
|
224
|
+
"""
|
|
225
|
+
pass
|
|
226
|
+
|
|
227
|
+
@abstractmethod
|
|
228
|
+
def request_solutions(
|
|
229
|
+
self,
|
|
230
|
+
solution_times: list[TypeTimestamp],
|
|
231
|
+
filter_description: str | None = None,
|
|
232
|
+
) -> list[Message | None] | None:
|
|
233
|
+
"""
|
|
234
|
+
Request filtering solutions at the times specified in the array ``solution_times``.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
solution_times (list[TypeTimestamp]): The solution times.
|
|
238
|
+
filter_description (str | None, optional): An :class:`pntos.api.OrchestrationPlugin` may run
|
|
239
|
+
multiple filters. To select which filter(s) to request solutions from, enter a valid
|
|
240
|
+
filter description string in ``filter_description``. Valid filter description
|
|
241
|
+
strings can be obtained by calling :attr:`filter_description_list`. Passing in
|
|
242
|
+
``None`` will provide a result specific to a particular :class:`pntos.api.OrchestrationPlugin`
|
|
243
|
+
implementation. When ``filter_description`` is ``None``, the implementation should
|
|
244
|
+
endeavor to return its best solution.
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
list[Message | None] | None: An array of messages containing the filter solutions for the requested
|
|
248
|
+
``solution_times``. The number of solutions should equal the number of times in
|
|
249
|
+
``solution_times``, although some entries may be ``None`` if they are unavailable at the
|
|
250
|
+
corresponding time in ``solution_times``. The returned :class:`pntos.api.Message` list may be
|
|
251
|
+
``None`` if ``filter_description`` is invalid.
|
|
252
|
+
"""
|
|
253
|
+
pass
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Python API of pntOS."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from pntos.api import CommonPlugin
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PlatformIntegrationPlugin(CommonPlugin, ABC):
|
|
9
|
+
"""
|
|
10
|
+
Platform integration plugin.
|
|
11
|
+
|
|
12
|
+
A plugin for command, control, solution output, and other behavior of the
|
|
13
|
+
system which is specific to a particular platform. Works closely with the
|
|
14
|
+
:class:`pntos.api.ControllerPlugin` to fully define the overall behavior of the system.
|
|
15
|
+
|
|
16
|
+
Caution:
|
|
17
|
+
**Unstable**: This feature is unstable and is not yet considered part of the stable pntOS
|
|
18
|
+
API. Usage of this feature is highly discouraged in non-experimental code, and its
|
|
19
|
+
definition may change at any time.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
@abstractmethod
|
|
23
|
+
def take_control(
|
|
24
|
+
self,
|
|
25
|
+
plugins: list[CommonPlugin],
|
|
26
|
+
plugin_resources_locations: list[str | None] | None = None,
|
|
27
|
+
initial_config: str | None = None,
|
|
28
|
+
) -> None:
|
|
29
|
+
"""
|
|
30
|
+
Takes over secondary control from the :class:`pntos.api.ControllerPlugin`.
|
|
31
|
+
|
|
32
|
+
When pntOS first boots, it passes control over to the :class:`pntos.api.ControllerPlugin`. After the
|
|
33
|
+
:class:`pntos.api.ControllerPlugin` has initialized the plugins it wants to run, it calls this
|
|
34
|
+
plugin's :meth:`take_control` to allow for platform specific control behavior to run. The
|
|
35
|
+
:class:`pntos.api.PlatformIntegrationPlugin` (PIP) is not responsible for calling the
|
|
36
|
+
:meth:`pntos.api.CommonPlugin.init_plugin` call on any of the plugins passed in its plugins list, and
|
|
37
|
+
thus the list of plugins that is passed to the PIP should be pruned to only those plugins
|
|
38
|
+
the :class:`pntos.api.ControllerPlugin` initialized. The PIP is consequently not responsible for the
|
|
39
|
+
:class:`pntos.api.Mediator` construction or message routing - those responsibilities fall on the
|
|
40
|
+
:class:`pntos.api.ControllerPlugin`. Instead, the PIP is responsible for doing any additional logic
|
|
41
|
+
that may be platform specific.
|
|
42
|
+
|
|
43
|
+
Example:
|
|
44
|
+
For example, the PIP may decide to output solutions at a particular rate, or to have the
|
|
45
|
+
:class:`pntos.api.TransportPlugin` passed in its plugins list start/stop listening in response to
|
|
46
|
+
moding commands, or inform the :class:`pntos.api.OrchestrationPlugin` that it should not use a
|
|
47
|
+
particular sensor at runtime (via a registry convention).
|
|
48
|
+
|
|
49
|
+
In general, the goal of the PIP is to implement the platform-specific needs, whereas the
|
|
50
|
+
:class:`pntos.api.ControllerPlugin` is designed to be the generic portion of the code. The
|
|
51
|
+
:class:`pntos.api.ControllerPlugin` should be designed to be generic and re-useable, but work
|
|
52
|
+
hand-in-hand with the PIP to fully define the control behavior of the system.
|
|
53
|
+
|
|
54
|
+
:class:`pntos.api.ControllerPlugin` responsibilities:
|
|
55
|
+
- Defining concurrency model.
|
|
56
|
+
- Initializing plugins (and constructing/passing in :class:`pntos.api.Mediator`).
|
|
57
|
+
- Routing data from transport plugin to orchestration/initialization/inertial plugins.
|
|
58
|
+
- Routing requests for registry data to registry plugins.
|
|
59
|
+
|
|
60
|
+
:class:`pntos.api.PlatformIntegrationPlugin` responsibilities:
|
|
61
|
+
- Platform specific outputs.
|
|
62
|
+
- Responding to moding commands from platform.
|
|
63
|
+
- Routing situational awareness information to other pntOS plugins (via registry
|
|
64
|
+
convention).
|
|
65
|
+
|
|
66
|
+
The parameters to :meth:`pntos.api.PlatformIntegrationPlugin.take_control` should be identical to
|
|
67
|
+
those passed to the :meth:`pntos.api.ControllerPlugin.take_control`, with the exception of the
|
|
68
|
+
``plugins`` list being a subset of the ``plugins`` passed to the :class:`pntos.api.ControllerPlugin`.
|
|
69
|
+
Which plugins are passed to the PIP is implementation specific and decided by the
|
|
70
|
+
:class:`pntos.api.ControllerPlugin`.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
plugins (list[CommonPlugin]): A subset of the ``plugins`` passed to the
|
|
74
|
+
:class:`pntos.api.ControllerPlugin`. Which plugins are passed to the PIP is implementation
|
|
75
|
+
specific and decided by the :class:`pntos.api.ControllerPlugin`.
|
|
76
|
+
plugin_resources_locations (list[str | None] | None, optional): Should be identical to
|
|
77
|
+
what was passed to :meth:`pntos.api.ControllerPlugin.take_control`.
|
|
78
|
+
initial_config (str | None, optional): Should be identical to what was passed to
|
|
79
|
+
:meth:`pntos.api.ControllerPlugin.take_control`.
|
|
80
|
+
"""
|
|
81
|
+
pass
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Python API of pntOS."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from pntos.api import CommonPlugin, Message
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Preprocessor(ABC):
|
|
9
|
+
"""
|
|
10
|
+
A preprocessor.
|
|
11
|
+
|
|
12
|
+
Caution:
|
|
13
|
+
**Unstable**: This feature is unstable and is not yet considered part of the stable pntOS
|
|
14
|
+
API. Usage of this feature is highly discouraged in non-experimental code, and its
|
|
15
|
+
definition may change at any time.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
@abstractmethod
|
|
19
|
+
def process_pntos_message(self, message: Message) -> list[Message] | None:
|
|
20
|
+
"""
|
|
21
|
+
Process a message.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
message (Message): A message to be processed.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
list[Message] | None: A list of :class:`pntos.api.Message` s. Usually this will be a single message, a
|
|
28
|
+
modified version of ``message``. It could be ``None`` if ``message`` is rejected or
|
|
29
|
+
dropped. The preprocessor could also accumulate several messages, returning ``None`` for
|
|
30
|
+
each one then returning an array with multiple processed messages.
|
|
31
|
+
"""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class PreprocessorPlugin(CommonPlugin, ABC):
|
|
36
|
+
"""
|
|
37
|
+
An implementation of a preprocessor plugin.
|
|
38
|
+
|
|
39
|
+
This plugin generates :class:`pntos.api.Preprocessor` instances which may be used to process incoming
|
|
40
|
+
messages before being distributed to other plugins.
|
|
41
|
+
|
|
42
|
+
Caution:
|
|
43
|
+
**Unstable**: This feature is unstable and is not yet considered part of the stable pntOS
|
|
44
|
+
API. Usage of this feature is highly discouraged in non-experimental code, and its
|
|
45
|
+
definition may change at any time.
|
|
46
|
+
|
|
47
|
+
Attributes:
|
|
48
|
+
preprocessor_identifiers (list[str]): A list of identifying strings for each kind of
|
|
49
|
+
:class:`pntos.api.Preprocessor` that this :class:`pntos.api.PreprocessorPlugin` can create instances of. The
|
|
50
|
+
``preprocessor_index`` parameter of :meth:`new_preprocessor` is an index into this
|
|
51
|
+
array.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
preprocessor_identifiers: list[str]
|
|
55
|
+
"""Strings describing the preprocessors the provider can create.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
@abstractmethod
|
|
59
|
+
def new_preprocessor(
|
|
60
|
+
self, preprocessor_index: int, config_group: str | None = None
|
|
61
|
+
) -> Preprocessor | None:
|
|
62
|
+
"""
|
|
63
|
+
Get a newly created :class:`pntos.api.Preprocessor`.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
preprocessor_index (int): Since the :class:`pntos.api.PreprocessorPlugin` can create a different
|
|
67
|
+
preprocessor for each element in ``preprocessor_identifiers``, the
|
|
68
|
+
``preprocessor_index`` parameter is used to select which kind of preprocessor to
|
|
69
|
+
create a new instance of. The :attr:`pntos.api.PreprocessorPlugin.preprocessor_identifiers`
|
|
70
|
+
field contains identifying strings for the kinds of preprocessors.
|
|
71
|
+
|
|
72
|
+
Example:
|
|
73
|
+
For example, if the plugin can create 45 different preprocessors, the identifier
|
|
74
|
+
of the last preprocessor that can be created is found in
|
|
75
|
+
``preprocessor_identifiers[44]``. An instance of this preprocessor can be
|
|
76
|
+
created by calling ``new_preprocessor(44, ...)``. Note that ``0 <=
|
|
77
|
+
preprocessor_index < length of preprocessor_identifiers``.
|
|
78
|
+
config_group (str | None, optional): Indicates which (if any) parameter group in the
|
|
79
|
+
registry may be used to obtain additional configuration values to generate the new
|
|
80
|
+
preprocessor. If the preprocessor requires no outside configuration,
|
|
81
|
+
``config_group`` may be ``None``.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Preprocessor: A newly created :class:`pntos.api.Preprocessor`. Returns ``None`` if
|
|
85
|
+
``preprocessor_index`` is greater than or equal to the length of
|
|
86
|
+
:attr:`pntos.api.PreprocessorPlugin.preprocessor_identifiers` or if ``config_group`` is invalid.
|
|
87
|
+
"""
|
|
88
|
+
pass
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Python API of pntOS."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from pntos.api import CommonPlugin, Registry
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RegistryPlugin(CommonPlugin, ABC):
|
|
9
|
+
"""
|
|
10
|
+
Registry plugin.
|
|
11
|
+
|
|
12
|
+
A plugin for a global key-value registry. See the `pntOS Registry` page in
|
|
13
|
+
the `Internals` section for more information on the goal of this plugin.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def new_registry(self, initial_config: str | None = None) -> Registry:
|
|
18
|
+
"""
|
|
19
|
+
Create a new registry based on the initial values stored in ``initial_config``.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
initial_config (str | None, optional): The initial values the new registry should be
|
|
23
|
+
based on. The format of ``initial_config`` is implementation
|
|
24
|
+
specific, and plugins are free to support any or no format. Possible formats may
|
|
25
|
+
include:
|
|
26
|
+
|
|
27
|
+
- ``None``, in which case the plugin is free to choose initial values. Choices may
|
|
28
|
+
include hard-coded in the plugin or none at all.
|
|
29
|
+
- A ``str``. Examples of possible values the parameter could hold:
|
|
30
|
+
|
|
31
|
+
1. The entire config.
|
|
32
|
+
2. A local file path on systems which support them.
|
|
33
|
+
3. A string adhering to the URI scheme.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Registry: The newly created registry.
|
|
37
|
+
|
|
38
|
+
Note:
|
|
39
|
+
The returned :class:`pntos.api.Registry` should be capable of producing :class:`pntos.api.KeyValueStore`
|
|
40
|
+
structs that are able to be used concurrently. Thus if the user uses the return value of
|
|
41
|
+
this method to start two batches, one on group "foo" and the other on group "bar", then
|
|
42
|
+
concurrent access to both of the resulting :class:`pntos.api.KeyValueStore` structs for "foo" and
|
|
43
|
+
"bar" should be supported (i.e. no shared mutable state between them that is not
|
|
44
|
+
synchronized).
|
|
45
|
+
"""
|
|
46
|
+
pass
|