manta-node 0.5b0.dev9__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.
Files changed (42) hide show
  1. manta_node/__init__.py +5 -0
  2. manta_node/__main__.py +57 -0
  3. manta_node/cli/__init__.py +6 -0
  4. manta_node/cli/commands/__init__.py +21 -0
  5. manta_node/cli/commands/cluster.py +419 -0
  6. manta_node/cli/commands/config.py +490 -0
  7. manta_node/cli/commands/logs.py +168 -0
  8. manta_node/cli/commands/start.py +459 -0
  9. manta_node/cli/commands/status.py +204 -0
  10. manta_node/cli/commands/stop.py +253 -0
  11. manta_node/cli/config_manager.py +139 -0
  12. manta_node/cli/main.py +133 -0
  13. manta_node/cli/version.py +106 -0
  14. manta_node/domain/__init__.py +8 -0
  15. manta_node/domain/task_lifecycle.py +83 -0
  16. manta_node/infrastructure/__init__.py +13 -0
  17. manta_node/infrastructure/config/__init__.py +31 -0
  18. manta_node/infrastructure/config/node_config_manager.py +918 -0
  19. manta_node/infrastructure/container/__init__.py +9 -0
  20. manta_node/infrastructure/container/docker_adapter.py +253 -0
  21. manta_node/infrastructure/container/manager.py +536 -0
  22. manta_node/infrastructure/filesystem/__init__.py +7 -0
  23. manta_node/infrastructure/filesystem/dataset_manager.py +469 -0
  24. manta_node/infrastructure/grpc/__init__.py +11 -0
  25. manta_node/infrastructure/grpc/client.py +373 -0
  26. manta_node/infrastructure/grpc/local_servicer.py +151 -0
  27. manta_node/infrastructure/grpc/world_servicer.py +284 -0
  28. manta_node/infrastructure/metrics/__init__.py +10 -0
  29. manta_node/infrastructure/metrics/collector.py +94 -0
  30. manta_node/infrastructure/metrics/metrics_collector.py +351 -0
  31. manta_node/infrastructure/mqtt/__init__.py +7 -0
  32. manta_node/infrastructure/mqtt/command_handler.py +315 -0
  33. manta_node/node_orchestrator.py +462 -0
  34. manta_node/task_manager.py +519 -0
  35. manta_node/tasks.py +272 -0
  36. manta_node/utils.py +52 -0
  37. manta_node-0.5b0.dev9.dist-info/METADATA +799 -0
  38. manta_node-0.5b0.dev9.dist-info/RECORD +42 -0
  39. manta_node-0.5b0.dev9.dist-info/WHEEL +5 -0
  40. manta_node-0.5b0.dev9.dist-info/entry_points.txt +2 -0
  41. manta_node-0.5b0.dev9.dist-info/licenses/LICENSE +683 -0
  42. manta_node-0.5b0.dev9.dist-info/top_level.txt +1 -0
