mantatech-sdk 0.5b0.dev65__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 (54) hide show
  1. manta/__init__.light.py +22 -0
  2. manta/__init__.py +83 -0
  3. manta/__main__.py +21 -0
  4. manta/apis/__init__.py +7 -0
  5. manta/apis/async_user_api.py +6458 -0
  6. manta/apis/graph.py +498 -0
  7. manta/apis/module.py +316 -0
  8. manta/apis/results.py +251 -0
  9. manta/apis/swarm.py +206 -0
  10. manta/apis/user_api.py +1016 -0
  11. manta/cli/__init__.py +1 -0
  12. manta/cli/commands/__init__.py +1 -0
  13. manta/cli/commands/base_handler.py +229 -0
  14. manta/cli/commands/doc.py +192 -0
  15. manta/cli/commands/install.py +346 -0
  16. manta/cli/commands/sdk.py +9 -0
  17. manta/cli/commands/sdk_cluster.py +211 -0
  18. manta/cli/commands/sdk_config.py +347 -0
  19. manta/cli/commands/sdk_globals.py +280 -0
  20. manta/cli/commands/sdk_logs.py +174 -0
  21. manta/cli/commands/sdk_main.py +167 -0
  22. manta/cli/commands/sdk_module.py +516 -0
  23. manta/cli/commands/sdk_nodes.py +168 -0
  24. manta/cli/commands/sdk_original.py +3873 -0
  25. manta/cli/commands/sdk_results.py +265 -0
  26. manta/cli/commands/sdk_swarm.py +454 -0
  27. manta/cli/commands/sdk_user.py +234 -0
  28. manta/cli/commands/status.py +292 -0
  29. manta/cli/component_detector.py +112 -0
  30. manta/cli/config_manager.py +445 -0
  31. manta/cli/main.py +265 -0
  32. manta/cli/utils/__init__.py +27 -0
  33. manta/cli/utils/converters.py +140 -0
  34. manta/clients/cluster_management_client.py +486 -0
  35. manta/clients/local_client.py +149 -0
  36. manta/clients/module_management_client.py +217 -0
  37. manta/clients/swarm_management_client.py +562 -0
  38. manta/clients/user_management_client.py +395 -0
  39. manta/clients/world_client.py +195 -0
  40. manta/light/__init__.py +31 -0
  41. manta/light/globals.py +245 -0
  42. manta/light/local.py +407 -0
  43. manta/light/logging_config.py +39 -0
  44. manta/light/path.py +116 -0
  45. manta/light/results.py +236 -0
  46. manta/light/task.py +100 -0
  47. manta/light/utils.py +217 -0
  48. manta/light/world.py +177 -0
  49. mantatech_sdk-0.5b0.dev65.dist-info/METADATA +1039 -0
  50. mantatech_sdk-0.5b0.dev65.dist-info/RECORD +54 -0
  51. mantatech_sdk-0.5b0.dev65.dist-info/WHEEL +5 -0
  52. mantatech_sdk-0.5b0.dev65.dist-info/entry_points.txt +2 -0
  53. mantatech_sdk-0.5b0.dev65.dist-info/licenses/LICENSE +683 -0
  54. mantatech_sdk-0.5b0.dev65.dist-info/top_level.txt +1 -0
