modal 0.68.27__py3-none-any.whl → 0.68.28__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/client.pyi +2 -2
- modal/file_io.py +52 -4
- modal/file_io.pyi +13 -0
- modal/sandbox.py +15 -0
- modal/sandbox.pyi +21 -0
- {modal-0.68.27.dist-info → modal-0.68.28.dist-info}/METADATA +1 -1
- {modal-0.68.27.dist-info → modal-0.68.28.dist-info}/RECORD +12 -12
- modal_version/_version_generated.py +1 -1
- {modal-0.68.27.dist-info → modal-0.68.28.dist-info}/LICENSE +0 -0
- {modal-0.68.27.dist-info → modal-0.68.28.dist-info}/WHEEL +0 -0
- {modal-0.68.27.dist-info → modal-0.68.28.dist-info}/entry_points.txt +0 -0
- {modal-0.68.27.dist-info → modal-0.68.28.dist-info}/top_level.txt +0 -0
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.68.
|
29
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.68.28"
|
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.68.
|
84
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.68.28"
|
85
85
|
): ...
|
86
86
|
def is_closed(self) -> bool: ...
|
87
87
|
@property
|
modal/file_io.py
CHANGED
@@ -6,6 +6,8 @@ from typing import TYPE_CHECKING, AsyncIterator, Generic, Optional, Sequence, Ty
|
|
6
6
|
if TYPE_CHECKING:
|
7
7
|
import _typeshed
|
8
8
|
|
9
|
+
import json
|
10
|
+
|
9
11
|
from grpclib.exceptions import GRPCError, StreamTerminatedError
|
10
12
|
|
11
13
|
from modal._utils.grpc_utils import retry_transient_errors
|
@@ -267,12 +269,12 @@ class _FileIO(Generic[T]):
|
|
267
269
|
output = await self._make_read_request(None)
|
268
270
|
if self._binary:
|
269
271
|
lines_bytes = output.split(b"\n")
|
270
|
-
|
271
|
-
return cast(Sequence[T],
|
272
|
+
return_bytes = [line + b"\n" for line in lines_bytes[:-1]] + ([lines_bytes[-1]] if lines_bytes[-1] else [])
|
273
|
+
return cast(Sequence[T], return_bytes)
|
272
274
|
else:
|
273
275
|
lines = output.decode("utf-8").split("\n")
|
274
|
-
|
275
|
-
return cast(Sequence[T],
|
276
|
+
return_strs = [line + "\n" for line in lines[:-1]] + ([lines[-1]] if lines[-1] else [])
|
277
|
+
return cast(Sequence[T], return_strs)
|
276
278
|
|
277
279
|
async def write(self, data: Union[bytes, str]) -> None:
|
278
280
|
"""Write data to the current position.
|
@@ -337,6 +339,52 @@ class _FileIO(Generic[T]):
|
|
337
339
|
)
|
338
340
|
await self._wait(resp.exec_id)
|
339
341
|
|
342
|
+
@classmethod
|
343
|
+
async def ls(cls, path: str, client: _Client, task_id: str) -> list[str]:
|
344
|
+
"""List the contents of the provided directory."""
|
345
|
+
self = cls.__new__(cls)
|
346
|
+
self._client = client
|
347
|
+
self._task_id = task_id
|
348
|
+
resp = await self._make_request(
|
349
|
+
api_pb2.ContainerFilesystemExecRequest(
|
350
|
+
file_ls_request=api_pb2.ContainerFileLsRequest(path=path),
|
351
|
+
task_id=task_id,
|
352
|
+
)
|
353
|
+
)
|
354
|
+
output = await self._wait(resp.exec_id)
|
355
|
+
try:
|
356
|
+
return json.loads(output.decode("utf-8"))["paths"]
|
357
|
+
except json.JSONDecodeError:
|
358
|
+
raise FilesystemExecutionError("failed to parse list output")
|
359
|
+
|
360
|
+
@classmethod
|
361
|
+
async def mkdir(cls, path: str, client: _Client, task_id: str, parents: bool = False) -> None:
|
362
|
+
"""Create a new directory."""
|
363
|
+
self = cls.__new__(cls)
|
364
|
+
self._client = client
|
365
|
+
self._task_id = task_id
|
366
|
+
resp = await self._make_request(
|
367
|
+
api_pb2.ContainerFilesystemExecRequest(
|
368
|
+
file_mkdir_request=api_pb2.ContainerFileMkdirRequest(path=path, make_parents=parents),
|
369
|
+
task_id=self._task_id,
|
370
|
+
)
|
371
|
+
)
|
372
|
+
await self._wait(resp.exec_id)
|
373
|
+
|
374
|
+
@classmethod
|
375
|
+
async def rm(cls, path: str, client: _Client, task_id: str, recursive: bool = False) -> None:
|
376
|
+
"""Remove a file or directory in the Sandbox."""
|
377
|
+
self = cls.__new__(cls)
|
378
|
+
self._client = client
|
379
|
+
self._task_id = task_id
|
380
|
+
resp = await self._make_request(
|
381
|
+
api_pb2.ContainerFilesystemExecRequest(
|
382
|
+
file_rm_request=api_pb2.ContainerFileRmRequest(path=path, recursive=recursive),
|
383
|
+
task_id=self._task_id,
|
384
|
+
)
|
385
|
+
)
|
386
|
+
await self._wait(resp.exec_id)
|
387
|
+
|
340
388
|
async def _close(self) -> None:
|
341
389
|
# Buffer is flushed by the runner on close
|
342
390
|
resp = await self._make_request(
|
modal/file_io.pyi
CHANGED
@@ -43,6 +43,12 @@ class _FileIO(typing.Generic[T]):
|
|
43
43
|
async def flush(self) -> None: ...
|
44
44
|
def _get_whence(self, whence: int): ...
|
45
45
|
async def seek(self, offset: int, whence: int = 0) -> None: ...
|
46
|
+
@classmethod
|
47
|
+
async def ls(cls, path: str, client: modal.client._Client, task_id: str) -> list[str]: ...
|
48
|
+
@classmethod
|
49
|
+
async def mkdir(cls, path: str, client: modal.client._Client, task_id: str, parents: bool = False) -> None: ...
|
50
|
+
@classmethod
|
51
|
+
async def rm(cls, path: str, client: modal.client._Client, task_id: str, recursive: bool = False) -> None: ...
|
46
52
|
async def _close(self) -> None: ...
|
47
53
|
async def close(self) -> None: ...
|
48
54
|
def _check_writable(self) -> None: ...
|
@@ -161,6 +167,13 @@ class FileIO(typing.Generic[T]):
|
|
161
167
|
|
162
168
|
seek: __seek_spec
|
163
169
|
|
170
|
+
@classmethod
|
171
|
+
def ls(cls, path: str, client: modal.client.Client, task_id: str) -> list[str]: ...
|
172
|
+
@classmethod
|
173
|
+
def mkdir(cls, path: str, client: modal.client.Client, task_id: str, parents: bool = False) -> None: ...
|
174
|
+
@classmethod
|
175
|
+
def rm(cls, path: str, client: modal.client.Client, task_id: str, recursive: bool = False) -> None: ...
|
176
|
+
|
164
177
|
class ___close_spec(typing_extensions.Protocol):
|
165
178
|
def __call__(self) -> None: ...
|
166
179
|
async def aio(self) -> None: ...
|
modal/sandbox.py
CHANGED
@@ -567,6 +567,21 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
567
567
|
task_id = await self._get_task_id()
|
568
568
|
return await _FileIO.create(path, mode, self._client, task_id)
|
569
569
|
|
570
|
+
async def ls(self, path: str) -> list[str]:
|
571
|
+
"""List the contents of a directory in the Sandbox."""
|
572
|
+
task_id = await self._get_task_id()
|
573
|
+
return await _FileIO.ls(path, self._client, task_id)
|
574
|
+
|
575
|
+
async def mkdir(self, path: str, parents: bool = False) -> None:
|
576
|
+
"""Create a new directory in the Sandbox."""
|
577
|
+
task_id = await self._get_task_id()
|
578
|
+
return await _FileIO.mkdir(path, self._client, task_id, parents)
|
579
|
+
|
580
|
+
async def rm(self, path: str, recursive: bool = False) -> None:
|
581
|
+
"""Remove a file or directory in the Sandbox."""
|
582
|
+
task_id = await self._get_task_id()
|
583
|
+
return await _FileIO.rm(path, self._client, task_id, recursive)
|
584
|
+
|
570
585
|
@property
|
571
586
|
def stdout(self) -> _StreamReader[str]:
|
572
587
|
"""
|
modal/sandbox.pyi
CHANGED
@@ -128,6 +128,9 @@ class _Sandbox(modal.object._Object):
|
|
128
128
|
async def open(self, path: str, mode: _typeshed.OpenTextMode) -> modal.file_io._FileIO[str]: ...
|
129
129
|
@typing.overload
|
130
130
|
async def open(self, path: str, mode: _typeshed.OpenBinaryMode) -> modal.file_io._FileIO[bytes]: ...
|
131
|
+
async def ls(self, path: str) -> list[str]: ...
|
132
|
+
async def mkdir(self, path: str, parents: bool = False) -> None: ...
|
133
|
+
async def rm(self, path: str, recursive: bool = False) -> None: ...
|
131
134
|
@property
|
132
135
|
def stdout(self) -> modal.io_streams._StreamReader[str]: ...
|
133
136
|
@property
|
@@ -367,6 +370,24 @@ class Sandbox(modal.object.Object):
|
|
367
370
|
|
368
371
|
open: __open_spec
|
369
372
|
|
373
|
+
class __ls_spec(typing_extensions.Protocol):
|
374
|
+
def __call__(self, path: str) -> list[str]: ...
|
375
|
+
async def aio(self, path: str) -> list[str]: ...
|
376
|
+
|
377
|
+
ls: __ls_spec
|
378
|
+
|
379
|
+
class __mkdir_spec(typing_extensions.Protocol):
|
380
|
+
def __call__(self, path: str, parents: bool = False) -> None: ...
|
381
|
+
async def aio(self, path: str, parents: bool = False) -> None: ...
|
382
|
+
|
383
|
+
mkdir: __mkdir_spec
|
384
|
+
|
385
|
+
class __rm_spec(typing_extensions.Protocol):
|
386
|
+
def __call__(self, path: str, recursive: bool = False) -> None: ...
|
387
|
+
async def aio(self, path: str, recursive: bool = False) -> None: ...
|
388
|
+
|
389
|
+
rm: __rm_spec
|
390
|
+
|
370
391
|
@property
|
371
392
|
def stdout(self) -> modal.io_streams.StreamReader[str]: ...
|
372
393
|
@property
|
@@ -19,7 +19,7 @@ modal/app.py,sha256=e-zwazkqvbtv0eXnIWQnfBW_v9g_6S9a8CGh1Bzr5HU,45423
|
|
19
19
|
modal/app.pyi,sha256=3h538rJ0Z2opldsKLuQhDnvop05TfzNG-Uw_n9rEHa4,25197
|
20
20
|
modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
|
21
21
|
modal/client.py,sha256=JAnd4-GCN093BwkvOFAK5a6iy5ycxofjpUncMxlrIMw,15253
|
22
|
-
modal/client.pyi,sha256=
|
22
|
+
modal/client.pyi,sha256=TcmFzBzBi5CDGun6ZTmON8TFf7rBIS2_QCai9JTbUIA,7280
|
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=ONnrfZ2vPcaY2JuKypPiBA9eTiyg8Qfg-Ull40nn9zs,30956
|
@@ -33,8 +33,8 @@ modal/environments.py,sha256=5cgA-zbm6ngKLsRA19zSOgtgo9-BarJK3FJK0BiF2Lo,6505
|
|
33
33
|
modal/environments.pyi,sha256=XalNpiPkAtHWAvOU2Cotq0ozmtl-Jv0FDsR8h9mr27Q,3521
|
34
34
|
modal/exception.py,sha256=dRK789TD1HaB63kHhu1yZuvS2vP_Vua3iLMBtA6dgqk,7128
|
35
35
|
modal/experimental.py,sha256=jFuNbwrNHos47viMB9q-cHJSvf2RDxDdoEcss9plaZE,2302
|
36
|
-
modal/file_io.py,sha256=
|
37
|
-
modal/file_io.pyi,sha256=
|
36
|
+
modal/file_io.py,sha256=pDOFNQU5m-x-k3oJauck4fOp3bZ55Vc-_LvSaN5_Bow,16465
|
37
|
+
modal/file_io.pyi,sha256=GMhCCRyMftXYI3HqI9EdGPOx70CbCNi-VC5Sfy5TYnc,7631
|
38
38
|
modal/file_pattern_matcher.py,sha256=vX6MjWRGdonE4I8QPdjFUnz6moBjSzvgD6417BNQrW4,4021
|
39
39
|
modal/functions.py,sha256=IIdHw0FNOdoMksG1b2zvkn8f-xskhJu07ZvHMey9iq4,67667
|
40
40
|
modal/functions.pyi,sha256=bHbJiWW5TbFKKjDn7bSCFvOcUcAjPFqTStS-NAHPSeM,25068
|
@@ -63,8 +63,8 @@ modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
|
|
63
63
|
modal/runner.py,sha256=Q02VdfLCO7YKpnOSqqh58XL3hR2XHaDeiJVYW3MKz_8,24580
|
64
64
|
modal/runner.pyi,sha256=BvMS1ZVzWSn8B8q0KnIZOJKPkN5L-i5b-USbV6SWWHQ,5177
|
65
65
|
modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
|
66
|
-
modal/sandbox.py,sha256=
|
67
|
-
modal/sandbox.pyi,sha256=
|
66
|
+
modal/sandbox.py,sha256=yoiBbUzUGnCnDauoMkHLNjzsyHenhM1NFk0poXq_Wv4,28043
|
67
|
+
modal/sandbox.pyi,sha256=k8_vHjN3oigxSCF13Cm2HfcSHuliGuSb8ryd3CGqwoA,19815
|
68
68
|
modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
|
69
69
|
modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
|
70
70
|
modal/secret.py,sha256=Y1WgybQIkfkxdzH9CQ1h-Wd1DJJpzipigMhyyvSxTww,10007
|
@@ -163,10 +163,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
|
|
163
163
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
164
164
|
modal_version/__init__.py,sha256=RT6zPoOdFO99u5Wcxxaoir4ZCuPTbQ22cvzFAXl3vUY,470
|
165
165
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
166
|
-
modal_version/_version_generated.py,sha256
|
167
|
-
modal-0.68.
|
168
|
-
modal-0.68.
|
169
|
-
modal-0.68.
|
170
|
-
modal-0.68.
|
171
|
-
modal-0.68.
|
172
|
-
modal-0.68.
|
166
|
+
modal_version/_version_generated.py,sha256=rCrKUIX9RlDkBXIhxZbfOSQ7GhlTnQx5fyFV4xz8l2M,149
|
167
|
+
modal-0.68.28.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
168
|
+
modal-0.68.28.dist-info/METADATA,sha256=4XYesHFd9NjVz8TZumQ1NyHdDGeO2Wphy-G_cWttZcI,2329
|
169
|
+
modal-0.68.28.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
170
|
+
modal-0.68.28.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
171
|
+
modal-0.68.28.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
|
172
|
+
modal-0.68.28.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|