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.
- manta/__init__.light.py +22 -0
- manta/__init__.py +83 -0
- manta/__main__.py +21 -0
- manta/apis/__init__.py +7 -0
- manta/apis/async_user_api.py +6458 -0
- manta/apis/graph.py +498 -0
- manta/apis/module.py +316 -0
- manta/apis/results.py +251 -0
- manta/apis/swarm.py +206 -0
- manta/apis/user_api.py +1016 -0
- manta/cli/__init__.py +1 -0
- manta/cli/commands/__init__.py +1 -0
- manta/cli/commands/base_handler.py +229 -0
- manta/cli/commands/doc.py +192 -0
- manta/cli/commands/install.py +346 -0
- manta/cli/commands/sdk.py +9 -0
- manta/cli/commands/sdk_cluster.py +211 -0
- manta/cli/commands/sdk_config.py +347 -0
- manta/cli/commands/sdk_globals.py +280 -0
- manta/cli/commands/sdk_logs.py +174 -0
- manta/cli/commands/sdk_main.py +167 -0
- manta/cli/commands/sdk_module.py +516 -0
- manta/cli/commands/sdk_nodes.py +168 -0
- manta/cli/commands/sdk_original.py +3873 -0
- manta/cli/commands/sdk_results.py +265 -0
- manta/cli/commands/sdk_swarm.py +454 -0
- manta/cli/commands/sdk_user.py +234 -0
- manta/cli/commands/status.py +292 -0
- manta/cli/component_detector.py +112 -0
- manta/cli/config_manager.py +445 -0
- manta/cli/main.py +265 -0
- manta/cli/utils/__init__.py +27 -0
- manta/cli/utils/converters.py +140 -0
- manta/clients/cluster_management_client.py +486 -0
- manta/clients/local_client.py +149 -0
- manta/clients/module_management_client.py +217 -0
- manta/clients/swarm_management_client.py +562 -0
- manta/clients/user_management_client.py +395 -0
- manta/clients/world_client.py +195 -0
- manta/light/__init__.py +31 -0
- manta/light/globals.py +245 -0
- manta/light/local.py +407 -0
- manta/light/logging_config.py +39 -0
- manta/light/path.py +116 -0
- manta/light/results.py +236 -0
- manta/light/task.py +100 -0
- manta/light/utils.py +217 -0
- manta/light/world.py +177 -0
- mantatech_sdk-0.5b0.dev65.dist-info/METADATA +1039 -0
- mantatech_sdk-0.5b0.dev65.dist-info/RECORD +54 -0
- mantatech_sdk-0.5b0.dev65.dist-info/WHEEL +5 -0
- mantatech_sdk-0.5b0.dev65.dist-info/entry_points.txt +2 -0
- mantatech_sdk-0.5b0.dev65.dist-info/licenses/LICENSE +683 -0
- mantatech_sdk-0.5b0.dev65.dist-info/top_level.txt +1 -0
manta/light/globals.py
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import AsyncIterable, Optional
|
|
5
|
+
|
|
6
|
+
import grpclib.exceptions
|
|
7
|
+
|
|
8
|
+
from ..clients.world_client import WorldClient
|
|
9
|
+
from manta_common.build.node.light_service import GetGlobalRequest, SetGlobalRequest
|
|
10
|
+
from manta_common.const import CHUNK_SIZE
|
|
11
|
+
from manta_common.conversions import ID
|
|
12
|
+
from manta_common.event_loop import EventLoopManager
|
|
13
|
+
from .utils import bytes_to_dict, dict_to_bytes
|
|
14
|
+
|
|
15
|
+
__all__ = ["Globals"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Globals:
|
|
19
|
+
"""
|
|
20
|
+
Class which deals with global manipulation (getter and setter)
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
host : str
|
|
25
|
+
Manager host
|
|
26
|
+
port : int
|
|
27
|
+
Manager port
|
|
28
|
+
task_id : ID
|
|
29
|
+
Task ID
|
|
30
|
+
swarm_id : ID
|
|
31
|
+
Swarm ID
|
|
32
|
+
chunk_size : int
|
|
33
|
+
Chunk size
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
__slots__ = [
|
|
37
|
+
"world_client",
|
|
38
|
+
"swarm_id",
|
|
39
|
+
"task_id",
|
|
40
|
+
"logger",
|
|
41
|
+
"chunk_size",
|
|
42
|
+
"_loop",
|
|
43
|
+
"_loop_lock",
|
|
44
|
+
"loop_manager",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
world_client: Optional[WorldClient] = None,
|
|
50
|
+
host: Optional[str] = None,
|
|
51
|
+
port: Optional[int] = None,
|
|
52
|
+
swarm_id: Optional[ID] = None,
|
|
53
|
+
task_id: Optional[ID] = None,
|
|
54
|
+
chunk_size: int = CHUNK_SIZE,
|
|
55
|
+
):
|
|
56
|
+
# Retrieve env variables for RPC host and port
|
|
57
|
+
if world_client is None:
|
|
58
|
+
self.world_client = WorldClient(
|
|
59
|
+
host=host or os.getenv("RPC_HOST", "host.docker.internal"),
|
|
60
|
+
port=int(port or os.getenv("RPC_PORT", 50051)),
|
|
61
|
+
)
|
|
62
|
+
else:
|
|
63
|
+
self.world_client = world_client
|
|
64
|
+
|
|
65
|
+
self.task_id: ID = task_id or ID(os.getenv("TASK_ID"))
|
|
66
|
+
self.swarm_id: ID = swarm_id or ID(os.getenv("SWARM_ID"))
|
|
67
|
+
|
|
68
|
+
self.chunk_size = chunk_size
|
|
69
|
+
|
|
70
|
+
self.logger = logging.getLogger(__name__)
|
|
71
|
+
|
|
72
|
+
self.loop_manager = EventLoopManager.get_instance()
|
|
73
|
+
|
|
74
|
+
def __getitem__(self, tag: str):
|
|
75
|
+
"""
|
|
76
|
+
Get the results of a Task
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
tag : str
|
|
81
|
+
The tag of the result to get
|
|
82
|
+
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
dict
|
|
86
|
+
The response from the world service
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
|
|
91
|
+
Inside a :class:`Task <manta_light.task.Task>` class, you can
|
|
92
|
+
access globals defined by a :class:`Swarm <manta.swarm.Swarm>`
|
|
93
|
+
by using the attribute :code:`self.world` automatically defined
|
|
94
|
+
by :class:`Task <manta_light.task.Task>`:
|
|
95
|
+
|
|
96
|
+
>>> weights = self.world.globals["global_model_params"]
|
|
97
|
+
"""
|
|
98
|
+
return self.loop_manager.run_coroutine(self.async_get(tag))
|
|
99
|
+
|
|
100
|
+
def __setitem__(self, tag: str, result: dict):
|
|
101
|
+
"""
|
|
102
|
+
Set a result of a task
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
tag : str
|
|
107
|
+
The tag of the result to set
|
|
108
|
+
result : dict
|
|
109
|
+
The result to set
|
|
110
|
+
|
|
111
|
+
Examples
|
|
112
|
+
--------
|
|
113
|
+
|
|
114
|
+
Inside a :class:`Task <manta_light.task.Task>` class, you can
|
|
115
|
+
change globals defined by a :class:`Swarm <manta.swarm.Swarm>`
|
|
116
|
+
by using the attribute :code:`self.world` automatically defined
|
|
117
|
+
by :class:`Task <manta_light.task.Task>`:
|
|
118
|
+
|
|
119
|
+
>>> self.world.globals["global_model_params"] = new_weights
|
|
120
|
+
"""
|
|
121
|
+
self.loop_manager.run_coroutine(self.async_set(tag, result))
|
|
122
|
+
|
|
123
|
+
def __str__(self): # pragma: no cover
|
|
124
|
+
return f"Globals(host={self.world_client.host}, port={self.world_client.port}, swarm_id={self.swarm_id}, task_id={self.task_id})"
|
|
125
|
+
|
|
126
|
+
def __repr__(self): # pragma: no cover
|
|
127
|
+
return str(self)
|
|
128
|
+
|
|
129
|
+
# Asynchonous methods
|
|
130
|
+
|
|
131
|
+
async def async_get(self, tag: str):
|
|
132
|
+
"""
|
|
133
|
+
Get the results of tasks
|
|
134
|
+
|
|
135
|
+
Parameters
|
|
136
|
+
----------
|
|
137
|
+
tag : str
|
|
138
|
+
The tag of the result to get
|
|
139
|
+
|
|
140
|
+
Returns
|
|
141
|
+
-------
|
|
142
|
+
dict
|
|
143
|
+
The response from the world service
|
|
144
|
+
|
|
145
|
+
Examples
|
|
146
|
+
--------
|
|
147
|
+
|
|
148
|
+
Same as :meth:`__getitem__ <manta_light.globals.Globals.__getitem__>`
|
|
149
|
+
but asynchronous.
|
|
150
|
+
|
|
151
|
+
>>> weights = await self.world.globals.async_get(
|
|
152
|
+
... "global_model_params"
|
|
153
|
+
... )
|
|
154
|
+
"""
|
|
155
|
+
# Initialize a buffer to accumulate chunks
|
|
156
|
+
buffer = io.BytesIO()
|
|
157
|
+
|
|
158
|
+
self.logger.info(
|
|
159
|
+
f"Getting global '{tag}' for task {self.task_id} and swarm {self.swarm_id}"
|
|
160
|
+
)
|
|
161
|
+
try:
|
|
162
|
+
# Iterate over the chunks
|
|
163
|
+
async for chunk in self.world_client.get_global(
|
|
164
|
+
GetGlobalRequest(
|
|
165
|
+
task_id=self.task_id.oid, swarm_id=self.swarm_id.oid, tag=tag
|
|
166
|
+
)
|
|
167
|
+
):
|
|
168
|
+
self.logger.debug(
|
|
169
|
+
f"Received chunk for global '{tag}' of size {len(chunk.data)}"
|
|
170
|
+
)
|
|
171
|
+
# Append the chunk to the buffer
|
|
172
|
+
buffer.write(chunk.data)
|
|
173
|
+
|
|
174
|
+
self.logger.info(f"Successfully received all chunks for global '{tag}'")
|
|
175
|
+
return bytes_to_dict(buffer.getvalue())
|
|
176
|
+
except grpclib.exceptions.GRPCError as e:
|
|
177
|
+
self.logger.error(
|
|
178
|
+
f"GRPC error while getting global '{tag}': {e!r}", exc_info=True
|
|
179
|
+
)
|
|
180
|
+
raise # Re-raise the original gRPC error
|
|
181
|
+
except Exception as e:
|
|
182
|
+
# This catches other potential errors, e.g., from bytes_to_dict if the stream was successful
|
|
183
|
+
# but data was malformed, or other unexpected errors within this block.
|
|
184
|
+
self.logger.error(
|
|
185
|
+
f"Failed to process global '{tag}' after fetching: {e!r}", exc_info=True
|
|
186
|
+
)
|
|
187
|
+
raise
|
|
188
|
+
|
|
189
|
+
async def chunked_global_update(
|
|
190
|
+
self, request: SetGlobalRequest
|
|
191
|
+
) -> AsyncIterable[SetGlobalRequest]:
|
|
192
|
+
"""
|
|
193
|
+
This function chunks the data into smaller pieces and yields GlobalUpdate messages.
|
|
194
|
+
|
|
195
|
+
Parameters
|
|
196
|
+
----------
|
|
197
|
+
request : SetGlobalRequest
|
|
198
|
+
Set global request
|
|
199
|
+
|
|
200
|
+
Returns
|
|
201
|
+
-------
|
|
202
|
+
AsyncIterable[SetGlobalRequest]
|
|
203
|
+
Async iterable of SetGlobalRequest messages
|
|
204
|
+
"""
|
|
205
|
+
data_stream = io.BytesIO(request.data)
|
|
206
|
+
while chunk := data_stream.read(self.chunk_size):
|
|
207
|
+
yield SetGlobalRequest(
|
|
208
|
+
task_id=request.task_id,
|
|
209
|
+
swarm_id=request.swarm_id,
|
|
210
|
+
tag=request.tag,
|
|
211
|
+
data=chunk,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
async def async_set(self, tag: str, result: dict):
|
|
215
|
+
"""
|
|
216
|
+
Set a result of a task
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
tag : str
|
|
221
|
+
The tag of the result to set
|
|
222
|
+
result : dict
|
|
223
|
+
The result to set
|
|
224
|
+
|
|
225
|
+
Examples
|
|
226
|
+
--------
|
|
227
|
+
|
|
228
|
+
Same as :meth:`__setitem__ <manta_light.globals.Globals.__setitem__>`
|
|
229
|
+
but asynchronous.
|
|
230
|
+
|
|
231
|
+
>>> await self.world.globals.async_set(
|
|
232
|
+
... "global_model_params",
|
|
233
|
+
... new_weights
|
|
234
|
+
... )
|
|
235
|
+
"""
|
|
236
|
+
await self.world_client.set_global(
|
|
237
|
+
self.chunked_global_update(
|
|
238
|
+
SetGlobalRequest(
|
|
239
|
+
task_id=self.task_id.oid,
|
|
240
|
+
swarm_id=self.swarm_id.oid,
|
|
241
|
+
tag=tag,
|
|
242
|
+
data=dict_to_bytes(result),
|
|
243
|
+
)
|
|
244
|
+
)
|
|
245
|
+
)
|
manta/light/local.py
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Union
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
import numpy
|
|
8
|
+
|
|
9
|
+
from ..clients.local_client import LocalClient
|
|
10
|
+
from manta_common.build.node.light_service import (
|
|
11
|
+
DataRequest,
|
|
12
|
+
DirRequest,
|
|
13
|
+
ListDirResponse,
|
|
14
|
+
ProtoPath,
|
|
15
|
+
ReadText,
|
|
16
|
+
)
|
|
17
|
+
from manta_common.conversions import ID
|
|
18
|
+
from manta_common.event_loop import EventLoopManager
|
|
19
|
+
from .logging_config import configure_logging
|
|
20
|
+
|
|
21
|
+
__all__ = ["Local"]
|
|
22
|
+
|
|
23
|
+
configure_logging()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Local:
|
|
27
|
+
"""
|
|
28
|
+
Local service for accessing local data securely
|
|
29
|
+
|
|
30
|
+
The :code:`Local` service allows the user to get local data.
|
|
31
|
+
|
|
32
|
+
Parameters should not be fulfill manually. Instead, it is managed during the
|
|
33
|
+
deployment of the task by the :code:`Node`.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
host : Optional[str]
|
|
38
|
+
Manager host
|
|
39
|
+
port : Optional[int]
|
|
40
|
+
Manager port
|
|
41
|
+
swarm_id : Optional[ID]
|
|
42
|
+
Swarm ID
|
|
43
|
+
task_id : Optional[ID]
|
|
44
|
+
Task ID
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
__slots__ = ["swarm_id", "task_id", "logger", "local_client", "loop_manager"]
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
host: Optional[str] = None,
|
|
52
|
+
port: Optional[int] = None,
|
|
53
|
+
swarm_id: Optional[ID] = None,
|
|
54
|
+
task_id: Optional[ID] = None,
|
|
55
|
+
):
|
|
56
|
+
# Retrieve env variables for RPC host and port
|
|
57
|
+
self.task_id: ID = task_id or ID(os.getenv("TASK_ID"))
|
|
58
|
+
self.swarm_id: ID = swarm_id or ID(os.getenv("SWARM_ID"))
|
|
59
|
+
|
|
60
|
+
self.loop_manager = EventLoopManager.get_instance()
|
|
61
|
+
self.local_client = LocalClient(
|
|
62
|
+
host=host or os.getenv("RPC_HOST", "host.docker.internal"),
|
|
63
|
+
port=int(port or os.getenv("RPC_PORT", 50051)),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
self.logger = logging.getLogger(__name__)
|
|
67
|
+
|
|
68
|
+
self.logger.info(
|
|
69
|
+
f"Local configured with Host: {self.local_client.host}, Port: {self.local_client.port},"
|
|
70
|
+
f" Task ID: {self.task_id.xid},"
|
|
71
|
+
f" Swarm ID: {self.swarm_id.xid}"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def get_numpy_data(self, dataset_name: Union[str, ProtoPath]) -> "numpy.ndarray": # type: ignore
|
|
75
|
+
"""
|
|
76
|
+
Get the numpy data
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
dataset_name : Union[str, ProtoPath]
|
|
81
|
+
The name of the dataset to get
|
|
82
|
+
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
numpy.ndarray
|
|
86
|
+
The numpy data
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
|
|
91
|
+
Inside a :class:`Task <manta_light.task.Task>` class, you can
|
|
92
|
+
access to local data by using the attribute :code:`self.local`
|
|
93
|
+
automatically created by :class:`Task <manta_light.task.Task>`:
|
|
94
|
+
|
|
95
|
+
>>> mnist_data = self.local.get_numpy_data("mnist.npz")
|
|
96
|
+
"""
|
|
97
|
+
return self.loop_manager.run_coroutine(self.async_get_numpy_data(dataset_name))
|
|
98
|
+
|
|
99
|
+
def get_binary_data(self, dataset_name: Union[str, ProtoPath]) -> io.BytesIO:
|
|
100
|
+
"""
|
|
101
|
+
Get the binary data
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
dataset_name : Union[str, ProtoPath]
|
|
106
|
+
The name of the dataset to get
|
|
107
|
+
|
|
108
|
+
Returns
|
|
109
|
+
-------
|
|
110
|
+
io.BytesIO
|
|
111
|
+
The binary data
|
|
112
|
+
|
|
113
|
+
Examples
|
|
114
|
+
--------
|
|
115
|
+
|
|
116
|
+
Inside a :class:`Task <manta_light.task.Task>` class, you can
|
|
117
|
+
access to local data by using the attribute :code:`self.local`
|
|
118
|
+
automatically created by :class:`Task <manta_light.task.Task>`:
|
|
119
|
+
|
|
120
|
+
>>> mnist_data = self.local.get_binary_data("mnist.npz")
|
|
121
|
+
>>> data = np.load(mnist_data)
|
|
122
|
+
"""
|
|
123
|
+
return self.loop_manager.run_coroutine(self.async_get_binary_data(dataset_name))
|
|
124
|
+
|
|
125
|
+
def list_dir(self, directory: Union[str, ProtoPath]) -> ListDirResponse:
|
|
126
|
+
"""
|
|
127
|
+
List directories
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
directory : Union[str, ProtoPath]
|
|
132
|
+
Directory name
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
ListDirResponse
|
|
137
|
+
List of directories
|
|
138
|
+
|
|
139
|
+
Examples
|
|
140
|
+
--------
|
|
141
|
+
|
|
142
|
+
Inside a :class:`Task <manta_light.task.Task>` class, you can
|
|
143
|
+
access to local data by using the attribute :code:`self.local`
|
|
144
|
+
automatically created by :class:`Task <manta_light.task.Task>`:
|
|
145
|
+
|
|
146
|
+
>>> images = self.local.list_dir("images")
|
|
147
|
+
>>> print(images)
|
|
148
|
+
>>> ListDirResponse(
|
|
149
|
+
>>> paths=[ProtoPath("image1.jpg", is_file=True), ProtoPath("image2.jpg", is_file=True)]
|
|
150
|
+
>>> )
|
|
151
|
+
"""
|
|
152
|
+
if isinstance(directory, str):
|
|
153
|
+
proto_path = ProtoPath(name=directory, value="")
|
|
154
|
+
else:
|
|
155
|
+
proto_path = directory
|
|
156
|
+
return self.loop_manager.run_coroutine(self.async_list_dir(proto_path))
|
|
157
|
+
|
|
158
|
+
def read_file_lines(
|
|
159
|
+
self,
|
|
160
|
+
file_name: Union[str, ProtoPath],
|
|
161
|
+
encoding: Optional[str] = None,
|
|
162
|
+
errors: Optional[str] = None,
|
|
163
|
+
newline: Optional[str] = None,
|
|
164
|
+
) -> io.StringIO:
|
|
165
|
+
"""
|
|
166
|
+
Read file lines
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
file_name : Union[str, ProtoPath]
|
|
171
|
+
File name
|
|
172
|
+
encoding : str, optional
|
|
173
|
+
Encoding, by default None
|
|
174
|
+
errors : str, optional
|
|
175
|
+
Errors, by default None
|
|
176
|
+
newline : str, optional
|
|
177
|
+
Newline, by default None
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
io.StringIO
|
|
182
|
+
String data
|
|
183
|
+
|
|
184
|
+
Examples
|
|
185
|
+
--------
|
|
186
|
+
|
|
187
|
+
Inside a :class:`Task <manta_light.task.Task>` class, you can
|
|
188
|
+
access to local data by using the attribute :code:`self.local`
|
|
189
|
+
automatically created by :class:`Task <manta_light.task.Task>`:
|
|
190
|
+
|
|
191
|
+
>>> text = self.local.read_file_lines("text.txt")
|
|
192
|
+
>>> print(text)
|
|
193
|
+
>>> io.StringIO("Hello world")
|
|
194
|
+
"""
|
|
195
|
+
if isinstance(file_name, str):
|
|
196
|
+
proto_path = ProtoPath(name=file_name, value="")
|
|
197
|
+
else:
|
|
198
|
+
proto_path = file_name
|
|
199
|
+
return self.loop_manager.run_coroutine(
|
|
200
|
+
self.async_read_file_lines(proto_path, encoding, errors, newline)
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def exists(self, file_name: Union[str, ProtoPath]) -> bool:
|
|
204
|
+
"""
|
|
205
|
+
Check if a file exists
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
file_name : Union[str, ProtoPath]
|
|
210
|
+
File name
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
bool
|
|
215
|
+
True if the file exists, False otherwise
|
|
216
|
+
|
|
217
|
+
Examples
|
|
218
|
+
--------
|
|
219
|
+
|
|
220
|
+
Inside a :class:`Task <manta_light.task.Task>` class, you can
|
|
221
|
+
access to local data by using the attribute :code:`self.local`
|
|
222
|
+
automatically created by :class:`Task <manta_light.task.Task>`:
|
|
223
|
+
|
|
224
|
+
>>> if self.local.exists("text.txt"):
|
|
225
|
+
>>> print("File exists")
|
|
226
|
+
>>> else:
|
|
227
|
+
>>> print("File does not exist")
|
|
228
|
+
"""
|
|
229
|
+
if isinstance(file_name, str):
|
|
230
|
+
proto_path = ProtoPath(name=file_name, value="")
|
|
231
|
+
else:
|
|
232
|
+
proto_path = file_name
|
|
233
|
+
return self.loop_manager.run_coroutine(self.async_exists(proto_path))
|
|
234
|
+
|
|
235
|
+
def __str__(self): # pragma: no cover
|
|
236
|
+
return f"Local(host={self.local_client.host}, port={self.local_client.port}, task_id={self.task_id}, swarm_id={self.swarm_id})"
|
|
237
|
+
|
|
238
|
+
def __repr__(self): # pragma: no cover
|
|
239
|
+
return str(self)
|
|
240
|
+
|
|
241
|
+
# Asynchronous methods
|
|
242
|
+
|
|
243
|
+
async def async_get_numpy_data(
|
|
244
|
+
self, dataset_name: Union[str, ProtoPath]
|
|
245
|
+
) -> "numpy.ndarray": # type: ignore
|
|
246
|
+
"""
|
|
247
|
+
Get Numpy Data
|
|
248
|
+
|
|
249
|
+
Parameters
|
|
250
|
+
----------
|
|
251
|
+
dataset_name : Union[str, ProtoPath]
|
|
252
|
+
Dataset name
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
numpy.ndarray
|
|
257
|
+
Numpy data
|
|
258
|
+
|
|
259
|
+
Examples
|
|
260
|
+
--------
|
|
261
|
+
|
|
262
|
+
Same as :meth:`get_numpy_data <manta_light.local.Local.get_numpy_data>`
|
|
263
|
+
but asynchronous:
|
|
264
|
+
|
|
265
|
+
>>> mnist_data = await self.local.async_get_numpy_data("mnist.npz")
|
|
266
|
+
"""
|
|
267
|
+
try:
|
|
268
|
+
import numpy as np
|
|
269
|
+
except ImportError:
|
|
270
|
+
raise ImportError("numpy is not installed")
|
|
271
|
+
|
|
272
|
+
buffer = await self.async_get_binary_data(dataset_name)
|
|
273
|
+
return np.load(buffer)
|
|
274
|
+
|
|
275
|
+
async def async_get_binary_data(
|
|
276
|
+
self, dataset_name: Union[str, ProtoPath]
|
|
277
|
+
) -> io.BytesIO:
|
|
278
|
+
"""
|
|
279
|
+
Asynchronously get binary data
|
|
280
|
+
|
|
281
|
+
Parameters
|
|
282
|
+
----------
|
|
283
|
+
dataset_name : Union[str, ProtoPath]
|
|
284
|
+
Dataset name
|
|
285
|
+
|
|
286
|
+
Returns
|
|
287
|
+
-------
|
|
288
|
+
io.BytesIO
|
|
289
|
+
Binary data
|
|
290
|
+
|
|
291
|
+
Examples
|
|
292
|
+
--------
|
|
293
|
+
|
|
294
|
+
Same as :meth:`get_binary_data <manta_light.local.Local.get_binary_data>`
|
|
295
|
+
but asynchronous:
|
|
296
|
+
|
|
297
|
+
>>> mnist_data = await self.local.async_get_binary_data("mnist.npz")
|
|
298
|
+
>>> data = np.load(mnist_data)
|
|
299
|
+
"""
|
|
300
|
+
if isinstance(dataset_name, str):
|
|
301
|
+
name = dataset_name
|
|
302
|
+
else:
|
|
303
|
+
name = dataset_name.name
|
|
304
|
+
|
|
305
|
+
# Get binary data and convert to BytesIO for numpy.load
|
|
306
|
+
buffer = io.BytesIO()
|
|
307
|
+
async for chunk in self.local_client.get_binary_data(
|
|
308
|
+
DataRequest(
|
|
309
|
+
task_id=self.task_id.oid, swarm_id=self.swarm_id.oid, name=name
|
|
310
|
+
),
|
|
311
|
+
):
|
|
312
|
+
buffer.write(chunk.content)
|
|
313
|
+
buffer.seek(0)
|
|
314
|
+
return buffer
|
|
315
|
+
|
|
316
|
+
async def async_list_dir(self, directory: ProtoPath) -> ListDirResponse:
|
|
317
|
+
"""
|
|
318
|
+
List directories
|
|
319
|
+
|
|
320
|
+
Parameters
|
|
321
|
+
----------
|
|
322
|
+
directory : ProtoPath
|
|
323
|
+
Directory name
|
|
324
|
+
|
|
325
|
+
Returns
|
|
326
|
+
-------
|
|
327
|
+
ListDirResponse
|
|
328
|
+
List of directories
|
|
329
|
+
"""
|
|
330
|
+
return await self.local_client.list_dir(
|
|
331
|
+
DirRequest(
|
|
332
|
+
data_request=DataRequest(
|
|
333
|
+
task_id=self.task_id.oid,
|
|
334
|
+
swarm_id=self.swarm_id.oid,
|
|
335
|
+
name=directory.name,
|
|
336
|
+
),
|
|
337
|
+
path=directory.value,
|
|
338
|
+
),
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
async def async_read_file_lines(
|
|
342
|
+
self,
|
|
343
|
+
file_name: ProtoPath,
|
|
344
|
+
encoding: Optional[str] = None,
|
|
345
|
+
errors: Optional[str] = None,
|
|
346
|
+
newline: Optional[str] = None,
|
|
347
|
+
) -> io.StringIO:
|
|
348
|
+
"""
|
|
349
|
+
Read file lines
|
|
350
|
+
|
|
351
|
+
Parameters
|
|
352
|
+
----------
|
|
353
|
+
file_name : ProtoPath
|
|
354
|
+
File name
|
|
355
|
+
encoding : Optional[str], optional
|
|
356
|
+
Encoding, by default None
|
|
357
|
+
errors : Optional[str], optional
|
|
358
|
+
Errors, by default None
|
|
359
|
+
newline : Optional[str], optional
|
|
360
|
+
Newline, by default None
|
|
361
|
+
|
|
362
|
+
Returns
|
|
363
|
+
-------
|
|
364
|
+
io.StringIO
|
|
365
|
+
String data
|
|
366
|
+
"""
|
|
367
|
+
buffer = io.StringIO()
|
|
368
|
+
async for chunk in self.local_client.read_file_lines(
|
|
369
|
+
ReadText(
|
|
370
|
+
data_request=DataRequest(
|
|
371
|
+
task_id=self.task_id.oid,
|
|
372
|
+
swarm_id=self.swarm_id.oid,
|
|
373
|
+
name=file_name.name,
|
|
374
|
+
),
|
|
375
|
+
path=file_name,
|
|
376
|
+
encoding="" if encoding is None else encoding,
|
|
377
|
+
errors="" if errors is None else errors,
|
|
378
|
+
newline="" if newline is None else newline,
|
|
379
|
+
),
|
|
380
|
+
):
|
|
381
|
+
buffer.write(chunk.content.decode())
|
|
382
|
+
buffer.seek(0)
|
|
383
|
+
return buffer
|
|
384
|
+
|
|
385
|
+
async def async_exists(self, path: ProtoPath) -> bool:
|
|
386
|
+
"""
|
|
387
|
+
Check if a file exists
|
|
388
|
+
|
|
389
|
+
Parameters
|
|
390
|
+
----------
|
|
391
|
+
path : ProtoPath
|
|
392
|
+
Path
|
|
393
|
+
|
|
394
|
+
Returns
|
|
395
|
+
-------
|
|
396
|
+
bool
|
|
397
|
+
True if exists
|
|
398
|
+
"""
|
|
399
|
+
response = await self.local_client.exists(
|
|
400
|
+
DirRequest(
|
|
401
|
+
data_request=DataRequest(
|
|
402
|
+
task_id=self.task_id.oid, swarm_id=self.swarm_id.oid, name=path.name
|
|
403
|
+
),
|
|
404
|
+
path=path.value,
|
|
405
|
+
),
|
|
406
|
+
)
|
|
407
|
+
return response.value
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import logging.config
|
|
3
|
+
|
|
4
|
+
FORMAT = (
|
|
5
|
+
"%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
MANTA_LOGGING_CONFIG = {
|
|
9
|
+
"version": 1,
|
|
10
|
+
"disable_existing_loggers": False,
|
|
11
|
+
"formatters": {
|
|
12
|
+
"standard": {"format": FORMAT},
|
|
13
|
+
},
|
|
14
|
+
"filters": {
|
|
15
|
+
"warnings_and_below": {
|
|
16
|
+
"()": "manta_common.logging_config.filter_maker",
|
|
17
|
+
"level": "WARNING",
|
|
18
|
+
},
|
|
19
|
+
"manta_filter": {
|
|
20
|
+
"()": "manta_common.logging_config.filter_manta",
|
|
21
|
+
"level": "INFO",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
"handlers": {
|
|
25
|
+
"default": {
|
|
26
|
+
"class": "logging.StreamHandler",
|
|
27
|
+
"level": "INFO",
|
|
28
|
+
"formatter": "standard",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
"root": {
|
|
32
|
+
"level": "DEBUG",
|
|
33
|
+
"handlers": ["default"],
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def configure_logging():
|
|
39
|
+
logging.config.dictConfig(MANTA_LOGGING_CONFIG)
|