@@ -0,0 +1,27 @@
1
+ """CLI utility functions and helpers."""
2
+
3
+ from .converters import (
4
+ enum_to_string,
5
+ timestamp_to_string,
6
+ bytes_to_gb,
7
+ extract_platform_type,
8
+ extract_node_resources,
9
+ NODE_STATUS_MAP,
10
+ SWARM_STATUS_MAP,
11
+ CLUSTER_STATUS_MAP,
12
+ TASK_STATUS_MAP,
13
+ LOG_SEVERITY_MAP,
14
+ )
15
+
16
+ __all__ = [
17
+ "enum_to_string",
18
+ "timestamp_to_string",
19
+ "bytes_to_gb",
20
+ "extract_platform_type",
21
+ "extract_node_resources",
22
+ "NODE_STATUS_MAP",
23
+ "SWARM_STATUS_MAP",
24
+ "CLUSTER_STATUS_MAP",
25
+ "TASK_STATUS_MAP",
26
+ "LOG_SEVERITY_MAP",
27
+ ]
@@ -0,0 +1,140 @@
1
+ """Utility functions for CLI data conversion and formatting."""
2
+
3
+ from datetime import datetime
4
+ from typing import Any, Dict, Optional, Union
5
+
6
+
7
+ def enum_to_string(value: Union[int, str], enum_map: Dict[int, str]) -> str:
8
+ """Convert enum value to string representation.
9
+
10
+ Args:
11
+ value: Enum value (int) or string
12
+ enum_map: Dictionary mapping enum int values to string names
13
+
14
+ Returns:
15
+ String representation of the enum value
16
+ """
17
+ if isinstance(value, int):
18
+ return enum_map.get(value, "UNKNOWN")
19
+ return str(value)
20
+
21
+
22
+ def timestamp_to_string(
23
+ timestamp: Union[Dict[str, Any], str, int, float, None],
24
+ format: str = "%Y-%m-%d %H:%M:%S",
25
+ ) -> str:
26
+ """Convert various timestamp formats to string.
27
+
28
+ Args:
29
+ timestamp: Timestamp in various formats (dict with seconds, string, int/float, or None)
30
+ format: Output format string
31
+
32
+ Returns:
33
+ Formatted timestamp string or 'Unknown' if invalid
34
+ """
35
+ if not timestamp:
36
+ return "Unknown"
37
+
38
+ if isinstance(timestamp, dict):
39
+ if "seconds" in timestamp:
40
+ return datetime.fromtimestamp(timestamp["seconds"]).strftime(format)
41
+ elif isinstance(timestamp, str):
42
+ return timestamp
43
+ elif isinstance(timestamp, (int, float)):
44
+ return datetime.fromtimestamp(timestamp).strftime(format)
45
+
46
+ return "Unknown"
47
+
48
+
49
+ def bytes_to_gb(bytes_value: Union[int, float, None]) -> float:
50
+ """Convert bytes to gigabytes.
51
+
52
+ Args:
53
+ bytes_value: Value in bytes
54
+
55
+ Returns:
56
+ Value in GB rounded to 2 decimal places
57
+ """
58
+ if bytes_value is None:
59
+ return 0.0
60
+ return round(bytes_value / (1024**3), 2)
61
+
62
+
63
+ def extract_platform_type(platform_info: Optional[Dict[str, Any]]) -> str:
64
+ """Extract platform type from platform_info structure.
65
+
66
+ Args:
67
+ platform_info: Platform information dictionary
68
+
69
+ Returns:
70
+ Platform/OS type string
71
+ """
72
+ if not platform_info:
73
+ return "Unknown"
74
+
75
+ # Try different possible field names
76
+ for field in ["system", "platform", "os"]:
77
+ if field in platform_info:
78
+ return platform_info[field]
79
+
80
+ return "Unknown"
81
+
82
+
83
+ def extract_node_resources(
84
+ metrics_snapshot: Optional[Dict[str, Any]],
85
+ ) -> Dict[str, Any]:
86
+ """Extract resource information from metrics snapshot.
87
+
88
+ Args:
89
+ metrics_snapshot: Metrics snapshot dictionary
90
+
91
+ Returns:
92
+ Dictionary with cpu_count and memory_gb
93
+ """
94
+ resources = {"cpu_count": "Unknown", "memory_gb": "Unknown"}
95
+
96
+ if not metrics_snapshot:
97
+ return resources
98
+
99
+ # Extract CPU info
100
+ if "cpu" in metrics_snapshot and metrics_snapshot["cpu"]:
101
+ cpu_info = metrics_snapshot["cpu"]
102
+ if "count" in cpu_info:
103
+ resources["cpu_count"] = cpu_info["count"]
104
+ elif "cores" in cpu_info:
105
+ resources["cpu_count"] = cpu_info["cores"]
106
+
107
+ # Extract memory info
108
+ if "memory" in metrics_snapshot and metrics_snapshot["memory"]:
109
+ memory_info = metrics_snapshot["memory"]
110
+ if "total_bytes" in memory_info:
111
+ resources["memory_gb"] = bytes_to_gb(memory_info["total_bytes"])
112
+ elif "total" in memory_info:
113
+ resources["memory_gb"] = bytes_to_gb(memory_info["total"])
114
+
115
+ return resources
116
+
117
+
118
+ # Enum mappings for various status fields
119
+ NODE_STATUS_MAP = {0: "UNKNOWN", 1: "CONNECTED", 2: "DISCONNECTED"}
120
+
121
+ SWARM_STATUS_MAP = {
122
+ 0: "PENDING",
123
+ 1: "ACTIVE",
124
+ 2: "PAUSED",
125
+ 3: "STOPPED",
126
+ 4: "COMPLETED",
127
+ 5: "FAILED",
128
+ }
129
+
130
+ CLUSTER_STATUS_MAP = {0: "CREATED", 1: "RUNNING", 2: "STOPPED", 3: "ERROR"}
131
+
132
+ TASK_STATUS_MAP = {
133
+ 0: "PENDING",
134
+ 1: "RUNNING",
135
+ 2: "COMPLETED",
136
+ 3: "FAILED",
137
+ 4: "CANCELLED",
138
+ }
139
+
140
+ LOG_SEVERITY_MAP = {0: "DEBUG", 1: "INFO", 2: "WARNING", 3: "ERROR", 4: "CRITICAL"}
@@ -0,0 +1,486 @@
1
+ """
2
+ Cluster Management Client implementation.
3
+
4
+ This module provides the ClusterManagementClient class for interacting with the ClusterManagement service.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from datetime import datetime
10
+ from logging import Logger
11
+ from pathlib import Path
12
+ from typing import Any, AsyncIterator, Dict, Optional, Type, TypeVar
13
+
14
+ from manta_common.base_client import GrpcClientBase, MetadataDict
15
+ from manta_common.build.common.cluster import Cluster
16
+ from manta_common.build.common.informations import MetricsSnapshot, Node
17
+ from manta_common.build.common.system import (
18
+ CollectionIds,
19
+ Empty,
20
+ Error,
21
+ Response,
22
+ StrId,
23
+ )
24
+ from manta_common.build.core.user_services import ( # Request/Response messages; Service stub
25
+ ClusterManagementStub,
26
+ CreateClusterRequest,
27
+ ErrorsRequest,
28
+ NodeRequest,
29
+ TaskResponse,
30
+ )
31
+ from manta_common.retry import RetryPolicy
32
+
33
+ T = TypeVar("T")
34
+
35
+
36
+ class ClusterManagementClient(GrpcClientBase):
37
+ """
38
+ Client for interacting with the ClusterManagement Service.
39
+
40
+ This client provides a high-level interface for making gRPC calls to the ClusterManagement service,
41
+ handling cluster lifecycle and node management operations.
42
+ """
43
+
44
+ __slots__ = ("_secure", "cafile", "certfile", "keyfile")
45
+
46
+ def __init__(
47
+ self,
48
+ host: str,
49
+ port: int,
50
+ jwt_token: str,
51
+ secure: bool = False,
52
+ cafile: Optional[str] = None,
53
+ certfile: Optional[str] = None,
54
+ keyfile: Optional[str] = None,
55
+ channel_options: Optional[Dict[str, Any]] = None,
56
+ logger: Optional[Logger] = None,
57
+ retry_policy: Optional[RetryPolicy] = None,
58
+ streaming_retry_policy: Optional[RetryPolicy] = None,
59
+ ):
60
+ """
61
+ Initialize the ClusterManagementClient.
62
+
63
+ Parameters
64
+ ----------
65
+ host : str
66
+ The host of the ClusterManagement service
67
+ port : int
68
+ The port of the ClusterManagement service
69
+ jwt_token : str
70
+ JWT token for authentication
71
+ secure : bool
72
+ Whether to use a secure connection
73
+ cafile : Optional[str]
74
+ Path to the CA certificate file for verifying the server
75
+ certfile : Optional[str]
76
+ Path to the client certificate file
77
+ keyfile : Optional[str]
78
+ Path to the client private key file
79
+ channel_options : Optional[Dict[str, Any]]
80
+ The channel options
81
+ logger : Optional[Logger]
82
+ The logger
83
+ retry_policy : Optional[RetryPolicy]
84
+ The retry policy
85
+ streaming_retry_policy : Optional[RetryPolicy]
86
+ The streaming retry policy
87
+ """
88
+ super().__init__(
89
+ host=host,
90
+ port=port,
91
+ secure=secure,
92
+ channel_options=channel_options,
93
+ tracer=logger,
94
+ retry_policy=retry_policy,
95
+ streaming_retry_policy=streaming_retry_policy,
96
+ )
97
+ self.jwt_token = jwt_token
98
+ self._secure = secure
99
+ self.cafile = Path(cafile) if cafile is not None else None
100
+ self.certfile = Path(certfile) if certfile is not None else None
101
+ self.keyfile = Path(keyfile) if keyfile is not None else None
102
+
103
+ def _get_stub_class(self) -> Type[ClusterManagementStub]:
104
+ """Get the stub class for the ClusterManagement service."""
105
+ return ClusterManagementStub
106
+
107
+ @property
108
+ def metadata(self) -> MetadataDict:
109
+ return {"authorization": self.jwt_token}
110
+
111
+ async def is_available(self) -> Response:
112
+ """
113
+ Check if the ClusterManagement service is available.
114
+
115
+ Returns
116
+ -------
117
+ Response
118
+ Service availability status
119
+ """
120
+ return await self.call_service_method(
121
+ "is_available",
122
+ Empty(),
123
+ )
124
+
125
+ async def create_cluster(self, name: Optional[str] = None) -> StrId:
126
+ """
127
+ Create a new cluster.
128
+
129
+ Parameters
130
+ ----------
131
+ name : Optional[str]
132
+ Name for the cluster
133
+
134
+ Returns
135
+ -------
136
+ StrId
137
+ Cluster ID
138
+ """
139
+ request = CreateClusterRequest()
140
+ if name:
141
+ request.name = name
142
+ return await self.call_service_method(
143
+ "create_cluster",
144
+ request,
145
+ )
146
+
147
+ async def start_cluster(self, cluster_id: str) -> Cluster:
148
+ """
149
+ Start cluster services.
150
+
151
+ Parameters
152
+ ----------
153
+ cluster_id : str
154
+ ID of the cluster to start
155
+
156
+ Returns
157
+ -------
158
+ Cluster
159
+ Cluster details
160
+ """
161
+ return await self.call_service_method(
162
+ "start_cluster",
163
+ StrId(id=cluster_id),
164
+ )
165
+
166
+ async def stop_cluster(self, cluster_id: str) -> Response:
167
+ """
168
+ Stop cluster services.
169
+
170
+ Parameters
171
+ ----------
172
+ cluster_id : str
173
+ ID of the cluster to stop
174
+
175
+ Returns
176
+ -------
177
+ Response
178
+ Stop operation response
179
+ """
180
+ return await self.call_service_method(
181
+ "stop_cluster",
182
+ StrId(id=cluster_id),
183
+ )
184
+
185
+ async def delete_cluster(self, cluster_id: str) -> Response:
186
+ """
187
+ Delete a cluster.
188
+
189
+ Parameters
190
+ ----------
191
+ cluster_id : str
192
+ ID of the cluster to delete
193
+
194
+ Returns
195
+ -------
196
+ Response
197
+ Deletion confirmation response
198
+ """
199
+ return await self.call_service_method(
200
+ "delete_cluster",
201
+ StrId(id=cluster_id),
202
+ )
203
+
204
+ async def list_cluster_ids(self) -> CollectionIds:
205
+ """
206
+ List all cluster IDs for the authenticated user.
207
+
208
+ Returns
209
+ -------
210
+ CollectionIds
211
+ Collection of cluster IDs
212
+ """
213
+ return await self.call_service_method(
214
+ "list_cluster_ids",
215
+ Empty(),
216
+ )
217
+
218
+ async def stream_clusters(self) -> AsyncIterator[Cluster]:
219
+ """
220
+ Stream all clusters for the authenticated user.
221
+
222
+ Yields
223
+ ------
224
+ Cluster
225
+ Cluster details
226
+ """
227
+ async for cluster in self.stream_service_method(
228
+ "stream_clusters",
229
+ Empty(),
230
+ ):
231
+ yield cluster
232
+
233
+ async def get_cluster(self, cluster_id: str) -> Cluster:
234
+ """
235
+ Get a cluster by its ID.
236
+
237
+ Parameters
238
+ ----------
239
+ cluster_id : str
240
+ ID of the cluster
241
+
242
+ Returns
243
+ -------
244
+ Cluster
245
+ Cluster details
246
+ """
247
+ return await self.call_service_method(
248
+ "get_cluster",
249
+ StrId(id=cluster_id),
250
+ )
251
+
252
+ async def list_node_ids(self, cluster_id: str) -> CollectionIds:
253
+ """
254
+ List node IDs in a cluster.
255
+
256
+ Parameters
257
+ ----------
258
+ cluster_id : str
259
+ ID of the cluster
260
+
261
+ Returns
262
+ -------
263
+ CollectionIds
264
+ Collection of node IDs
265
+ """
266
+ return await self.call_service_method(
267
+ "list_node_ids",
268
+ StrId(id=cluster_id),
269
+ )
270
+
271
+ async def stream_nodes(self, cluster_id: str) -> AsyncIterator[Node]:
272
+ """
273
+ Stream all nodes in a cluster.
274
+
275
+ Parameters
276
+ ----------
277
+ cluster_id : str
278
+ ID of the cluster
279
+
280
+ Yields
281
+ ------
282
+ Node
283
+ Node information
284
+ """
285
+ async for node in self.stream_service_method(
286
+ "stream_nodes",
287
+ StrId(id=cluster_id),
288
+ ):
289
+ yield node
290
+
291
+ async def stop_node(self, cluster_id: str, node_id: str) -> Response:
292
+ """
293
+ Stop a specific node.
294
+
295
+ Parameters
296
+ ----------
297
+ cluster_id : str
298
+ ID of the cluster
299
+ node_id : str
300
+ ID of the node to stop
301
+
302
+ Returns
303
+ -------
304
+ Response
305
+ Stop operation response
306
+ """
307
+ return await self.call_service_method(
308
+ "stop_node",
309
+ NodeRequest(cluster_id=cluster_id, node_id=node_id),
310
+ )
311
+
312
+ async def remove_node(self, cluster_id: str, node_id: str) -> Response:
313
+ """
314
+ Remove a node from the cluster.
315
+
316
+ Parameters
317
+ ----------
318
+ cluster_id : str
319
+ ID of the cluster
320
+ node_id : str
321
+ ID of the node to remove
322
+
323
+ Returns
324
+ -------
325
+ Response
326
+ Removal confirmation response
327
+ """
328
+ return await self.call_service_method(
329
+ "remove_node",
330
+ NodeRequest(cluster_id=cluster_id, node_id=node_id),
331
+ )
332
+
333
+ async def get_node(self, cluster_id: str, node_id: str) -> Node:
334
+ """
335
+ Get a node by its ID.
336
+
337
+ Parameters
338
+ ----------
339
+ cluster_id : str
340
+ ID of the cluster
341
+ node_id : str
342
+ ID of the node
343
+
344
+ Returns
345
+ -------
346
+ Node
347
+ Node information
348
+ """
349
+ return await self.call_service_method(
350
+ "get_node",
351
+ NodeRequest(cluster_id=cluster_id, node_id=node_id),
352
+ )
353
+
354
+ async def get_node_resources(
355
+ self, cluster_id: str, node_id: str
356
+ ) -> MetricsSnapshot:
357
+ """
358
+ Get node resources for a specific node.
359
+
360
+ Parameters
361
+ ----------
362
+ cluster_id : str
363
+ ID of the cluster
364
+ node_id : str
365
+ ID of the node
366
+
367
+ Returns
368
+ -------
369
+ MetricsSnapshot
370
+ Node resource metrics
371
+ """
372
+ return await self.call_service_method(
373
+ "get_node_resources",
374
+ NodeRequest(cluster_id=cluster_id, node_id=node_id),
375
+ )
376
+
377
+ async def stream_node_resources(
378
+ self, cluster_id: str, node_id: str
379
+ ) -> AsyncIterator[MetricsSnapshot]:
380
+ """
381
+ Stream node resources for a specific node.
382
+
383
+ Parameters
384
+ ----------
385
+ cluster_id : str
386
+ ID of the cluster
387
+ node_id : str
388
+ ID of the node
389
+
390
+ Yields
391
+ ------
392
+ MetricsSnapshot
393
+ Stream of node resource metrics
394
+ """
395
+ async for resource in self.stream_service_method(
396
+ "stream_node_resources",
397
+ NodeRequest(cluster_id=cluster_id, node_id=node_id),
398
+ ):
399
+ yield resource
400
+
401
+ async def list_available_node_ids(self, cluster_id: str) -> CollectionIds:
402
+ """
403
+ List available node IDs in a cluster.
404
+
405
+ Parameters
406
+ ----------
407
+ cluster_id : str
408
+ ID of the cluster
409
+
410
+ Returns
411
+ -------
412
+ CollectionIds
413
+ Collection of available node IDs
414
+ """
415
+ return await self.call_service_method(
416
+ "list_available_node_ids",
417
+ StrId(id=cluster_id),
418
+ )
419
+
420
+ async def collect_errors(
421
+ self,
422
+ cluster_id: str,
423
+ start_time: Optional[datetime] = None,
424
+ end_time: Optional[datetime] = None,
425
+ limit: Optional[int] = None,
426
+ sort_order: Optional[str] = None,
427
+ ) -> AsyncIterator[Error]:
428
+ """
429
+ Collect errors from a cluster.
430
+
431
+ Parameters
432
+ ----------
433
+ cluster_id : str
434
+ ID of the cluster
435
+ start_time : Optional[datetime]
436
+ Start time for filtering errors
437
+ end_time : Optional[datetime]
438
+ End time for filtering errors
439
+ limit : Optional[int]
440
+ Maximum number of errors to return
441
+ sort_order : Optional[str]
442
+ Sort order for results
443
+
444
+ Yields
445
+ ------
446
+ Error
447
+ Stream of errors
448
+ """
449
+ request = ErrorsRequest(cluster_id=cluster_id)
450
+ if start_time:
451
+ request.start_time = start_time
452
+ if end_time:
453
+ request.end_time = end_time
454
+ if limit:
455
+ request.limit = limit
456
+ if sort_order:
457
+ request.sort_order = sort_order
458
+ async for error in self.stream_service_method(
459
+ "collect_errors",
460
+ request,
461
+ ):
462
+ yield error
463
+
464
+ async def select_tasks(
465
+ self, cluster_id: str, node_id: str
466
+ ) -> AsyncIterator[TaskResponse]:
467
+ """
468
+ Select tasks for a specific node.
469
+
470
+ Parameters
471
+ ----------
472
+ cluster_id : str
473
+ ID of the cluster
474
+ node_id : str
475
+ ID of the node
476
+
477
+ Yields
478
+ ------
479
+ TaskResponse
480
+ Stream of task information
481
+ """
482
+ async for task in self.stream_service_method(
483
+ "select_tasks",
484
+ NodeRequest(cluster_id=cluster_id, node_id=node_id),
485
+ ):
486
+ yield task