modal 0.72.4__py3-none-any.whl → 0.72.48__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/_container_entrypoint.py +5 -10
- modal/_object.py +297 -0
- modal/_resolver.py +7 -5
- modal/_runtime/container_io_manager.py +0 -11
- modal/_runtime/user_code_imports.py +7 -7
- modal/_serialization.py +4 -3
- modal/_tunnel.py +1 -1
- modal/app.py +14 -61
- modal/app.pyi +25 -25
- modal/cli/app.py +3 -2
- modal/cli/container.py +1 -1
- modal/cli/import_refs.py +185 -113
- modal/cli/launch.py +10 -5
- modal/cli/programs/run_jupyter.py +2 -2
- modal/cli/programs/vscode.py +3 -3
- modal/cli/run.py +134 -68
- modal/client.py +1 -0
- modal/client.pyi +18 -14
- modal/cloud_bucket_mount.py +4 -0
- modal/cloud_bucket_mount.pyi +4 -0
- modal/cls.py +33 -5
- modal/cls.pyi +20 -5
- modal/container_process.pyi +8 -6
- modal/dict.py +1 -1
- modal/dict.pyi +32 -29
- modal/environments.py +1 -1
- modal/environments.pyi +2 -1
- modal/experimental.py +47 -11
- modal/experimental.pyi +29 -0
- modal/file_io.pyi +30 -28
- modal/file_pattern_matcher.py +32 -25
- modal/functions.py +31 -23
- modal/functions.pyi +57 -50
- modal/gpu.py +19 -26
- modal/image.py +47 -19
- modal/image.pyi +28 -21
- modal/io_streams.pyi +14 -12
- modal/mount.py +14 -5
- modal/mount.pyi +28 -25
- modal/network_file_system.py +7 -7
- modal/network_file_system.pyi +27 -24
- modal/object.py +2 -265
- modal/object.pyi +46 -130
- modal/parallel_map.py +2 -2
- modal/parallel_map.pyi +10 -7
- modal/partial_function.py +22 -3
- modal/partial_function.pyi +45 -27
- modal/proxy.py +1 -1
- modal/proxy.pyi +2 -1
- modal/queue.py +1 -1
- modal/queue.pyi +26 -23
- modal/runner.py +14 -3
- modal/sandbox.py +11 -7
- modal/sandbox.pyi +30 -27
- modal/secret.py +1 -1
- modal/secret.pyi +2 -1
- modal/token_flow.pyi +6 -4
- modal/volume.py +1 -1
- modal/volume.pyi +36 -33
- {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/METADATA +2 -2
- {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/RECORD +73 -71
- modal_proto/api.proto +151 -4
- modal_proto/api_grpc.py +113 -0
- modal_proto/api_pb2.py +998 -795
- modal_proto/api_pb2.pyi +430 -11
- modal_proto/api_pb2_grpc.py +233 -1
- modal_proto/api_pb2_grpc.pyi +75 -3
- modal_proto/modal_api_grpc.py +7 -0
- modal_version/_version_generated.py +1 -1
- {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/LICENSE +0 -0
- {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/WHEEL +0 -0
- {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/entry_points.txt +0 -0
- {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/top_level.txt +0 -0
modal/queue.pyi
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import collections.abc
|
2
|
+
import modal._object
|
2
3
|
import modal.client
|
3
4
|
import modal.object
|
4
5
|
import synchronicity.combined_types
|
5
6
|
import typing
|
6
7
|
import typing_extensions
|
7
8
|
|
8
|
-
class _Queue(modal.
|
9
|
+
class _Queue(modal._object._Object):
|
9
10
|
def __init__(self): ...
|
10
11
|
@staticmethod
|
11
12
|
def validate_partition_key(partition: typing.Optional[str]) -> bytes: ...
|
@@ -84,6 +85,8 @@ class _Queue(modal.object._Object):
|
|
84
85
|
self, *, partition: typing.Optional[str] = None, item_poll_timeout: float = 0.0
|
85
86
|
) -> collections.abc.AsyncGenerator[typing.Any, None]: ...
|
86
87
|
|
88
|
+
SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
|
89
|
+
|
87
90
|
class Queue(modal.object.Object):
|
88
91
|
def __init__(self): ...
|
89
92
|
@staticmethod
|
@@ -138,13 +141,13 @@ class Queue(modal.object.Object):
|
|
138
141
|
|
139
142
|
delete: __delete_spec
|
140
143
|
|
141
|
-
class ___get_nonblocking_spec(typing_extensions.Protocol):
|
144
|
+
class ___get_nonblocking_spec(typing_extensions.Protocol[SUPERSELF]):
|
142
145
|
def __call__(self, partition: typing.Optional[str], n_values: int) -> list[typing.Any]: ...
|
143
146
|
async def aio(self, partition: typing.Optional[str], n_values: int) -> list[typing.Any]: ...
|
144
147
|
|
145
|
-
_get_nonblocking: ___get_nonblocking_spec
|
148
|
+
_get_nonblocking: ___get_nonblocking_spec[typing_extensions.Self]
|
146
149
|
|
147
|
-
class ___get_blocking_spec(typing_extensions.Protocol):
|
150
|
+
class ___get_blocking_spec(typing_extensions.Protocol[SUPERSELF]):
|
148
151
|
def __call__(
|
149
152
|
self, partition: typing.Optional[str], timeout: typing.Optional[float], n_values: int
|
150
153
|
) -> list[typing.Any]: ...
|
@@ -152,15 +155,15 @@ class Queue(modal.object.Object):
|
|
152
155
|
self, partition: typing.Optional[str], timeout: typing.Optional[float], n_values: int
|
153
156
|
) -> list[typing.Any]: ...
|
154
157
|
|
155
|
-
_get_blocking: ___get_blocking_spec
|
158
|
+
_get_blocking: ___get_blocking_spec[typing_extensions.Self]
|
156
159
|
|
157
|
-
class __clear_spec(typing_extensions.Protocol):
|
160
|
+
class __clear_spec(typing_extensions.Protocol[SUPERSELF]):
|
158
161
|
def __call__(self, *, partition: typing.Optional[str] = None, all: bool = False) -> None: ...
|
159
162
|
async def aio(self, *, partition: typing.Optional[str] = None, all: bool = False) -> None: ...
|
160
163
|
|
161
|
-
clear: __clear_spec
|
164
|
+
clear: __clear_spec[typing_extensions.Self]
|
162
165
|
|
163
|
-
class __get_spec(typing_extensions.Protocol):
|
166
|
+
class __get_spec(typing_extensions.Protocol[SUPERSELF]):
|
164
167
|
def __call__(
|
165
168
|
self, block: bool = True, timeout: typing.Optional[float] = None, *, partition: typing.Optional[str] = None
|
166
169
|
) -> typing.Optional[typing.Any]: ...
|
@@ -168,9 +171,9 @@ class Queue(modal.object.Object):
|
|
168
171
|
self, block: bool = True, timeout: typing.Optional[float] = None, *, partition: typing.Optional[str] = None
|
169
172
|
) -> typing.Optional[typing.Any]: ...
|
170
173
|
|
171
|
-
get: __get_spec
|
174
|
+
get: __get_spec[typing_extensions.Self]
|
172
175
|
|
173
|
-
class __get_many_spec(typing_extensions.Protocol):
|
176
|
+
class __get_many_spec(typing_extensions.Protocol[SUPERSELF]):
|
174
177
|
def __call__(
|
175
178
|
self,
|
176
179
|
n_values: int,
|
@@ -188,9 +191,9 @@ class Queue(modal.object.Object):
|
|
188
191
|
partition: typing.Optional[str] = None,
|
189
192
|
) -> list[typing.Any]: ...
|
190
193
|
|
191
|
-
get_many: __get_many_spec
|
194
|
+
get_many: __get_many_spec[typing_extensions.Self]
|
192
195
|
|
193
|
-
class __put_spec(typing_extensions.Protocol):
|
196
|
+
class __put_spec(typing_extensions.Protocol[SUPERSELF]):
|
194
197
|
def __call__(
|
195
198
|
self,
|
196
199
|
v: typing.Any,
|
@@ -210,9 +213,9 @@ class Queue(modal.object.Object):
|
|
210
213
|
partition_ttl: int = 86400,
|
211
214
|
) -> None: ...
|
212
215
|
|
213
|
-
put: __put_spec
|
216
|
+
put: __put_spec[typing_extensions.Self]
|
214
217
|
|
215
|
-
class __put_many_spec(typing_extensions.Protocol):
|
218
|
+
class __put_many_spec(typing_extensions.Protocol[SUPERSELF]):
|
216
219
|
def __call__(
|
217
220
|
self,
|
218
221
|
vs: list[typing.Any],
|
@@ -232,9 +235,9 @@ class Queue(modal.object.Object):
|
|
232
235
|
partition_ttl: int = 86400,
|
233
236
|
) -> None: ...
|
234
237
|
|
235
|
-
put_many: __put_many_spec
|
238
|
+
put_many: __put_many_spec[typing_extensions.Self]
|
236
239
|
|
237
|
-
class ___put_many_blocking_spec(typing_extensions.Protocol):
|
240
|
+
class ___put_many_blocking_spec(typing_extensions.Protocol[SUPERSELF]):
|
238
241
|
def __call__(
|
239
242
|
self,
|
240
243
|
partition: typing.Optional[str],
|
@@ -250,21 +253,21 @@ class Queue(modal.object.Object):
|
|
250
253
|
timeout: typing.Optional[float] = None,
|
251
254
|
): ...
|
252
255
|
|
253
|
-
_put_many_blocking: ___put_many_blocking_spec
|
256
|
+
_put_many_blocking: ___put_many_blocking_spec[typing_extensions.Self]
|
254
257
|
|
255
|
-
class ___put_many_nonblocking_spec(typing_extensions.Protocol):
|
258
|
+
class ___put_many_nonblocking_spec(typing_extensions.Protocol[SUPERSELF]):
|
256
259
|
def __call__(self, partition: typing.Optional[str], partition_ttl: int, vs: list[typing.Any]): ...
|
257
260
|
async def aio(self, partition: typing.Optional[str], partition_ttl: int, vs: list[typing.Any]): ...
|
258
261
|
|
259
|
-
_put_many_nonblocking: ___put_many_nonblocking_spec
|
262
|
+
_put_many_nonblocking: ___put_many_nonblocking_spec[typing_extensions.Self]
|
260
263
|
|
261
|
-
class __len_spec(typing_extensions.Protocol):
|
264
|
+
class __len_spec(typing_extensions.Protocol[SUPERSELF]):
|
262
265
|
def __call__(self, *, partition: typing.Optional[str] = None, total: bool = False) -> int: ...
|
263
266
|
async def aio(self, *, partition: typing.Optional[str] = None, total: bool = False) -> int: ...
|
264
267
|
|
265
|
-
len: __len_spec
|
268
|
+
len: __len_spec[typing_extensions.Self]
|
266
269
|
|
267
|
-
class __iterate_spec(typing_extensions.Protocol):
|
270
|
+
class __iterate_spec(typing_extensions.Protocol[SUPERSELF]):
|
268
271
|
def __call__(
|
269
272
|
self, *, partition: typing.Optional[str] = None, item_poll_timeout: float = 0.0
|
270
273
|
) -> typing.Generator[typing.Any, None, None]: ...
|
@@ -272,4 +275,4 @@ class Queue(modal.object.Object):
|
|
272
275
|
self, *, partition: typing.Optional[str] = None, item_poll_timeout: float = 0.0
|
273
276
|
) -> collections.abc.AsyncGenerator[typing.Any, None]: ...
|
274
277
|
|
275
|
-
iterate: __iterate_spec
|
278
|
+
iterate: __iterate_spec[typing_extensions.Self]
|
modal/runner.py
CHANGED
@@ -4,6 +4,7 @@ import dataclasses
|
|
4
4
|
import os
|
5
5
|
import time
|
6
6
|
import typing
|
7
|
+
import warnings
|
7
8
|
from collections.abc import AsyncGenerator
|
8
9
|
from multiprocessing.synchronize import Event
|
9
10
|
from typing import TYPE_CHECKING, Any, Optional, TypeVar
|
@@ -14,6 +15,7 @@ from synchronicity.async_wrap import asynccontextmanager
|
|
14
15
|
import modal_proto.api_pb2
|
15
16
|
from modal_proto import api_pb2
|
16
17
|
|
18
|
+
from ._object import _get_environment_name, _Object
|
17
19
|
from ._pty import get_pty_info
|
18
20
|
from ._resolver import Resolver
|
19
21
|
from ._runtime.execution_context import is_local
|
@@ -28,7 +30,6 @@ from .config import config, logger
|
|
28
30
|
from .environments import _get_environment_cached
|
29
31
|
from .exception import InteractiveTimeoutError, InvalidError, RemoteError, _CliUserExecutionError
|
30
32
|
from .functions import _Function
|
31
|
-
from .object import _get_environment_name, _Object
|
32
33
|
from .output import _get_output_manager, enable_output
|
33
34
|
from .running_app import RunningApp, running_app_from_layout
|
34
35
|
from .sandbox import _Sandbox
|
@@ -155,7 +156,7 @@ async def _create_all_objects(
|
|
155
156
|
# this is to ensure that directly referenced functions from the global scope has
|
156
157
|
# ids associated with them when they are serialized into other functions
|
157
158
|
await resolver.preload(obj, existing_object_id)
|
158
|
-
if obj.
|
159
|
+
if obj.is_hydrated:
|
159
160
|
tag_to_object_id[tag] = obj.object_id
|
160
161
|
|
161
162
|
await TaskContext.gather(*(_preload(tag, obj) for tag, obj in indexed_objects.items()))
|
@@ -287,6 +288,16 @@ async def _run_app(
|
|
287
288
|
client = await _Client.from_env()
|
288
289
|
|
289
290
|
app_state = api_pb2.APP_STATE_DETACHED if detach else api_pb2.APP_STATE_EPHEMERAL
|
291
|
+
|
292
|
+
output_mgr = _get_output_manager()
|
293
|
+
if interactive and output_mgr is None:
|
294
|
+
warnings.warn(
|
295
|
+
"Interactive mode is disabled because no output manager is active. "
|
296
|
+
"Use 'with modal.enable_output():' to enable interactive mode and see logs.",
|
297
|
+
stacklevel=2,
|
298
|
+
)
|
299
|
+
interactive = False
|
300
|
+
|
290
301
|
running_app: RunningApp = await _init_local_app_new(
|
291
302
|
client,
|
292
303
|
app.description or "",
|
@@ -306,7 +317,7 @@ async def _run_app(
|
|
306
317
|
tc.infinite_loop(heartbeat, sleep=HEARTBEAT_INTERVAL, log_exception=not detach)
|
307
318
|
logs_loop: Optional[asyncio.Task] = None
|
308
319
|
|
309
|
-
if output_mgr
|
320
|
+
if output_mgr is not None:
|
310
321
|
# Defer import so this module is rich-safe
|
311
322
|
# TODO(michael): The get_app_logs_loop function is itself rich-safe aside from accepting an OutputManager
|
312
323
|
# as an argument, so with some refactoring we could avoid the need for this deferred import.
|
modal/sandbox.py
CHANGED
@@ -16,9 +16,10 @@ from modal.volume import _Volume
|
|
16
16
|
from modal_proto import api_pb2
|
17
17
|
|
18
18
|
from ._location import parse_cloud_provider
|
19
|
+
from ._object import _get_environment_name, _Object
|
19
20
|
from ._resolver import Resolver
|
20
21
|
from ._resources import convert_fn_config_to_resources_config
|
21
|
-
from ._utils.async_utils import synchronize_api
|
22
|
+
from ._utils.async_utils import TaskContext, synchronize_api
|
22
23
|
from ._utils.deprecation import deprecation_error
|
23
24
|
from ._utils.grpc_utils import retry_transient_errors
|
24
25
|
from ._utils.mount_utils import validate_network_file_systems, validate_volumes
|
@@ -32,7 +33,6 @@ from .image import _Image
|
|
32
33
|
from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
|
33
34
|
from .mount import _Mount
|
34
35
|
from .network_file_system import _NetworkFileSystem, network_file_system_mount_protos
|
35
|
-
from .object import _get_environment_name, _Object
|
36
36
|
from .proxy import _Proxy
|
37
37
|
from .scheduler_placement import SchedulerPlacement
|
38
38
|
from .secret import _Secret
|
@@ -165,7 +165,8 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
165
165
|
resources=convert_fn_config_to_resources_config(
|
166
166
|
cpu=cpu, memory=memory, gpu=gpu, ephemeral_disk=ephemeral_disk
|
167
167
|
),
|
168
|
-
cloud_provider=parse_cloud_provider(cloud) if cloud else None,
|
168
|
+
cloud_provider=parse_cloud_provider(cloud) if cloud else None, # Deprecated at some point
|
169
|
+
cloud_provider_str=cloud.upper() if cloud else None, # Supersedes cloud_provider
|
169
170
|
nfs_mounts=network_file_system_mount_protos(validated_network_file_systems, False),
|
170
171
|
runtime_debug=config.get("function_runtime_debug"),
|
171
172
|
cloud_bucket_mounts=cloud_bucket_mounts_to_proto(cloud_bucket_mounts),
|
@@ -350,6 +351,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
350
351
|
Returns an [`Image`](https://modal.com/docs/reference/modal.Image) object which
|
351
352
|
can be used to spawn a new Sandbox with the same filesystem.
|
352
353
|
"""
|
354
|
+
await self._get_task_id() # Ensure the sandbox has started
|
353
355
|
req = api_pb2.SandboxSnapshotFsRequest(sandbox_id=self.object_id, timeout=timeout)
|
354
356
|
resp = await retry_transient_errors(self._client.stub.SandboxSnapshotFs, req)
|
355
357
|
|
@@ -360,10 +362,12 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
360
362
|
metadata = resp.image_metadata
|
361
363
|
|
362
364
|
async def _load(self: _Image, resolver: Resolver, existing_object_id: Optional[str]):
|
363
|
-
|
365
|
+
# no need to hydrate again since we do it eagerly below
|
366
|
+
pass
|
364
367
|
|
365
368
|
rep = "Image()"
|
366
|
-
image = _Image._from_loader(_load, rep)
|
369
|
+
image = _Image._from_loader(_load, rep, hydrate_lazily=True)
|
370
|
+
image._hydrate(image_id, self._client, metadata) # hydrating eagerly since we have all of the data
|
367
371
|
|
368
372
|
return image
|
369
373
|
|
@@ -513,8 +517,8 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
513
517
|
raise InvalidError(f"workdir must be an absolute path, got: {workdir}")
|
514
518
|
|
515
519
|
# Force secret resolution so we can pass the secret IDs to the backend.
|
516
|
-
for secret in secrets
|
517
|
-
|
520
|
+
secret_coros = [secret.hydrate(client=self._client) for secret in secrets]
|
521
|
+
await TaskContext.gather(*secret_coros)
|
518
522
|
|
519
523
|
task_id = await self._get_task_id()
|
520
524
|
req = api_pb2.ContainerExecRequest(
|
modal/sandbox.pyi
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import _typeshed
|
2
2
|
import collections.abc
|
3
3
|
import google.protobuf.message
|
4
|
+
import modal._object
|
4
5
|
import modal._tunnel
|
5
6
|
import modal.app
|
6
7
|
import modal.client
|
@@ -23,7 +24,7 @@ import os
|
|
23
24
|
import typing
|
24
25
|
import typing_extensions
|
25
26
|
|
26
|
-
class _Sandbox(modal.
|
27
|
+
class _Sandbox(modal._object._Object):
|
27
28
|
_result: typing.Optional[modal_proto.api_pb2.GenericResult]
|
28
29
|
_stdout: modal.io_streams._StreamReader[str]
|
29
30
|
_stderr: modal.io_streams._StreamReader[str]
|
@@ -154,6 +155,8 @@ class _Sandbox(modal.object._Object):
|
|
154
155
|
client: typing.Optional[modal.client._Client] = None,
|
155
156
|
) -> collections.abc.AsyncGenerator[_Sandbox, None]: ...
|
156
157
|
|
158
|
+
SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
|
159
|
+
|
157
160
|
class Sandbox(modal.object.Object):
|
158
161
|
_result: typing.Optional[modal_proto.api_pb2.GenericResult]
|
159
162
|
_stdout: modal.io_streams.StreamReader[str]
|
@@ -263,49 +266,49 @@ class Sandbox(modal.object.Object):
|
|
263
266
|
|
264
267
|
from_id: __from_id_spec
|
265
268
|
|
266
|
-
class __set_tags_spec(typing_extensions.Protocol):
|
269
|
+
class __set_tags_spec(typing_extensions.Protocol[SUPERSELF]):
|
267
270
|
def __call__(self, tags: dict[str, str], *, client: typing.Optional[modal.client.Client] = None): ...
|
268
271
|
async def aio(self, tags: dict[str, str], *, client: typing.Optional[modal.client.Client] = None): ...
|
269
272
|
|
270
|
-
set_tags: __set_tags_spec
|
273
|
+
set_tags: __set_tags_spec[typing_extensions.Self]
|
271
274
|
|
272
|
-
class __snapshot_filesystem_spec(typing_extensions.Protocol):
|
275
|
+
class __snapshot_filesystem_spec(typing_extensions.Protocol[SUPERSELF]):
|
273
276
|
def __call__(self, timeout: int = 55) -> modal.image.Image: ...
|
274
277
|
async def aio(self, timeout: int = 55) -> modal.image.Image: ...
|
275
278
|
|
276
|
-
snapshot_filesystem: __snapshot_filesystem_spec
|
279
|
+
snapshot_filesystem: __snapshot_filesystem_spec[typing_extensions.Self]
|
277
280
|
|
278
|
-
class __wait_spec(typing_extensions.Protocol):
|
281
|
+
class __wait_spec(typing_extensions.Protocol[SUPERSELF]):
|
279
282
|
def __call__(self, raise_on_termination: bool = True): ...
|
280
283
|
async def aio(self, raise_on_termination: bool = True): ...
|
281
284
|
|
282
|
-
wait: __wait_spec
|
285
|
+
wait: __wait_spec[typing_extensions.Self]
|
283
286
|
|
284
|
-
class __tunnels_spec(typing_extensions.Protocol):
|
287
|
+
class __tunnels_spec(typing_extensions.Protocol[SUPERSELF]):
|
285
288
|
def __call__(self, timeout: int = 50) -> dict[int, modal._tunnel.Tunnel]: ...
|
286
289
|
async def aio(self, timeout: int = 50) -> dict[int, modal._tunnel.Tunnel]: ...
|
287
290
|
|
288
|
-
tunnels: __tunnels_spec
|
291
|
+
tunnels: __tunnels_spec[typing_extensions.Self]
|
289
292
|
|
290
|
-
class __terminate_spec(typing_extensions.Protocol):
|
293
|
+
class __terminate_spec(typing_extensions.Protocol[SUPERSELF]):
|
291
294
|
def __call__(self): ...
|
292
295
|
async def aio(self): ...
|
293
296
|
|
294
|
-
terminate: __terminate_spec
|
297
|
+
terminate: __terminate_spec[typing_extensions.Self]
|
295
298
|
|
296
|
-
class __poll_spec(typing_extensions.Protocol):
|
299
|
+
class __poll_spec(typing_extensions.Protocol[SUPERSELF]):
|
297
300
|
def __call__(self) -> typing.Optional[int]: ...
|
298
301
|
async def aio(self) -> typing.Optional[int]: ...
|
299
302
|
|
300
|
-
poll: __poll_spec
|
303
|
+
poll: __poll_spec[typing_extensions.Self]
|
301
304
|
|
302
|
-
class ___get_task_id_spec(typing_extensions.Protocol):
|
305
|
+
class ___get_task_id_spec(typing_extensions.Protocol[SUPERSELF]):
|
303
306
|
def __call__(self): ...
|
304
307
|
async def aio(self): ...
|
305
308
|
|
306
|
-
_get_task_id: ___get_task_id_spec
|
309
|
+
_get_task_id: ___get_task_id_spec[typing_extensions.Self]
|
307
310
|
|
308
|
-
class __exec_spec(typing_extensions.Protocol):
|
311
|
+
class __exec_spec(typing_extensions.Protocol[SUPERSELF]):
|
309
312
|
@typing.overload
|
310
313
|
def __call__(
|
311
314
|
self,
|
@@ -363,9 +366,9 @@ class Sandbox(modal.object.Object):
|
|
363
366
|
_pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
|
364
367
|
) -> modal.container_process.ContainerProcess[bytes]: ...
|
365
368
|
|
366
|
-
exec: __exec_spec
|
369
|
+
exec: __exec_spec[typing_extensions.Self]
|
367
370
|
|
368
|
-
class __open_spec(typing_extensions.Protocol):
|
371
|
+
class __open_spec(typing_extensions.Protocol[SUPERSELF]):
|
369
372
|
@typing.overload
|
370
373
|
def __call__(self, path: str, mode: _typeshed.OpenTextMode) -> modal.file_io.FileIO[str]: ...
|
371
374
|
@typing.overload
|
@@ -375,27 +378,27 @@ class Sandbox(modal.object.Object):
|
|
375
378
|
@typing.overload
|
376
379
|
async def aio(self, path: str, mode: _typeshed.OpenBinaryMode) -> modal.file_io.FileIO[bytes]: ...
|
377
380
|
|
378
|
-
open: __open_spec
|
381
|
+
open: __open_spec[typing_extensions.Self]
|
379
382
|
|
380
|
-
class __ls_spec(typing_extensions.Protocol):
|
383
|
+
class __ls_spec(typing_extensions.Protocol[SUPERSELF]):
|
381
384
|
def __call__(self, path: str) -> list[str]: ...
|
382
385
|
async def aio(self, path: str) -> list[str]: ...
|
383
386
|
|
384
|
-
ls: __ls_spec
|
387
|
+
ls: __ls_spec[typing_extensions.Self]
|
385
388
|
|
386
|
-
class __mkdir_spec(typing_extensions.Protocol):
|
389
|
+
class __mkdir_spec(typing_extensions.Protocol[SUPERSELF]):
|
387
390
|
def __call__(self, path: str, parents: bool = False) -> None: ...
|
388
391
|
async def aio(self, path: str, parents: bool = False) -> None: ...
|
389
392
|
|
390
|
-
mkdir: __mkdir_spec
|
393
|
+
mkdir: __mkdir_spec[typing_extensions.Self]
|
391
394
|
|
392
|
-
class __rm_spec(typing_extensions.Protocol):
|
395
|
+
class __rm_spec(typing_extensions.Protocol[SUPERSELF]):
|
393
396
|
def __call__(self, path: str, recursive: bool = False) -> None: ...
|
394
397
|
async def aio(self, path: str, recursive: bool = False) -> None: ...
|
395
398
|
|
396
|
-
rm: __rm_spec
|
399
|
+
rm: __rm_spec[typing_extensions.Self]
|
397
400
|
|
398
|
-
class __watch_spec(typing_extensions.Protocol):
|
401
|
+
class __watch_spec(typing_extensions.Protocol[SUPERSELF]):
|
399
402
|
def __call__(
|
400
403
|
self,
|
401
404
|
path: str,
|
@@ -411,7 +414,7 @@ class Sandbox(modal.object.Object):
|
|
411
414
|
timeout: typing.Optional[int] = None,
|
412
415
|
) -> typing.AsyncIterator[modal.file_io.FileWatchEvent]: ...
|
413
416
|
|
414
|
-
watch: __watch_spec
|
417
|
+
watch: __watch_spec[typing_extensions.Self]
|
415
418
|
|
416
419
|
@property
|
417
420
|
def stdout(self) -> modal.io_streams.StreamReader[str]: ...
|
modal/secret.py
CHANGED
@@ -6,6 +6,7 @@ from grpclib import GRPCError, Status
|
|
6
6
|
|
7
7
|
from modal_proto import api_pb2
|
8
8
|
|
9
|
+
from ._object import _get_environment_name, _Object
|
9
10
|
from ._resolver import Resolver
|
10
11
|
from ._runtime.execution_context import is_local
|
11
12
|
from ._utils.async_utils import synchronize_api
|
@@ -14,7 +15,6 @@ from ._utils.grpc_utils import retry_transient_errors
|
|
14
15
|
from ._utils.name_utils import check_object_name
|
15
16
|
from .client import _Client
|
16
17
|
from .exception import InvalidError, NotFoundError
|
17
|
-
from .object import _get_environment_name, _Object
|
18
18
|
|
19
19
|
ENV_DICT_WRONG_TYPE_ERR = "the env_dict argument to Secret has to be a dict[str, Union[str, None]]"
|
20
20
|
|
modal/secret.pyi
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
import modal._object
|
1
2
|
import modal.client
|
2
3
|
import modal.object
|
3
4
|
import typing
|
4
5
|
import typing_extensions
|
5
6
|
|
6
|
-
class _Secret(modal.
|
7
|
+
class _Secret(modal._object._Object):
|
7
8
|
@staticmethod
|
8
9
|
def from_dict(env_dict: dict[str, typing.Optional[str]] = {}): ...
|
9
10
|
@staticmethod
|
modal/token_flow.pyi
CHANGED
@@ -13,10 +13,12 @@ class _TokenFlow:
|
|
13
13
|
self, timeout: float = 40.0, grpc_extra_timeout: float = 5.0
|
14
14
|
) -> typing.Optional[modal_proto.api_pb2.TokenFlowWaitResponse]: ...
|
15
15
|
|
16
|
+
SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
|
17
|
+
|
16
18
|
class TokenFlow:
|
17
19
|
def __init__(self, client: modal.client.Client): ...
|
18
20
|
|
19
|
-
class __start_spec(typing_extensions.Protocol):
|
21
|
+
class __start_spec(typing_extensions.Protocol[SUPERSELF]):
|
20
22
|
def __call__(
|
21
23
|
self, utm_source: typing.Optional[str] = None, next_url: typing.Optional[str] = None
|
22
24
|
) -> synchronicity.combined_types.AsyncAndBlockingContextManager[tuple[str, str, str]]: ...
|
@@ -24,9 +26,9 @@ class TokenFlow:
|
|
24
26
|
self, utm_source: typing.Optional[str] = None, next_url: typing.Optional[str] = None
|
25
27
|
) -> typing.AsyncContextManager[tuple[str, str, str]]: ...
|
26
28
|
|
27
|
-
start: __start_spec
|
29
|
+
start: __start_spec[typing_extensions.Self]
|
28
30
|
|
29
|
-
class __finish_spec(typing_extensions.Protocol):
|
31
|
+
class __finish_spec(typing_extensions.Protocol[SUPERSELF]):
|
30
32
|
def __call__(
|
31
33
|
self, timeout: float = 40.0, grpc_extra_timeout: float = 5.0
|
32
34
|
) -> typing.Optional[modal_proto.api_pb2.TokenFlowWaitResponse]: ...
|
@@ -34,7 +36,7 @@ class TokenFlow:
|
|
34
36
|
self, timeout: float = 40.0, grpc_extra_timeout: float = 5.0
|
35
37
|
) -> typing.Optional[modal_proto.api_pb2.TokenFlowWaitResponse]: ...
|
36
38
|
|
37
|
-
finish: __finish_spec
|
39
|
+
finish: __finish_spec[typing_extensions.Self]
|
38
40
|
|
39
41
|
async def _new_token(
|
40
42
|
*,
|
modal/volume.py
CHANGED
@@ -27,6 +27,7 @@ import modal_proto.api_pb2
|
|
27
27
|
from modal.exception import VolumeUploadTimeoutError
|
28
28
|
from modal_proto import api_pb2
|
29
29
|
|
30
|
+
from ._object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
|
30
31
|
from ._resolver import Resolver
|
31
32
|
from ._utils.async_utils import TaskContext, aclosing, async_map, asyncnullcontext, synchronize_api
|
32
33
|
from ._utils.blob_utils import (
|
@@ -41,7 +42,6 @@ from ._utils.grpc_utils import retry_transient_errors
|
|
41
42
|
from ._utils.name_utils import check_object_name
|
42
43
|
from .client import _Client
|
43
44
|
from .config import logger
|
44
|
-
from .object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
|
45
45
|
|
46
46
|
# Max duration for uploading to volumes files
|
47
47
|
# As a guide, files >40GiB will take >10 minutes to upload.
|
modal/volume.pyi
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import asyncio.locks
|
2
2
|
import collections.abc
|
3
3
|
import enum
|
4
|
+
import modal._object
|
4
5
|
import modal._utils.blob_utils
|
5
6
|
import modal.client
|
6
7
|
import modal.object
|
@@ -33,7 +34,7 @@ class FileEntry:
|
|
33
34
|
def __delattr__(self, name): ...
|
34
35
|
def __hash__(self): ...
|
35
36
|
|
36
|
-
class _Volume(modal.
|
37
|
+
class _Volume(modal._object._Object):
|
37
38
|
_lock: typing.Optional[asyncio.locks.Lock]
|
38
39
|
|
39
40
|
async def _get_lock(self): ...
|
@@ -98,16 +99,16 @@ class _VolumeUploadContextManager:
|
|
98
99
|
_volume_id: str
|
99
100
|
_client: modal.client._Client
|
100
101
|
_force: bool
|
101
|
-
progress_cb:
|
102
|
+
progress_cb: collections.abc.Callable[..., typing.Any]
|
102
103
|
_upload_generators: list[
|
103
|
-
collections.abc.Generator[
|
104
|
+
collections.abc.Generator[collections.abc.Callable[[], modal._utils.blob_utils.FileUploadSpec], None, None]
|
104
105
|
]
|
105
106
|
|
106
107
|
def __init__(
|
107
108
|
self,
|
108
109
|
volume_id: str,
|
109
110
|
client: modal.client._Client,
|
110
|
-
progress_cb: typing.Optional[
|
111
|
+
progress_cb: typing.Optional[collections.abc.Callable[..., typing.Any]] = None,
|
111
112
|
force: bool = False,
|
112
113
|
): ...
|
113
114
|
async def __aenter__(self): ...
|
@@ -128,16 +129,18 @@ class _VolumeUploadContextManager:
|
|
128
129
|
self, file_spec: modal._utils.blob_utils.FileUploadSpec
|
129
130
|
) -> modal_proto.api_pb2.MountFile: ...
|
130
131
|
|
132
|
+
SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
|
133
|
+
|
131
134
|
class Volume(modal.object.Object):
|
132
135
|
_lock: typing.Optional[asyncio.locks.Lock]
|
133
136
|
|
134
137
|
def __init__(self, *args, **kwargs): ...
|
135
138
|
|
136
|
-
class ___get_lock_spec(typing_extensions.Protocol):
|
139
|
+
class ___get_lock_spec(typing_extensions.Protocol[SUPERSELF]):
|
137
140
|
def __call__(self): ...
|
138
141
|
async def aio(self): ...
|
139
142
|
|
140
|
-
_get_lock: ___get_lock_spec
|
143
|
+
_get_lock: ___get_lock_spec[typing_extensions.Self]
|
141
144
|
|
142
145
|
@staticmethod
|
143
146
|
def from_name(
|
@@ -198,71 +201,71 @@ class Volume(modal.object.Object):
|
|
198
201
|
|
199
202
|
create_deployed: __create_deployed_spec
|
200
203
|
|
201
|
-
class ___do_reload_spec(typing_extensions.Protocol):
|
204
|
+
class ___do_reload_spec(typing_extensions.Protocol[SUPERSELF]):
|
202
205
|
def __call__(self, lock=True): ...
|
203
206
|
async def aio(self, lock=True): ...
|
204
207
|
|
205
|
-
_do_reload: ___do_reload_spec
|
208
|
+
_do_reload: ___do_reload_spec[typing_extensions.Self]
|
206
209
|
|
207
|
-
class __commit_spec(typing_extensions.Protocol):
|
210
|
+
class __commit_spec(typing_extensions.Protocol[SUPERSELF]):
|
208
211
|
def __call__(self): ...
|
209
212
|
async def aio(self): ...
|
210
213
|
|
211
|
-
commit: __commit_spec
|
214
|
+
commit: __commit_spec[typing_extensions.Self]
|
212
215
|
|
213
|
-
class __reload_spec(typing_extensions.Protocol):
|
216
|
+
class __reload_spec(typing_extensions.Protocol[SUPERSELF]):
|
214
217
|
def __call__(self): ...
|
215
218
|
async def aio(self): ...
|
216
219
|
|
217
|
-
reload: __reload_spec
|
220
|
+
reload: __reload_spec[typing_extensions.Self]
|
218
221
|
|
219
|
-
class __iterdir_spec(typing_extensions.Protocol):
|
222
|
+
class __iterdir_spec(typing_extensions.Protocol[SUPERSELF]):
|
220
223
|
def __call__(self, path: str, *, recursive: bool = True) -> typing.Iterator[FileEntry]: ...
|
221
224
|
def aio(self, path: str, *, recursive: bool = True) -> collections.abc.AsyncIterator[FileEntry]: ...
|
222
225
|
|
223
|
-
iterdir: __iterdir_spec
|
226
|
+
iterdir: __iterdir_spec[typing_extensions.Self]
|
224
227
|
|
225
|
-
class __listdir_spec(typing_extensions.Protocol):
|
228
|
+
class __listdir_spec(typing_extensions.Protocol[SUPERSELF]):
|
226
229
|
def __call__(self, path: str, *, recursive: bool = False) -> list[FileEntry]: ...
|
227
230
|
async def aio(self, path: str, *, recursive: bool = False) -> list[FileEntry]: ...
|
228
231
|
|
229
|
-
listdir: __listdir_spec
|
232
|
+
listdir: __listdir_spec[typing_extensions.Self]
|
230
233
|
|
231
|
-
class __read_file_spec(typing_extensions.Protocol):
|
234
|
+
class __read_file_spec(typing_extensions.Protocol[SUPERSELF]):
|
232
235
|
def __call__(self, path: str) -> typing.Iterator[bytes]: ...
|
233
236
|
def aio(self, path: str) -> collections.abc.AsyncIterator[bytes]: ...
|
234
237
|
|
235
|
-
read_file: __read_file_spec
|
238
|
+
read_file: __read_file_spec[typing_extensions.Self]
|
236
239
|
|
237
|
-
class __read_file_into_fileobj_spec(typing_extensions.Protocol):
|
240
|
+
class __read_file_into_fileobj_spec(typing_extensions.Protocol[SUPERSELF]):
|
238
241
|
def __call__(self, path: str, fileobj: typing.IO[bytes]) -> int: ...
|
239
242
|
async def aio(self, path: str, fileobj: typing.IO[bytes]) -> int: ...
|
240
243
|
|
241
|
-
read_file_into_fileobj: __read_file_into_fileobj_spec
|
244
|
+
read_file_into_fileobj: __read_file_into_fileobj_spec[typing_extensions.Self]
|
242
245
|
|
243
|
-
class __remove_file_spec(typing_extensions.Protocol):
|
246
|
+
class __remove_file_spec(typing_extensions.Protocol[SUPERSELF]):
|
244
247
|
def __call__(self, path: str, recursive: bool = False) -> None: ...
|
245
248
|
async def aio(self, path: str, recursive: bool = False) -> None: ...
|
246
249
|
|
247
|
-
remove_file: __remove_file_spec
|
250
|
+
remove_file: __remove_file_spec[typing_extensions.Self]
|
248
251
|
|
249
|
-
class __copy_files_spec(typing_extensions.Protocol):
|
252
|
+
class __copy_files_spec(typing_extensions.Protocol[SUPERSELF]):
|
250
253
|
def __call__(self, src_paths: collections.abc.Sequence[str], dst_path: str) -> None: ...
|
251
254
|
async def aio(self, src_paths: collections.abc.Sequence[str], dst_path: str) -> None: ...
|
252
255
|
|
253
|
-
copy_files: __copy_files_spec
|
256
|
+
copy_files: __copy_files_spec[typing_extensions.Self]
|
254
257
|
|
255
|
-
class __batch_upload_spec(typing_extensions.Protocol):
|
258
|
+
class __batch_upload_spec(typing_extensions.Protocol[SUPERSELF]):
|
256
259
|
def __call__(self, force: bool = False) -> VolumeUploadContextManager: ...
|
257
260
|
async def aio(self, force: bool = False) -> VolumeUploadContextManager: ...
|
258
261
|
|
259
|
-
batch_upload: __batch_upload_spec
|
262
|
+
batch_upload: __batch_upload_spec[typing_extensions.Self]
|
260
263
|
|
261
|
-
class ___instance_delete_spec(typing_extensions.Protocol):
|
264
|
+
class ___instance_delete_spec(typing_extensions.Protocol[SUPERSELF]):
|
262
265
|
def __call__(self): ...
|
263
266
|
async def aio(self): ...
|
264
267
|
|
265
|
-
_instance_delete: ___instance_delete_spec
|
268
|
+
_instance_delete: ___instance_delete_spec[typing_extensions.Self]
|
266
269
|
|
267
270
|
class __delete_spec(typing_extensions.Protocol):
|
268
271
|
def __call__(
|
@@ -304,16 +307,16 @@ class VolumeUploadContextManager:
|
|
304
307
|
_volume_id: str
|
305
308
|
_client: modal.client.Client
|
306
309
|
_force: bool
|
307
|
-
progress_cb:
|
310
|
+
progress_cb: collections.abc.Callable[..., typing.Any]
|
308
311
|
_upload_generators: list[
|
309
|
-
collections.abc.Generator[
|
312
|
+
collections.abc.Generator[collections.abc.Callable[[], modal._utils.blob_utils.FileUploadSpec], None, None]
|
310
313
|
]
|
311
314
|
|
312
315
|
def __init__(
|
313
316
|
self,
|
314
317
|
volume_id: str,
|
315
318
|
client: modal.client.Client,
|
316
|
-
progress_cb: typing.Optional[
|
319
|
+
progress_cb: typing.Optional[collections.abc.Callable[..., typing.Any]] = None,
|
317
320
|
force: bool = False,
|
318
321
|
): ...
|
319
322
|
def __enter__(self): ...
|
@@ -333,10 +336,10 @@ class VolumeUploadContextManager:
|
|
333
336
|
recursive: bool = True,
|
334
337
|
): ...
|
335
338
|
|
336
|
-
class ___upload_file_spec(typing_extensions.Protocol):
|
339
|
+
class ___upload_file_spec(typing_extensions.Protocol[SUPERSELF]):
|
337
340
|
def __call__(self, file_spec: modal._utils.blob_utils.FileUploadSpec) -> modal_proto.api_pb2.MountFile: ...
|
338
341
|
async def aio(self, file_spec: modal._utils.blob_utils.FileUploadSpec) -> modal_proto.api_pb2.MountFile: ...
|
339
342
|
|
340
|
-
_upload_file: ___upload_file_spec
|
343
|
+
_upload_file: ___upload_file_spec[typing_extensions.Self]
|
341
344
|
|
342
345
|
def _open_files_error_annotation(mount_path: str) -> typing.Optional[str]: ...
|