fprime-gds 3.4.2__py3-none-any.whl → 3.4.4a1__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.
- fprime_gds/common/communication/adapters/base.py +30 -58
- fprime_gds/common/communication/adapters/ip.py +23 -5
- fprime_gds/common/communication/adapters/uart.py +20 -7
- fprime_gds/common/communication/checksum.py +1 -3
- fprime_gds/common/communication/framing.py +53 -4
- fprime_gds/common/loaders/xml_loader.py +5 -1
- fprime_gds/common/zmq_transport.py +33 -18
- fprime_gds/executables/apps.py +150 -0
- fprime_gds/executables/cli.py +219 -65
- fprime_gds/executables/comm.py +14 -17
- fprime_gds/executables/run_deployment.py +55 -14
- fprime_gds/executables/utils.py +1 -1
- fprime_gds/plugin/__init__.py +0 -0
- fprime_gds/plugin/definitions.py +71 -0
- fprime_gds/plugin/system.py +225 -0
- {fprime_gds-3.4.2.dist-info → fprime_gds-3.4.4a1.dist-info}/METADATA +2 -2
- {fprime_gds-3.4.2.dist-info → fprime_gds-3.4.4a1.dist-info}/RECORD +22 -18
- {fprime_gds-3.4.2.dist-info → fprime_gds-3.4.4a1.dist-info}/WHEEL +1 -1
- {fprime_gds-3.4.2.dist-info → fprime_gds-3.4.4a1.dist-info}/LICENSE.txt +0 -0
- {fprime_gds-3.4.2.dist-info → fprime_gds-3.4.4a1.dist-info}/NOTICE.txt +0 -0
- {fprime_gds-3.4.2.dist-info → fprime_gds-3.4.4a1.dist-info}/entry_points.txt +0 -0
- {fprime_gds-3.4.2.dist-info → fprime_gds-3.4.4a1.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,7 @@ from fprime_gds.executables.cli import (
|
|
13
13
|
GdsParser,
|
14
14
|
ParserBase,
|
15
15
|
StandardPipelineParser,
|
16
|
+
PluginArgumentParser,
|
16
17
|
)
|
17
18
|
from fprime_gds.executables.utils import AppWrapperException, run_wrapped_application
|
18
19
|
|
@@ -20,14 +21,20 @@ BASE_MODULE_ARGUMENTS = [sys.executable, "-u", "-m"]
|
|
20
21
|
|
21
22
|
|
22
23
|
def parse_args():
|
23
|
-
"""
|
24
|
+
"""Parse command line arguments
|
24
25
|
Gets an argument parsers to read the command line and process the arguments. Return
|
25
26
|
the arguments in their namespace.
|
26
27
|
|
27
28
|
:return: parsed argument namespace
|
28
29
|
"""
|
29
30
|
# Get custom handlers for all executables we are running
|
30
|
-
arg_handlers = [
|
31
|
+
arg_handlers = [
|
32
|
+
StandardPipelineParser,
|
33
|
+
GdsParser,
|
34
|
+
BinaryDeployment,
|
35
|
+
CommParser,
|
36
|
+
PluginArgumentParser,
|
37
|
+
]
|
31
38
|
# Parse the arguments, and refine through all handlers
|
32
39
|
args, parser = ParserBase.parse_args(arg_handlers, "Run F prime deployment and GDS")
|
33
40
|
return args
|
@@ -63,7 +70,7 @@ def launch_process(cmd, logfile=None, name=None, env=None, launch_time=5):
|
|
63
70
|
|
64
71
|
|
65
72
|
def launch_tts(parsed_args):
|
66
|
-
"""
|
73
|
+
"""Launch the ThreadedTcpServer middleware application
|
67
74
|
|
68
75
|
|
69
76
|
Args:
|
@@ -85,7 +92,7 @@ def launch_tts(parsed_args):
|
|
85
92
|
|
86
93
|
|
87
94
|
def launch_html(parsed_args):
|
88
|
-
"""
|
95
|
+
"""Launch the Flask application
|
89
96
|
|
90
97
|
Args:
|
91
98
|
parsed_args: parsed argument namespace
|
@@ -112,14 +119,18 @@ def launch_html(parsed_args):
|
|
112
119
|
str(parsed_args.gui_port),
|
113
120
|
]
|
114
121
|
ret = launch_process(gse_args, name="HTML GUI", env=flask_env, launch_time=2)
|
122
|
+
ui_url = f"http://{str(parsed_args.gui_addr)}:{str(parsed_args.gui_port)}/"
|
123
|
+
print(f"[INFO] Launched UI at: {ui_url}")
|
115
124
|
webbrowser.open(
|
116
|
-
|
125
|
+
ui_url,
|
126
|
+
new=0,
|
127
|
+
autoraise=True,
|
117
128
|
)
|
118
129
|
return ret
|
119
130
|
|
120
131
|
|
121
132
|
def launch_app(parsed_args):
|
122
|
-
"""
|
133
|
+
"""Launch the raw application
|
123
134
|
|
124
135
|
Args:
|
125
136
|
parsed_args: parsed argument namespace
|
@@ -128,14 +139,20 @@ def launch_app(parsed_args):
|
|
128
139
|
"""
|
129
140
|
app_path = parsed_args.app
|
130
141
|
logfile = os.path.join(parsed_args.logs, f"{app_path.name}.log")
|
131
|
-
app_cmd = [
|
142
|
+
app_cmd = [
|
143
|
+
app_path.absolute(),
|
144
|
+
"-p",
|
145
|
+
str(parsed_args.port),
|
146
|
+
"-a",
|
147
|
+
parsed_args.address,
|
148
|
+
]
|
132
149
|
return launch_process(
|
133
150
|
app_cmd, name=f"{app_path.name} Application", logfile=logfile, launch_time=1
|
134
151
|
)
|
135
152
|
|
136
153
|
|
137
154
|
def launch_comm(parsed_args):
|
138
|
-
"""
|
155
|
+
"""Launch the communication adapter process
|
139
156
|
|
140
157
|
Args:
|
141
158
|
parsed_args: parsed argument namespace
|
@@ -143,9 +160,27 @@ def launch_comm(parsed_args):
|
|
143
160
|
launched process
|
144
161
|
"""
|
145
162
|
arguments = CommParser().reproduce_cli_args(parsed_args)
|
146
|
-
arguments =
|
163
|
+
arguments = (
|
164
|
+
arguments + ["--log-directly"]
|
165
|
+
if "--log-directly" not in arguments
|
166
|
+
else arguments
|
167
|
+
)
|
147
168
|
app_cmd = BASE_MODULE_ARGUMENTS + ["fprime_gds.executables.comm"] + arguments
|
148
|
-
return launch_process(
|
169
|
+
return launch_process(
|
170
|
+
app_cmd,
|
171
|
+
name=f"comm[{parsed_args.communication_selection}] Application",
|
172
|
+
launch_time=1,
|
173
|
+
)
|
174
|
+
|
175
|
+
|
176
|
+
def launch_plugin(plugin_class_instance):
|
177
|
+
""" Launch a plugin instance """
|
178
|
+
plugin_name = getattr(plugin_class_instance, "get_name", lambda: cls.__name__)()
|
179
|
+
return launch_process(
|
180
|
+
plugin_class_instance.get_process_invocation(),
|
181
|
+
name=f"{ plugin_name } Plugin App",
|
182
|
+
launch_time=1,
|
183
|
+
)
|
149
184
|
|
150
185
|
|
151
186
|
def main():
|
@@ -155,20 +190,23 @@ def main():
|
|
155
190
|
parsed_args = parse_args()
|
156
191
|
launchers = []
|
157
192
|
|
158
|
-
# Launch
|
193
|
+
# Launch middleware layer if not using ZMQ
|
159
194
|
if not parsed_args.zmq:
|
160
195
|
launchers.append(launch_tts)
|
161
196
|
|
162
197
|
# Check if we are running with communications
|
163
|
-
if parsed_args.
|
198
|
+
if parsed_args.communication_selection != "none":
|
164
199
|
launchers.append(launch_comm)
|
165
200
|
|
166
201
|
# Add app, if possible
|
167
202
|
if parsed_args.app:
|
168
|
-
if parsed_args.
|
203
|
+
if parsed_args.communication_selection == "ip":
|
169
204
|
launchers.append(launch_app)
|
170
205
|
else:
|
171
|
-
print(
|
206
|
+
print(
|
207
|
+
"[WARNING] App cannot be auto-launched without IP adapter",
|
208
|
+
file=sys.stderr,
|
209
|
+
)
|
172
210
|
|
173
211
|
# Launch the desired GUI package
|
174
212
|
if parsed_args.gui == "html":
|
@@ -177,6 +215,9 @@ def main():
|
|
177
215
|
# Launch launchers and wait for the last app to finish
|
178
216
|
try:
|
179
217
|
procs = [launcher(parsed_args) for launcher in launchers]
|
218
|
+
_ = [launch_plugin(cls) for cls in parsed_args.gds_app_enabled_instances]
|
219
|
+
_ = [instance.run() for instance in parsed_args.gds_function_enabled_instances]
|
220
|
+
|
180
221
|
print("[INFO] F prime is now running. CTRL-C to shutdown all components.")
|
181
222
|
procs[-1].wait()
|
182
223
|
except KeyboardInterrupt:
|
fprime_gds/executables/utils.py
CHANGED
@@ -118,7 +118,7 @@ def run_wrapped_application(arguments, logfile=None, env=None, launch_time=None)
|
|
118
118
|
if launch_time is not None:
|
119
119
|
time.sleep(launch_time)
|
120
120
|
child.poll()
|
121
|
-
if child.returncode is not None:
|
121
|
+
if child.returncode is not None and child.returncode != 0:
|
122
122
|
raise ProcessNotStableException(
|
123
123
|
arguments[0], child.returncode, launch_time
|
124
124
|
)
|
File without changes
|
@@ -0,0 +1,71 @@
|
|
1
|
+
""" fprime_gds.plugin.definitions: definitions of plugin specifications and decorators
|
2
|
+
|
3
|
+
In order to define a plugin, an implementation decorator is used. Users can import `gds_plugin_implementation` from this
|
4
|
+
file to decorate functions that implement plugins.
|
5
|
+
|
6
|
+
This file also defines helper classes to support the plugin system.
|
7
|
+
|
8
|
+
@author lestarch
|
9
|
+
"""
|
10
|
+
import pluggy
|
11
|
+
from enum import Enum, auto
|
12
|
+
from typing import Any, Dict, Tuple, Type
|
13
|
+
|
14
|
+
PROJECT_NAME = "fprime_gds"
|
15
|
+
|
16
|
+
gds_plugin_specification = pluggy.HookspecMarker(PROJECT_NAME)
|
17
|
+
gds_plugin_implementation = pluggy.HookimplMarker(PROJECT_NAME)
|
18
|
+
|
19
|
+
|
20
|
+
class PluginType(Enum):
|
21
|
+
""" Enumeration of plugin types"""
|
22
|
+
ALL = auto()
|
23
|
+
""" Plugin selection including all types of plugins """
|
24
|
+
|
25
|
+
SELECTION = auto()
|
26
|
+
""" Plugin that provides a selection between implementations """
|
27
|
+
|
28
|
+
FEATURE = auto()
|
29
|
+
""" Plugin that provides a feature """
|
30
|
+
|
31
|
+
|
32
|
+
class Plugin(object):
|
33
|
+
""" Plugin wrapper object """
|
34
|
+
|
35
|
+
def __init__(self, category: str, plugin_type: PluginType, plugin_class: Type[Any]):
|
36
|
+
""" Initialize the plugin
|
37
|
+
|
38
|
+
Args:
|
39
|
+
category: category of the plugin (i.e. register_<category>_function)
|
40
|
+
plugin_type: type of plugin
|
41
|
+
plugin_class: implementation class of the plugin
|
42
|
+
"""
|
43
|
+
self.category = category
|
44
|
+
self.type = plugin_type
|
45
|
+
self.plugin_class = plugin_class
|
46
|
+
|
47
|
+
def get_name(self):
|
48
|
+
""" Get the name of the plugin
|
49
|
+
|
50
|
+
Plugin names are derived from the `get_name` class method of the plugin's implementation class. When not defined
|
51
|
+
that name is derived from the plugin's implementation class __name__ property instead.
|
52
|
+
|
53
|
+
Returns:
|
54
|
+
name of plugin
|
55
|
+
"""
|
56
|
+
return (
|
57
|
+
self.plugin_class.get_name() if hasattr(self.plugin_class, "get_name")
|
58
|
+
else self.plugin_class.__name__
|
59
|
+
)
|
60
|
+
|
61
|
+
def get_arguments(self) -> Dict[Tuple[str, ...], Dict[str, Any]]:
|
62
|
+
""" Get arguments needed by plugin
|
63
|
+
|
64
|
+
Plugin argument are derived from the `get_arguments` class method of the plugin's implementation class. When not
|
65
|
+
defined an empty dictionary is returned.
|
66
|
+
|
67
|
+
Returns:
|
68
|
+
argument specification for plugin
|
69
|
+
"""
|
70
|
+
return self.plugin_class.get_arguments() if hasattr(self.plugin_class, "get_arguments") else {}
|
71
|
+
|
@@ -0,0 +1,225 @@
|
|
1
|
+
""" fprime_gds.plugin.system: implementation of plugins
|
2
|
+
|
3
|
+
This file contains the implementation and registration of plugins for fprime_gds. Primarily, it defines the Plugins
|
4
|
+
class that handles plugins. Users can acquire the Plugin singleton with `Plugin.system()`.
|
5
|
+
|
6
|
+
This file also imports and registers plugin implementations built-into fprime-gds. These plugins are not registered
|
7
|
+
using entrypoints.
|
8
|
+
|
9
|
+
@author lestarch
|
10
|
+
"""
|
11
|
+
import os
|
12
|
+
import importlib
|
13
|
+
import inspect
|
14
|
+
import logging
|
15
|
+
from typing import Iterable, List, Union
|
16
|
+
|
17
|
+
import pluggy
|
18
|
+
|
19
|
+
from fprime_gds.plugin.definitions import Plugin, PluginType, PROJECT_NAME
|
20
|
+
|
21
|
+
# For automatic validation of plugins, each plugin class type must be imported here
|
22
|
+
from fprime_gds.executables.apps import GdsFunction, GdsApp
|
23
|
+
from fprime_gds.common.communication.framing import FramerDeframer, FpFramerDeframer
|
24
|
+
from fprime_gds.common.communication.adapters.base import BaseAdapter, NoneAdapter
|
25
|
+
from fprime_gds.common.communication.adapters.ip import IpAdapter
|
26
|
+
|
27
|
+
try:
|
28
|
+
from fprime_gds.common.communication.adapters.uart import SerialAdapter
|
29
|
+
except ImportError:
|
30
|
+
SerialAdapter = None
|
31
|
+
|
32
|
+
# Handy constants
|
33
|
+
LOGGER = logging.getLogger(__name__)
|
34
|
+
|
35
|
+
|
36
|
+
# Metadata regarding each plugin:
|
37
|
+
_PLUGIN_METADATA = {
|
38
|
+
"framing": {
|
39
|
+
"class": FramerDeframer,
|
40
|
+
"type": PluginType.SELECTION,
|
41
|
+
"built-in": [FpFramerDeframer]
|
42
|
+
},
|
43
|
+
"communication": {
|
44
|
+
"class": BaseAdapter,
|
45
|
+
"type": PluginType.SELECTION,
|
46
|
+
"built-in": [adapter for adapter in [NoneAdapter, IpAdapter, SerialAdapter] if adapter is not None]
|
47
|
+
},
|
48
|
+
"gds_function": {
|
49
|
+
"class": GdsFunction,
|
50
|
+
"type": PluginType.FEATURE,
|
51
|
+
"built-in": []
|
52
|
+
},
|
53
|
+
"gds_app": {
|
54
|
+
"class": GdsApp,
|
55
|
+
"type": PluginType.FEATURE,
|
56
|
+
"built-in": []
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
class PluginException(Exception):
|
62
|
+
pass
|
63
|
+
|
64
|
+
|
65
|
+
class InvalidCategoryException(PluginException):
|
66
|
+
pass
|
67
|
+
|
68
|
+
|
69
|
+
class Plugins(object):
|
70
|
+
"""GDS plugin system providing a plugin Singleton for use across the GDS
|
71
|
+
|
72
|
+
GDS plugins are broken into categories (e.g. framing) that represent the key features users can adjust. Each GDS
|
73
|
+
application will support and load the plugins for a given category.
|
74
|
+
"""
|
75
|
+
PLUGIN_ENVIRONMENT_VARIABLE = "FPRIME_GDS_EXTRA_PLUGINS"
|
76
|
+
_singleton = None
|
77
|
+
|
78
|
+
def __init__(self, categories: Union[None, List] = None):
|
79
|
+
""" Initialize the plugin system with specific categories
|
80
|
+
|
81
|
+
Initialize the plugin system with support for the supplied categories. Only plugins for the specified categories
|
82
|
+
will be loaded for use. Other plugins will not be available for use.
|
83
|
+
|
84
|
+
Args:
|
85
|
+
categories: None for all categories otherwise a list of categories
|
86
|
+
"""
|
87
|
+
categories = self.get_all_categories() if categories is None else categories
|
88
|
+
self.categories = categories
|
89
|
+
self.manager = pluggy.PluginManager(PROJECT_NAME)
|
90
|
+
|
91
|
+
# Load hook specifications from only the configured categories
|
92
|
+
for category in categories:
|
93
|
+
self.manager.add_hookspecs(_PLUGIN_METADATA[category]["class"])
|
94
|
+
|
95
|
+
# Load plugins from setuptools entrypoints and the built-in plugins (limited to category)
|
96
|
+
self.manager.load_setuptools_entrypoints(PROJECT_NAME)
|
97
|
+
|
98
|
+
# Load plugins from environment variable specified modules
|
99
|
+
for token in [token for token in os.environ.get(self.PLUGIN_ENVIRONMENT_VARIABLE, "").split(";") if token]:
|
100
|
+
module, class_token = token.split(":")
|
101
|
+
try:
|
102
|
+
imported_module = importlib.import_module(module)
|
103
|
+
module_class = module if class_token == "" else getattr(imported_module, class_token, imported_module)
|
104
|
+
self.register_plugin(module_class)
|
105
|
+
except ImportError as imp:
|
106
|
+
LOGGER.debug("Failed to load %s.%s as plugin", module, class_token)
|
107
|
+
|
108
|
+
# Load built-in plugins
|
109
|
+
for category in categories:
|
110
|
+
for built_in in _PLUGIN_METADATA[category]["built-in"]:
|
111
|
+
self.register_plugin(built_in)
|
112
|
+
|
113
|
+
def get_plugins(self, category) -> Iterable:
|
114
|
+
"""Get available plugins for the given category
|
115
|
+
|
116
|
+
Gets all plugin implementors of "category" by looking for register_<category>_plugin implementors. If such a
|
117
|
+
function does not exist then this results in an exception.
|
118
|
+
|
119
|
+
Args:
|
120
|
+
category: category of the plugin requested
|
121
|
+
|
122
|
+
Return:
|
123
|
+
validated list of plugin implementor classes
|
124
|
+
"""
|
125
|
+
try:
|
126
|
+
plugin_classes = getattr(self.manager.hook, f"register_{category}_plugin")()
|
127
|
+
except KeyError as error:
|
128
|
+
raise InvalidCategoryException(f"Invalid plugin category: {error}")
|
129
|
+
|
130
|
+
return [
|
131
|
+
Plugin(category, self.get_category_plugin_type(category), plugin_class)
|
132
|
+
for plugin_class in plugin_classes
|
133
|
+
if self.validate_selection(category, plugin_class)
|
134
|
+
]
|
135
|
+
|
136
|
+
def register_plugin(self, module_or_class):
|
137
|
+
"""Register a plugin directly
|
138
|
+
|
139
|
+
Allows local registration of plugin implementations that are shipped as part of the GDS package.
|
140
|
+
|
141
|
+
Args:
|
142
|
+
module_or_class: module or class that has plugin implementations
|
143
|
+
"""
|
144
|
+
self.manager.register(module_or_class)
|
145
|
+
|
146
|
+
def get_categories(self):
|
147
|
+
""" Get plugin categories """
|
148
|
+
return self.categories
|
149
|
+
|
150
|
+
@staticmethod
|
151
|
+
def get_all_categories():
|
152
|
+
""" Get all plugin categories """
|
153
|
+
return _PLUGIN_METADATA.keys()
|
154
|
+
|
155
|
+
@staticmethod
|
156
|
+
def get_plugin_metadata(category):
|
157
|
+
""" Get the plugin metadata for a given plugin category """
|
158
|
+
return _PLUGIN_METADATA[category]
|
159
|
+
|
160
|
+
@classmethod
|
161
|
+
def get_category_plugin_type(cls, category):
|
162
|
+
""" Get the plugin type given the category """
|
163
|
+
return cls.get_plugin_metadata(category)["type"]
|
164
|
+
|
165
|
+
@classmethod
|
166
|
+
def get_category_specification_class(cls, category):
|
167
|
+
""" Get the plugin class given the category """
|
168
|
+
return cls.get_plugin_metadata(category)["class"]
|
169
|
+
|
170
|
+
@classmethod
|
171
|
+
def validate_selection(cls, category, result):
|
172
|
+
"""Validate the result of plugin hook
|
173
|
+
|
174
|
+
Validates the result of a plugin hook call to ensure the result meets the expected properties for plugins of the
|
175
|
+
given category. Primarily this ensures that this plugin returns a concrete subclass of the expected type.
|
176
|
+
|
177
|
+
Args:
|
178
|
+
category: category of plugin used
|
179
|
+
result: result from the plugin hook call
|
180
|
+
Return:
|
181
|
+
True when the plugin passes validation, False otherwise
|
182
|
+
"""
|
183
|
+
# Typing library not intended for introspection at runtime, thus we maintain a map of plugin specification
|
184
|
+
# functions to the types expected as a return value. When this is not found, plugins may continue without
|
185
|
+
# automatic validation.
|
186
|
+
try:
|
187
|
+
expected_class = cls.get_category_specification_class(category)
|
188
|
+
# Validate the result
|
189
|
+
if not issubclass(result, expected_class):
|
190
|
+
LOGGER.warning(
|
191
|
+
f"{result.__name__} is not a subclass of {expected_class.__name__}. Not registering."
|
192
|
+
)
|
193
|
+
return False
|
194
|
+
elif inspect.isabstract(result):
|
195
|
+
LOGGER.warning(
|
196
|
+
f"{result.__name__} is an abstract class. Not registering."
|
197
|
+
)
|
198
|
+
return False
|
199
|
+
except KeyError:
|
200
|
+
LOGGER.warning(
|
201
|
+
f"Plugin not registered for validation. Continuing without validation."
|
202
|
+
)
|
203
|
+
return True
|
204
|
+
|
205
|
+
@classmethod
|
206
|
+
def system(cls, categories: Union[None, List] = None) -> "Plugins":
|
207
|
+
""" Get plugin system singleton
|
208
|
+
|
209
|
+
Constructs the plugin system singleton (when it has yet to be constructed) then returns the singleton. The
|
210
|
+
singleton will support specific categories and further requests for a singleton will cause an assertion error
|
211
|
+
unless the categories match or is None.
|
212
|
+
|
213
|
+
Args:
|
214
|
+
categories: a list of categories to support or None to use the existing categories
|
215
|
+
|
216
|
+
Returns:
|
217
|
+
plugin system
|
218
|
+
"""
|
219
|
+
# Singleton undefined, construct it
|
220
|
+
if cls._singleton is None:
|
221
|
+
cls._singleton = cls(cls.get_all_categories() if categories is None else categories)
|
222
|
+
# Ensure categories was unspecified or matches the singleton
|
223
|
+
assert categories is None or cls._singleton.categories == categories, "Inconsistent plugin categories"
|
224
|
+
return cls._singleton
|
225
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fprime-gds
|
3
|
-
Version: 3.4.
|
3
|
+
Version: 3.4.4a1
|
4
4
|
Summary: F Prime Flight Software Ground Data System layer
|
5
5
|
Author-email: Michael Starch <Michael.D.Starch@jpl.nasa.gov>, Thomas Boyer-Chammard <Thomas.Boyer.Chammard@jpl.nasa.gov>
|
6
6
|
License:
|
@@ -234,7 +234,7 @@ Requires-Dist: pyzmq >=24.0.1
|
|
234
234
|
Requires-Dist: pexpect >=4.8.0
|
235
235
|
Requires-Dist: pytest >=6.2.4
|
236
236
|
Requires-Dist: flask-restful >=0.3.8
|
237
|
-
Requires-Dist: fprime-tools >=3.
|
237
|
+
Requires-Dist: fprime-tools >=3.4.3
|
238
238
|
Requires-Dist: argcomplete >=1.12.3
|
239
239
|
Requires-Dist: Jinja2 >=2.11.3
|
240
240
|
Requires-Dist: openpyxl >=3.0.10
|
@@ -4,16 +4,16 @@ fprime_gds/version.py,sha256=dlUlfOKTsGaqz_L7TjhCVC-Vanx5cK67kdZlqcHCM8M,395
|
|
4
4
|
fprime_gds/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
fprime_gds/common/handlers.py,sha256=t2-st-C3Z486kfcu2cpf-wHJQmpaaHQYj1dyXJEMmSU,2632
|
6
6
|
fprime_gds/common/transport.py,sha256=y9HiupzsCRF5_JFMMtMWQxcEYPvPuxX1P_oBeqosKR0,10565
|
7
|
-
fprime_gds/common/zmq_transport.py,sha256=
|
7
|
+
fprime_gds/common/zmq_transport.py,sha256=Wb9IFFyp89S6y2okYavmVygOSqg7IJMbBoyBOR4iIrg,12291
|
8
8
|
fprime_gds/common/communication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
fprime_gds/common/communication/checksum.py,sha256=
|
10
|
-
fprime_gds/common/communication/framing.py,sha256=
|
9
|
+
fprime_gds/common/communication/checksum.py,sha256=f6W0Tr68U-XGnFmysMqsFzoGYZVE8clKf-VIJja_1YM,741
|
10
|
+
fprime_gds/common/communication/framing.py,sha256=TPpVn5JfGJxdc9BuKJzm5LXo6OQKtkSqX695UdN-Ezk,12915
|
11
11
|
fprime_gds/common/communication/ground.py,sha256=9SD3AoyHA43yNE8UYkWnu5nEJt1PgyB3sU3QLDc4eDY,3619
|
12
12
|
fprime_gds/common/communication/updown.py,sha256=UhfCIIA2eM5g2FsIhOGJJH6HzHurUPgcKIJ5fsLb2lE,9888
|
13
13
|
fprime_gds/common/communication/adapters/__init__.py,sha256=ivGtzUTqhBYuve5mhN9VOHITwgZjNMVv7sxuac2Ll3c,470
|
14
|
-
fprime_gds/common/communication/adapters/base.py,sha256=
|
15
|
-
fprime_gds/common/communication/adapters/ip.py,sha256=
|
16
|
-
fprime_gds/common/communication/adapters/uart.py,sha256=
|
14
|
+
fprime_gds/common/communication/adapters/base.py,sha256=i3mf4HC-4tuf4mNkhdXCKlngRhODyTriia2pw6XBoSQ,3393
|
15
|
+
fprime_gds/common/communication/adapters/ip.py,sha256=vCDclpsb3rVRXSxKqdt9UfkM2M6oCxnsKdzbzhMc0kM,17074
|
16
|
+
fprime_gds/common/communication/adapters/uart.py,sha256=6SrN42ShVjwNubFg-1YrO09o1uJtu1rFqeMpLDNWlW4,6647
|
17
17
|
fprime_gds/common/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
18
|
fprime_gds/common/data_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
fprime_gds/common/data_types/ch_data.py,sha256=RP9zSyzNcH0nJ3MYyW_IATnmnHYZ6d0KmoJUJantdBI,6111
|
@@ -66,7 +66,7 @@ fprime_gds/common/loaders/event_py_loader.py,sha256=m4KlDl0mXn8ZQr-IfpUg0KaGIOJU
|
|
66
66
|
fprime_gds/common/loaders/event_xml_loader.py,sha256=DXyriGpGiuzG1a5Eyb8PLH3x7X1-hNxiIpY_yC3UPgQ,2790
|
67
67
|
fprime_gds/common/loaders/pkt_xml_loader.py,sha256=ZS4qchqQnIBx0Tw69ehP8yqm1g_uYSQzmnijR3FxqJg,4795
|
68
68
|
fprime_gds/common/loaders/python_loader.py,sha256=FUNQbFy75bpqvss1JDu2UWZBMrtnMpFegM6mcglh42I,4858
|
69
|
-
fprime_gds/common/loaders/xml_loader.py,sha256=
|
69
|
+
fprime_gds/common/loaders/xml_loader.py,sha256=QqNYFjxLB7mmj-9rsqKHB1QunC-dcj1cBHrvhhZvakw,14121
|
70
70
|
fprime_gds/common/logger/__init__.py,sha256=YBrr9An0fZbp4kvphRl8nLfolkdBqFAsSGzEZXQiH6g,1448
|
71
71
|
fprime_gds/common/logger/data_logger.py,sha256=VjfhTGO1gGw954xNhSc0_zpw8JexCho5f8BlXDEYkL4,2505
|
72
72
|
fprime_gds/common/logger/test_logger.py,sha256=wL8Lq49sVmxGRALgv-ei6AnXFh79qlHFehmKJ1A8X28,6475
|
@@ -102,12 +102,13 @@ fprime_gds/common/utils/data_desc_type.py,sha256=9GV8hV5q1dDxdfF-1-Wty5MBrFd94Eb
|
|
102
102
|
fprime_gds/common/utils/event_severity.py,sha256=7qPXHrDaM_REJ7sKBUEJTZIE0D4qVnVajsPDUuHg7sI,300
|
103
103
|
fprime_gds/common/utils/string_util.py,sha256=jqut5Dd0EjvTHMci1mvs_8KQ1Nq-38xZofeaaSoiJEY,3985
|
104
104
|
fprime_gds/executables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
105
|
-
fprime_gds/executables/
|
106
|
-
fprime_gds/executables/
|
105
|
+
fprime_gds/executables/apps.py,sha256=h2acqdOyMgv77IMEQUc41QcwAZ-_DToX6sZplCk17Zg,6543
|
106
|
+
fprime_gds/executables/cli.py,sha256=bitIny2JYApMVuu3G4adnxB9iI-pieDaXAWJjNcHcLo,36942
|
107
|
+
fprime_gds/executables/comm.py,sha256=KMoAtcUdE_KOFg4DynHCCCc3rfIiedjexx_FP6oN77s,5259
|
107
108
|
fprime_gds/executables/fprime_cli.py,sha256=GvvuUQuoDGBrqQB867bDjUR3Kn5yPUckAY2rdfTa8jo,12432
|
108
|
-
fprime_gds/executables/run_deployment.py,sha256=
|
109
|
+
fprime_gds/executables/run_deployment.py,sha256=01tI0JVONRkKaPPdfJS0Qt1mWm_7Wgf3N9iknozXmYc,7043
|
109
110
|
fprime_gds/executables/tcpserver.py,sha256=KspVpu5YIuiWKOk5E6UDMKvqXYrRB1j9aX8CkMxysfw,17555
|
110
|
-
fprime_gds/executables/utils.py,sha256=
|
111
|
+
fprime_gds/executables/utils.py,sha256=cBCFOpQthjxohWZmsdAQL1Y_lFYw73SQ-ANDjUoe33w,7221
|
111
112
|
fprime_gds/flask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
112
113
|
fprime_gds/flask/app.py,sha256=kJDCziri_BwZWKUszkR7u3RaNG_FWRzDkdCPsVDAtYM,6720
|
113
114
|
fprime_gds/flask/channels.py,sha256=sOeL-UmWPh2hqYvqj81STpABLlPcjdPgkRwjd3Qx77k,735
|
@@ -218,10 +219,13 @@ fprime_gds/flask/static/third-party/webfonts/fa-solid-900.svg,sha256=lnTrG9VQRxe
|
|
218
219
|
fprime_gds/flask/static/third-party/webfonts/fa-solid-900.ttf,sha256=r2OXUD_O-9YTl2whrVweNymMGLvgfQltsDzNOvbgW6g,202744
|
219
220
|
fprime_gds/flask/static/third-party/webfonts/fa-solid-900.woff,sha256=P200iM9lN09vZ2wxU0CwrCvoMr1VJAyAlEjjbvm5YyY,101648
|
220
221
|
fprime_gds/flask/static/third-party/webfonts/fa-solid-900.woff2,sha256=mDS4KtJuKjdYPSJnahLdLrD-fIA1aiEU0NsaqLOJlTc,78268
|
221
|
-
fprime_gds
|
222
|
-
fprime_gds
|
223
|
-
fprime_gds
|
224
|
-
fprime_gds-3.4.
|
225
|
-
fprime_gds-3.4.
|
226
|
-
fprime_gds-3.4.
|
227
|
-
fprime_gds-3.4.
|
222
|
+
fprime_gds/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
223
|
+
fprime_gds/plugin/definitions.py,sha256=5rHGSOrr62qRNVfX9bZIo4HDAKG62lKteNum9G40y3g,2347
|
224
|
+
fprime_gds/plugin/system.py,sha256=uWd6DVW90Re0FoNMPNCx0cXXTJUdpgAAO0mtakzRNgk,8564
|
225
|
+
fprime_gds-3.4.4a1.dist-info/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
226
|
+
fprime_gds-3.4.4a1.dist-info/METADATA,sha256=TiKl7YCs8sVBbCDBfQm6EK67tFvTtfH3f_hl3ewZ-tY,24755
|
227
|
+
fprime_gds-3.4.4a1.dist-info/NOTICE.txt,sha256=vXjA_xRcQhd83Vfk5D_vXg5kOjnnXvLuMi5vFKDEVmg,1612
|
228
|
+
fprime_gds-3.4.4a1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
229
|
+
fprime_gds-3.4.4a1.dist-info/entry_points.txt,sha256=UisSXL905z4YEjwd7c-I2o6ZKmOw1xDDdO1mN0VPu6c,271
|
230
|
+
fprime_gds-3.4.4a1.dist-info/top_level.txt,sha256=6vzFLIX6ANfavKaXFHDMSLFtS94a6FaAsIWhjgYuSNE,27
|
231
|
+
fprime_gds-3.4.4a1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|