modal 0.67.37__py3-none-any.whl → 0.67.39__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.
- modal/cli/network_file_system.py +23 -2
- modal/client.pyi +2 -2
- modal/network_file_system.py +6 -0
- modal/network_file_system.pyi +20 -0
- modal/sandbox.py +24 -1
- modal/sandbox.pyi +7 -0
- {modal-0.67.37.dist-info → modal-0.67.39.dist-info}/METADATA +1 -1
- {modal-0.67.37.dist-info → modal-0.67.39.dist-info}/RECORD +13 -13
- modal_version/_version_generated.py +1 -1
- {modal-0.67.37.dist-info → modal-0.67.39.dist-info}/LICENSE +0 -0
- {modal-0.67.37.dist-info → modal-0.67.39.dist-info}/WHEEL +0 -0
- {modal-0.67.37.dist-info → modal-0.67.39.dist-info}/entry_points.txt +0 -0
- {modal-0.67.37.dist-info → modal-0.67.39.dist-info}/top_level.txt +0 -0
modal/cli/network_file_system.py
CHANGED
@@ -10,7 +10,7 @@ from grpclib import GRPCError, Status
|
|
10
10
|
from rich.console import Console
|
11
11
|
from rich.syntax import Syntax
|
12
12
|
from rich.table import Table
|
13
|
-
from typer import Typer
|
13
|
+
from typer import Argument, Typer
|
14
14
|
|
15
15
|
import modal
|
16
16
|
from modal._location import display_location
|
@@ -18,7 +18,7 @@ from modal._output import OutputManager, ProgressHandler
|
|
18
18
|
from modal._utils.async_utils import synchronizer
|
19
19
|
from modal._utils.grpc_utils import retry_transient_errors
|
20
20
|
from modal.cli._download import _volume_download
|
21
|
-
from modal.cli.utils import ENV_OPTION, display_table, timestamp_to_local
|
21
|
+
from modal.cli.utils import ENV_OPTION, YES_OPTION, display_table, timestamp_to_local
|
22
22
|
from modal.client import _Client
|
23
23
|
from modal.environments import ensure_env
|
24
24
|
from modal.network_file_system import _NetworkFileSystem
|
@@ -217,3 +217,24 @@ async def rm(
|
|
217
217
|
if exc.status in (Status.NOT_FOUND, Status.INVALID_ARGUMENT):
|
218
218
|
raise UsageError(exc.message)
|
219
219
|
raise
|
220
|
+
|
221
|
+
|
222
|
+
@nfs_cli.command(
|
223
|
+
name="delete",
|
224
|
+
help="Delete a named, persistent modal.NetworkFileSystem.",
|
225
|
+
rich_help_panel="Management",
|
226
|
+
)
|
227
|
+
@synchronizer.create_blocking
|
228
|
+
async def delete(
|
229
|
+
nfs_name: str = Argument(help="Name of the modal.NetworkFileSystem to be deleted. Case sensitive"),
|
230
|
+
yes: bool = YES_OPTION,
|
231
|
+
env: Optional[str] = ENV_OPTION,
|
232
|
+
):
|
233
|
+
if not yes:
|
234
|
+
typer.confirm(
|
235
|
+
f"Are you sure you want to irrevocably delete the modal.NetworkFileSystem '{nfs_name}'?",
|
236
|
+
default=False,
|
237
|
+
abort=True,
|
238
|
+
)
|
239
|
+
|
240
|
+
await _NetworkFileSystem.delete(label=nfs_name, environment_name=env)
|
modal/client.pyi
CHANGED
@@ -26,7 +26,7 @@ class _Client:
|
|
26
26
|
_stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
|
27
27
|
|
28
28
|
def __init__(
|
29
|
-
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.
|
29
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.39"
|
30
30
|
): ...
|
31
31
|
def is_closed(self) -> bool: ...
|
32
32
|
@property
|
@@ -81,7 +81,7 @@ class Client:
|
|
81
81
|
_stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
|
82
82
|
|
83
83
|
def __init__(
|
84
|
-
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.
|
84
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.39"
|
85
85
|
): ...
|
86
86
|
def is_closed(self) -> bool: ...
|
87
87
|
@property
|
modal/network_file_system.py
CHANGED
@@ -221,6 +221,12 @@ class _NetworkFileSystem(_Object, type_prefix="sv"):
|
|
221
221
|
resp = await retry_transient_errors(client.stub.SharedVolumeGetOrCreate, request)
|
222
222
|
return resp.shared_volume_id
|
223
223
|
|
224
|
+
@staticmethod
|
225
|
+
async def delete(label: str, client: Optional[_Client] = None, environment_name: Optional[str] = None):
|
226
|
+
obj = await _NetworkFileSystem.lookup(label, client=client, environment_name=environment_name)
|
227
|
+
req = api_pb2.SharedVolumeDeleteRequest(shared_volume_id=obj.object_id)
|
228
|
+
await retry_transient_errors(obj._client.stub.SharedVolumeDelete, req)
|
229
|
+
|
224
230
|
@live_method
|
225
231
|
async def write_file(self, remote_path: str, fp: BinaryIO, progress_cb: Optional[Callable[..., Any]] = None) -> int:
|
226
232
|
"""Write from a file object to a path on the network file system, atomically.
|
modal/network_file_system.pyi
CHANGED
@@ -41,6 +41,10 @@ class _NetworkFileSystem(modal.object._Object):
|
|
41
41
|
client: typing.Optional[modal.client._Client] = None,
|
42
42
|
environment_name: typing.Optional[str] = None,
|
43
43
|
) -> str: ...
|
44
|
+
@staticmethod
|
45
|
+
async def delete(
|
46
|
+
label: str, client: typing.Optional[modal.client._Client] = None, environment_name: typing.Optional[str] = None
|
47
|
+
): ...
|
44
48
|
async def write_file(
|
45
49
|
self,
|
46
50
|
remote_path: str,
|
@@ -118,6 +122,22 @@ class NetworkFileSystem(modal.object.Object):
|
|
118
122
|
|
119
123
|
create_deployed: __create_deployed_spec
|
120
124
|
|
125
|
+
class __delete_spec(typing_extensions.Protocol):
|
126
|
+
def __call__(
|
127
|
+
self,
|
128
|
+
label: str,
|
129
|
+
client: typing.Optional[modal.client.Client] = None,
|
130
|
+
environment_name: typing.Optional[str] = None,
|
131
|
+
): ...
|
132
|
+
async def aio(
|
133
|
+
self,
|
134
|
+
label: str,
|
135
|
+
client: typing.Optional[modal.client.Client] = None,
|
136
|
+
environment_name: typing.Optional[str] = None,
|
137
|
+
): ...
|
138
|
+
|
139
|
+
delete: __delete_spec
|
140
|
+
|
121
141
|
class __write_file_spec(typing_extensions.Protocol):
|
122
142
|
def __call__(
|
123
143
|
self,
|
modal/sandbox.py
CHANGED
@@ -21,7 +21,7 @@ from ._utils.mount_utils import validate_network_file_systems, validate_volumes
|
|
21
21
|
from .client import _Client
|
22
22
|
from .config import config
|
23
23
|
from .container_process import _ContainerProcess
|
24
|
-
from .exception import InvalidError, SandboxTerminatedError, SandboxTimeoutError, deprecation_warning
|
24
|
+
from .exception import ExecutionError, InvalidError, SandboxTerminatedError, SandboxTimeoutError, deprecation_warning
|
25
25
|
from .gpu import GPU_T
|
26
26
|
from .image import _Image
|
27
27
|
from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
|
@@ -331,6 +331,29 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
331
331
|
except GRPCError as exc:
|
332
332
|
raise InvalidError(exc.message) if exc.status == Status.INVALID_ARGUMENT else exc
|
333
333
|
|
334
|
+
async def snapshot_filesystem(self, timeout: int = 55) -> _Image:
|
335
|
+
"""Snapshot the filesystem of the Sandbox.
|
336
|
+
|
337
|
+
Returns an [`Image`](https://modal.com/docs/reference/modal.Image) object which
|
338
|
+
can be used to spawn a new Sandbox with the same filesystem.
|
339
|
+
"""
|
340
|
+
req = api_pb2.SandboxSnapshotFsRequest(sandbox_id=self.object_id, timeout=timeout)
|
341
|
+
resp = await retry_transient_errors(self._client.stub.SandboxSnapshotFs, req)
|
342
|
+
|
343
|
+
if resp.result.status != api_pb2.GenericResult.GENERIC_STATUS_SUCCESS:
|
344
|
+
raise ExecutionError(resp.result.exception)
|
345
|
+
|
346
|
+
image_id = resp.image_id
|
347
|
+
metadata = resp.image_metadata
|
348
|
+
|
349
|
+
async def _load(self: _Image, resolver: Resolver, existing_object_id: Optional[str]):
|
350
|
+
self._hydrate(image_id, resolver.client, metadata)
|
351
|
+
|
352
|
+
rep = "Image()"
|
353
|
+
image = _Image._from_loader(_load, rep)
|
354
|
+
|
355
|
+
return image
|
356
|
+
|
334
357
|
# Live handle methods
|
335
358
|
|
336
359
|
async def wait(self, raise_on_termination: bool = True):
|
modal/sandbox.pyi
CHANGED
@@ -88,6 +88,7 @@ class _Sandbox(modal.object._Object):
|
|
88
88
|
@staticmethod
|
89
89
|
async def from_id(sandbox_id: str, client: typing.Optional[modal.client._Client] = None) -> _Sandbox: ...
|
90
90
|
async def set_tags(self, tags: dict[str, str], *, client: typing.Optional[modal.client._Client] = None): ...
|
91
|
+
async def snapshot_filesystem(self, timeout: int = 55) -> modal.image._Image: ...
|
91
92
|
async def wait(self, raise_on_termination: bool = True): ...
|
92
93
|
async def tunnels(self, timeout: int = 50) -> dict[int, modal._tunnel.Tunnel]: ...
|
93
94
|
async def terminate(self): ...
|
@@ -252,6 +253,12 @@ class Sandbox(modal.object.Object):
|
|
252
253
|
|
253
254
|
set_tags: __set_tags_spec
|
254
255
|
|
256
|
+
class __snapshot_filesystem_spec(typing_extensions.Protocol):
|
257
|
+
def __call__(self, timeout: int = 55) -> modal.image.Image: ...
|
258
|
+
async def aio(self, timeout: int = 55) -> modal.image.Image: ...
|
259
|
+
|
260
|
+
snapshot_filesystem: __snapshot_filesystem_spec
|
261
|
+
|
255
262
|
class __wait_spec(typing_extensions.Protocol):
|
256
263
|
def __call__(self, raise_on_termination: bool = True): ...
|
257
264
|
async def aio(self, raise_on_termination: bool = True): ...
|
@@ -19,7 +19,7 @@ modal/app.py,sha256=EJ7FUN6rWnSwLJoYJh8nmKg_t-8hdN8_rt0OrkP7JvQ,46084
|
|
19
19
|
modal/app.pyi,sha256=BE5SlR5tRECuc6-e2lUuOknDdov3zxgZ4N0AsLb5ZVQ,25270
|
20
20
|
modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
|
21
21
|
modal/client.py,sha256=cmylZhU35txmrx4nltNYuuqXRgeoMtm0ow1J9wJkEYQ,16400
|
22
|
-
modal/client.pyi,sha256=
|
22
|
+
modal/client.pyi,sha256=D17w1r5HIlAe0QG2Xx65-Dmv-0WD1ATslnQIfXqTiTE,7354
|
23
23
|
modal/cloud_bucket_mount.py,sha256=G7T7jWLD0QkmrfKR75mSTwdUZ2xNfj7pkVqb4ipmxmI,5735
|
24
24
|
modal/cloud_bucket_mount.pyi,sha256=CEi7vrH3kDUF4LAy4qP6tfImy2UJuFRcRbsgRNM1wo8,1403
|
25
25
|
modal/cls.py,sha256=OJqzj_V-n1g48BY_4Jg_BOTQdftEEl4kTWN0X4FOOdg,27378
|
@@ -42,8 +42,8 @@ modal/io_streams.py,sha256=QkQiizKRzd5bnbKQsap31LJgBYlAnj4-XkV_50xPYX0,15079
|
|
42
42
|
modal/io_streams.pyi,sha256=bCCVSxkMcosYd8O3PQDDwJw7TQ8JEcnYonLJ5t27TQs,4804
|
43
43
|
modal/mount.py,sha256=liaid5p42o0OKnzoocJJ_oCovDVderk3-JuCTa5pqtA,27656
|
44
44
|
modal/mount.pyi,sha256=3e4nkXUeeVmUmOyK8Tiyk_EQlHeWruN3yGJVnmDUVrI,9761
|
45
|
-
modal/network_file_system.py,sha256=
|
46
|
-
modal/network_file_system.pyi,sha256=
|
45
|
+
modal/network_file_system.py,sha256=NKZgh_p8MyJyyJgP92lhRgTmwA3kOPw7m8AbYlchhCE,14530
|
46
|
+
modal/network_file_system.pyi,sha256=8mHKXuRkxHPazF6ljIW7g4M5aVqLSl6eKUPLgDCug5c,7901
|
47
47
|
modal/object.py,sha256=KmtWRDd5ntHGSO9ASHe9MJcIgjNRqaDXGc3rWOXwrmA,9646
|
48
48
|
modal/object.pyi,sha256=MO78H9yFSE5i1gExPEwyyQzLdlshkcGHN1aQ0ylyvq0,8802
|
49
49
|
modal/output.py,sha256=N0xf4qeudEaYrslzdAl35VKV8rapstgIM2e9wO8_iy0,1967
|
@@ -60,8 +60,8 @@ modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
|
|
60
60
|
modal/runner.py,sha256=7obU-Gq1ocpBGCuR6pvn1T-D6ggg1T48qFo2TNUGWkU,24089
|
61
61
|
modal/runner.pyi,sha256=RAtCvx_lXWjyFjIaZ3t9-X1c7rqpgAQlhl4Hww53OY8,5038
|
62
62
|
modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
|
63
|
-
modal/sandbox.py,sha256=
|
64
|
-
modal/sandbox.pyi,sha256=
|
63
|
+
modal/sandbox.py,sha256=5V0y7HfhfhVYY-mx-w--iKMYBPrSnu-KYOp5nPy9LkE,26097
|
64
|
+
modal/sandbox.pyi,sha256=mUxo6YMJgwiWLuG-NiqhZvH7yaWmAortTlqz2Tzmc7A,18036
|
65
65
|
modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
|
66
66
|
modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
|
67
67
|
modal/secret.py,sha256=Y1WgybQIkfkxdzH9CQ1h-Wd1DJJpzipigMhyyvSxTww,10007
|
@@ -110,7 +110,7 @@ modal/cli/entry_point.py,sha256=aaNxFAqZcmtSjwzkYIA_Ba9CkL4cL4_i2gy5VjoXxkM,4228
|
|
110
110
|
modal/cli/environment.py,sha256=Ayddkiq9jdj3XYDJ8ZmUqFpPPH8xajYlbexRkzGtUcg,4334
|
111
111
|
modal/cli/import_refs.py,sha256=wnqE5AMeyAN3IZmQvJCp54KRnJh8Nq_5fMqB6u6GEL8,9147
|
112
112
|
modal/cli/launch.py,sha256=uyI-ouGvYRjHLGxGQ2lYBZq32BiRT1i0L8ksz5iy7K8,2935
|
113
|
-
modal/cli/network_file_system.py,sha256=
|
113
|
+
modal/cli/network_file_system.py,sha256=3QbAxKEoRc6RCMsYE3OS-GcuiI4GMkz_wAKsIBbN1qg,8186
|
114
114
|
modal/cli/profile.py,sha256=rLXfjJObfPNjaZvNfHGIKqs7y9bGYyGe-K7V0w-Ni0M,3110
|
115
115
|
modal/cli/queues.py,sha256=MIh2OsliNE2QeL1erubfsRsNuG4fxqcqWA2vgIfQ4Mg,4494
|
116
116
|
modal/cli/run.py,sha256=IPA5Hx7HqCE01NilPZDh1fFaslO4QZa-RKEpMPqjLqA,17066
|
@@ -159,10 +159,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
|
|
159
159
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
160
160
|
modal_version/__init__.py,sha256=3IY-AWLH55r35_mQXIaut0jrJvoPuf1NZJBQQfSbPuo,470
|
161
161
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
162
|
-
modal_version/_version_generated.py,sha256=
|
163
|
-
modal-0.67.
|
164
|
-
modal-0.67.
|
165
|
-
modal-0.67.
|
166
|
-
modal-0.67.
|
167
|
-
modal-0.67.
|
168
|
-
modal-0.67.
|
162
|
+
modal_version/_version_generated.py,sha256=66TXyta4tOwtrTM1q4q1RMzjierpXNDNticXEWERvRk,149
|
163
|
+
modal-0.67.39.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
164
|
+
modal-0.67.39.dist-info/METADATA,sha256=HV_U4DQAm8v0pMbjpvEXN7G5eaoCOk-Z_Jkf3f-QRuw,2329
|
165
|
+
modal-0.67.39.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
166
|
+
modal-0.67.39.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
167
|
+
modal-0.67.39.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
|
168
|
+
modal-0.67.39.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|