manta_node/tasks.py ADDED
@@ -0,0 +1,272 @@
1
+ from datetime import datetime
2
+ from pathlib import Path
3
+ from typing import Callable, Iterable, Iterator, List, Tuple
4
+
5
+ from manta_common.build.common.tasks import MqttTask, TaskStatus, TaskUpdate
6
+ from manta_common.conversions import ID, TupleID
7
+ from .domain.task_lifecycle import TaskLifecycleService, TaskTransitionRule
8
+
9
+
10
+ class TaskProgression:
11
+ """
12
+ Task progression is a data structure which holds :
13
+
14
+ * a task update
15
+ * a module file
16
+ * a start time
17
+ """
18
+
19
+ __slots__ = ["task_update", "module_file", "start_time"]
20
+
21
+ def __init__(
22
+ self, task_update: TaskUpdate, module_file: Path, start_time: datetime
23
+ ):
24
+ self.task_update = task_update
25
+ self.module_file = module_file
26
+ self.start_time = start_time
27
+
28
+ @property
29
+ def task_id(self) -> ID:
30
+ """
31
+ Get Task ID
32
+
33
+ Returns
34
+ -------
35
+ ID
36
+ Task ID
37
+ """
38
+ return ID(self.task_update.task_id)
39
+
40
+ @property
41
+ def swarm_id(self) -> ID:
42
+ """
43
+ Get Swarm ID
44
+
45
+ Returns
46
+ -------
47
+ ID
48
+ Swarm ID
49
+ """
50
+ return ID(self.task_update.swarm_id)
51
+
52
+ @property
53
+ def task_status(self) -> TaskStatus:
54
+ """
55
+ Get Task Status
56
+
57
+ Returns
58
+ -------
59
+ TaskStatus
60
+ Task Status
61
+ """
62
+ return self.task_update.task_status
63
+
64
+ @task_status.setter
65
+ def task_status(self, task_status: TaskStatus):
66
+ """
67
+ Set a new task status
68
+
69
+ Parameters
70
+ ----------
71
+ task_status : TaskStatus
72
+ Task Status to set
73
+ """
74
+ self.task_update.task_status = task_status
75
+
76
+ def unlink(self, missing_ok: bool = True):
77
+ """
78
+ Unlink module file
79
+
80
+ Parameters
81
+ ----------
82
+ missing_ok : bool
83
+ Extra parameter from :code:`Path.unlink`
84
+ """
85
+ self.module_file.unlink(missing_ok)
86
+
87
+ def is_active_task(self) -> bool:
88
+ """
89
+ Check if is an active task
90
+
91
+ Returns
92
+ -------
93
+ bool
94
+ Is active task
95
+ """
96
+ # Use domain service for business logic
97
+ return TaskLifecycleService.is_active(self.task_status)
98
+
99
+ def is_finished_task(self) -> bool:
100
+ """
101
+ Check if is a finished task
102
+
103
+ Returns
104
+ -------
105
+ bool
106
+ Is a finished task
107
+ """
108
+ # Use domain rule for terminal state check
109
+ return TaskTransitionRule.is_finished(self.task_status)
110
+
111
+ def compare_iteration(self, mqtt_task: MqttTask) -> bool:
112
+ """
113
+ Compare iteration between a task from MQTT and itself
114
+
115
+ Parameters
116
+ ----------
117
+ mqtt_task : MqttTask
118
+ Task from MQTT
119
+
120
+ Returns
121
+ -------
122
+ bool
123
+ Same iteration
124
+ """
125
+ return (
126
+ self.task_update.iteration == mqtt_task.iteration
127
+ and self.task_update.circular == mqtt_task.circular
128
+ )
129
+
130
+
131
+ class TaskProgressions:
132
+ """
133
+ List of Task Progression used in Task Manager and World Servicer
134
+ """
135
+
136
+ __slots__ = ["_tasks", "_env_ids"]
137
+
138
+ def __init__(self):
139
+ self._tasks: List[TaskProgression] = []
140
+ self._env_ids: List[Tuple[TupleID, TupleID]] = []
141
+
142
+ def __iter__(self) -> Iterator[TaskProgression]:
143
+ """
144
+ Iterate over tasks
145
+
146
+ Returns
147
+ -------
148
+ Iterator[TaskProgression]
149
+ Iterator of task progressions
150
+ """
151
+ return iter(self._tasks)
152
+
153
+ def __getitem__(self, env_id: Tuple[TupleID, TupleID]) -> TaskProgression:
154
+ """
155
+ Return the task progression given the task ID
156
+
157
+ Parameters
158
+ ----------
159
+ env_id : str
160
+ Task and Swarms IDs in a tuple
161
+
162
+ Returns
163
+ -------
164
+ TaskProgression
165
+ Task Progression
166
+ """
167
+ if env_id not in self._env_ids:
168
+ raise KeyError(
169
+ f"Cannot get task due to {env_id} not found in tasks {self._env_ids}"
170
+ )
171
+ return self._tasks[self._env_ids.index(env_id)]
172
+
173
+ def __contains__(self, env_id: Tuple[TupleID, TupleID]) -> bool:
174
+ """
175
+ Check if the task ID exists in itself
176
+
177
+ Parameters
178
+ ----------
179
+ env_id : Tuple[TupleID, TupleID]
180
+ Task and Swarms IDs in a tuple
181
+
182
+ Returns
183
+ -------
184
+ bool
185
+ It contains the task ID
186
+ """
187
+ return env_id in self._env_ids
188
+
189
+ def append(self, task_progression: TaskProgression):
190
+ """
191
+ Append a task progression
192
+
193
+ Parameters
194
+ ----------
195
+ task_progression : TaskProgression
196
+ Task Progression
197
+ """
198
+ self._tasks.append(task_progression)
199
+ self._env_ids.append(
200
+ (
201
+ ID(task_progression.task_update.swarm_id).tid,
202
+ task_progression.task_id.tid,
203
+ )
204
+ )
205
+
206
+ def filter(
207
+ self, condition: Callable[[TaskProgression], bool]
208
+ ) -> Iterable[TaskProgression]:
209
+ """
210
+ Filter keys given the condition function
211
+
212
+ Parameters
213
+ ----------
214
+ condition : Callable[[TaskProgression], bool]
215
+ Condition function
216
+
217
+ Returns
218
+ -------
219
+ Iterable[TaskProgression]
220
+ Filtered keys
221
+ """
222
+ return filter(condition, self._tasks)
223
+
224
+ def pop(self, env_id: Tuple[TupleID, TupleID]) -> TaskProgression:
225
+ """
226
+ Pop a task progression given the task ID
227
+
228
+ Parameters
229
+ ----------
230
+ task_id : Tuple[TupleID, TupleID]
231
+ Task and Swarms IDs in a tuple
232
+
233
+ Returns
234
+ -------
235
+ TaskProgression
236
+ Task progression popped
237
+ """
238
+ if env_id not in self._env_ids:
239
+ raise KeyError(f"Cannot pop task due to {env_id} not found in tasks")
240
+ index = self._env_ids.index(env_id)
241
+ self._env_ids.pop(index)
242
+ return self._tasks.pop(index)
243
+
244
+ def active_tasks(self) -> Iterable[TaskProgression]:
245
+ """
246
+ Return an iterable of active tasks
247
+
248
+ Returns
249
+ -------
250
+ Iterable[TaskProgression]
251
+ Active task progressions
252
+ """
253
+ return (
254
+ task_progression
255
+ for task_progression in self._tasks
256
+ if task_progression.is_active_task()
257
+ )
258
+
259
+ def finished_tasks(self) -> Iterable[TaskProgression]:
260
+ """
261
+ Return an iterable of finished tasks
262
+
263
+ Returns
264
+ -------
265
+ Iterable[TaskProgression]
266
+ Finished task progressions
267
+ """
268
+ return (
269
+ task_progression
270
+ for task_progression in self._tasks
271
+ if task_progression.is_finished_task()
272
+ )
manta_node/utils.py ADDED
@@ -0,0 +1,52 @@
1
+ from pathlib import Path
2
+ from typing import List
3
+
4
+ from manta_common.build.common.informations import Overview
5
+
6
+ __all__ = ["collect_dataset_overviews"]
7
+
8
+ DTYPES = {
9
+ ".txt": "text",
10
+ ".csv": "csv",
11
+ ".npx": "numpy",
12
+ ".npy": "numpy",
13
+ ".npz": "numpy",
14
+ ".np": "numpy",
15
+ }
16
+
17
+
18
+ def collect_dataset_overviews(data_folder: Path) -> List[Overview]:
19
+ """
20
+ Collect dataset overviews including :
21
+
22
+ - name of a dataset
23
+ - its description
24
+ - its dtype (numpy, pytorch ...)
25
+
26
+ Parameters
27
+ ----------
28
+ data_folder: Path
29
+ Data folder
30
+
31
+ Returns
32
+ -------
33
+ List[Overview]
34
+ List of dataset overviews
35
+ """
36
+ overviews = []
37
+ # Check if the file exists in the data_folder
38
+ if not data_folder.exists():
39
+ # Create the data folder
40
+ data_folder.mkdir(exist_ok=True)
41
+ return overviews
42
+
43
+ # Get the list of files in the data_folder
44
+ overviews = [
45
+ Overview(
46
+ name=file.name,
47
+ description="No description available",
48
+ dtype=DTYPES.get(file.suffix, "binary") if file.is_file() else "folder",
49
+ )
50
+ for file in data_folder.iterdir()
51
+ ]
52
+ return overviews