modal 0.72.20__py3-none-any.whl → 0.72.22__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 +1 -1
- modal/_object.py +279 -0
- modal/_resolver.py +7 -5
- modal/_runtime/user_code_imports.py +7 -7
- modal/_serialization.py +4 -3
- modal/_tunnel.py +1 -1
- modal/app.py +1 -1
- modal/app.pyi +4 -3
- modal/cli/app.py +1 -1
- modal/cli/container.py +1 -1
- modal/client.py +1 -0
- modal/client.pyi +4 -2
- modal/cls.py +1 -1
- modal/cls.pyi +2 -1
- modal/dict.py +1 -1
- modal/dict.pyi +2 -1
- modal/environments.py +1 -1
- modal/environments.pyi +2 -1
- modal/functions.py +18 -20
- modal/functions.pyi +7 -6
- modal/image.py +16 -10
- modal/image.pyi +2 -1
- modal/mount.py +14 -5
- modal/mount.pyi +2 -1
- modal/network_file_system.py +7 -7
- modal/network_file_system.pyi +2 -1
- modal/object.py +2 -265
- modal/object.pyi +30 -122
- modal/proxy.py +1 -1
- modal/proxy.pyi +2 -1
- modal/queue.py +1 -1
- modal/queue.pyi +2 -1
- modal/runner.py +2 -2
- modal/sandbox.py +1 -1
- modal/sandbox.pyi +2 -1
- modal/secret.py +1 -1
- modal/secret.pyi +2 -1
- modal/volume.py +1 -1
- modal/volume.pyi +2 -1
- {modal-0.72.20.dist-info → modal-0.72.22.dist-info}/METADATA +1 -1
- {modal-0.72.20.dist-info → modal-0.72.22.dist-info}/RECORD +46 -45
- modal_version/_version_generated.py +1 -1
- {modal-0.72.20.dist-info → modal-0.72.22.dist-info}/LICENSE +0 -0
- {modal-0.72.20.dist-info → modal-0.72.22.dist-info}/WHEEL +0 -0
- {modal-0.72.20.dist-info → modal-0.72.22.dist-info}/entry_points.txt +0 -0
- {modal-0.72.20.dist-info → modal-0.72.22.dist-info}/top_level.txt +0 -0
modal/functions.py
CHANGED
@@ -26,6 +26,7 @@ from modal_proto import api_pb2
|
|
26
26
|
from modal_proto.modal_api_grpc import ModalClientModal
|
27
27
|
|
28
28
|
from ._location import parse_cloud_provider
|
29
|
+
from ._object import _get_environment_name, _Object, live_method, live_method_gen
|
29
30
|
from ._pty import get_pty_info
|
30
31
|
from ._resolver import Resolver
|
31
32
|
from ._resources import convert_fn_config_to_resources_config
|
@@ -71,7 +72,6 @@ from .gpu import GPU_T, parse_gpu_config
|
|
71
72
|
from .image import _Image
|
72
73
|
from .mount import _get_client_mount, _Mount, get_auto_mounts
|
73
74
|
from .network_file_system import _NetworkFileSystem, network_file_system_mount_protos
|
74
|
-
from .object import _get_environment_name, _Object, live_method, live_method_gen
|
75
75
|
from .output import _get_output_manager
|
76
76
|
from .parallel_map import (
|
77
77
|
_for_each_async,
|
@@ -388,7 +388,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
388
388
|
_is_method: bool
|
389
389
|
_spec: Optional[_FunctionSpec] = None
|
390
390
|
_tag: str
|
391
|
-
_raw_f: Callable[..., Any]
|
391
|
+
_raw_f: Optional[Callable[..., Any]] # this is set to None for a "class service [function]"
|
392
392
|
_build_args: dict
|
393
393
|
|
394
394
|
_is_generator: Optional[bool] = None
|
@@ -474,7 +474,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
474
474
|
_experimental_buffer_containers: Optional[int] = None,
|
475
475
|
_experimental_proxy_ip: Optional[str] = None,
|
476
476
|
_experimental_custom_scaling_factor: Optional[float] = None,
|
477
|
-
) ->
|
477
|
+
) -> "_Function":
|
478
478
|
"""mdmd:hidden"""
|
479
479
|
# Needed to avoid circular imports
|
480
480
|
from .partial_function import _find_partial_methods_for_user_cls, _PartialFunctionFlags
|
@@ -573,7 +573,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
573
573
|
)
|
574
574
|
image = _Image._from_args(
|
575
575
|
base_images={"base": image},
|
576
|
-
build_function=snapshot_function,
|
576
|
+
build_function=snapshot_function, # type: ignore # TODO: separate functions.py and _functions.py
|
577
577
|
force_build=image.force_build or pf.force_build,
|
578
578
|
)
|
579
579
|
|
@@ -962,7 +962,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
962
962
|
f"The {identity} has not been hydrated with the metadata it needs to run on Modal{reason}."
|
963
963
|
)
|
964
964
|
|
965
|
-
assert parent._client.stub
|
965
|
+
assert parent._client and parent._client.stub
|
966
966
|
|
967
967
|
if can_use_parent:
|
968
968
|
# We can end up here if parent wasn't hydrated when class was instantiated, but has been since.
|
@@ -983,9 +983,9 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
983
983
|
else:
|
984
984
|
serialized_params = serialize((args, kwargs))
|
985
985
|
environment_name = _get_environment_name(None, resolver)
|
986
|
-
assert parent is not None
|
986
|
+
assert parent is not None and parent.is_hydrated
|
987
987
|
req = api_pb2.FunctionBindParamsRequest(
|
988
|
-
function_id=parent.
|
988
|
+
function_id=parent.object_id,
|
989
989
|
serialized_params=serialized_params,
|
990
990
|
function_options=options,
|
991
991
|
environment_name=environment_name
|
@@ -1032,11 +1032,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1032
1032
|
"""
|
1033
1033
|
)
|
1034
1034
|
)
|
1035
|
-
assert self._client and self._client.stub
|
1036
1035
|
request = api_pb2.FunctionUpdateSchedulingParamsRequest(
|
1037
|
-
function_id=self.
|
1036
|
+
function_id=self.object_id, warm_pool_size_override=warm_pool_size
|
1038
1037
|
)
|
1039
|
-
await retry_transient_errors(self.
|
1038
|
+
await retry_transient_errors(self.client.stub.FunctionUpdateSchedulingParams, request)
|
1040
1039
|
|
1041
1040
|
@classmethod
|
1042
1041
|
@renamed_parameter((2024, 12, 18), "tag", "name")
|
@@ -1142,7 +1141,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1142
1141
|
"""mdmd:hidden"""
|
1143
1142
|
# Plaintext source and arg definition for the function, so it's part of the image
|
1144
1143
|
# hash. We can't use the cloudpickle hash because it's not very stable.
|
1145
|
-
assert hasattr(self, "_raw_f") and hasattr(self, "_build_args")
|
1144
|
+
assert hasattr(self, "_raw_f") and hasattr(self, "_build_args") and self._raw_f is not None
|
1146
1145
|
return f"{inspect.getsource(self._raw_f)}\n{repr(self._build_args)}"
|
1147
1146
|
|
1148
1147
|
# Live handle methods
|
@@ -1248,7 +1247,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1248
1247
|
_map_invocation(
|
1249
1248
|
self, # type: ignore
|
1250
1249
|
input_queue,
|
1251
|
-
self.
|
1250
|
+
self.client,
|
1252
1251
|
order_outputs,
|
1253
1252
|
return_exceptions,
|
1254
1253
|
count_update_callback,
|
@@ -1266,7 +1265,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1266
1265
|
self,
|
1267
1266
|
args,
|
1268
1267
|
kwargs,
|
1269
|
-
client=self.
|
1268
|
+
client=self.client,
|
1270
1269
|
function_call_invocation_type=function_call_invocation_type,
|
1271
1270
|
)
|
1272
1271
|
|
@@ -1276,7 +1275,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1276
1275
|
self, args, kwargs, function_call_invocation_type: "api_pb2.FunctionCallInvocationType.ValueType"
|
1277
1276
|
) -> _Invocation:
|
1278
1277
|
return await _Invocation.create(
|
1279
|
-
self, args, kwargs, client=self.
|
1278
|
+
self, args, kwargs, client=self.client, function_call_invocation_type=function_call_invocation_type
|
1280
1279
|
)
|
1281
1280
|
|
1282
1281
|
@warn_if_generator_is_not_consumed()
|
@@ -1287,7 +1286,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1287
1286
|
self,
|
1288
1287
|
args,
|
1289
1288
|
kwargs,
|
1290
|
-
client=self.
|
1289
|
+
client=self.client,
|
1291
1290
|
function_call_invocation_type=api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC_LEGACY,
|
1292
1291
|
)
|
1293
1292
|
async for res in invocation.run_generator():
|
@@ -1303,7 +1302,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1303
1302
|
self,
|
1304
1303
|
args,
|
1305
1304
|
kwargs,
|
1306
|
-
client=self.
|
1305
|
+
client=self.client,
|
1307
1306
|
function_call_invocation_type=api_pb2.FUNCTION_CALL_INVOCATION_TYPE_ASYNC_LEGACY,
|
1308
1307
|
)
|
1309
1308
|
|
@@ -1452,14 +1451,14 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
1452
1451
|
|
1453
1452
|
def get_raw_f(self) -> Callable[..., Any]:
|
1454
1453
|
"""Return the inner Python object wrapped by this Modal Function."""
|
1454
|
+
assert self._raw_f is not None
|
1455
1455
|
return self._raw_f
|
1456
1456
|
|
1457
1457
|
@live_method
|
1458
1458
|
async def get_current_stats(self) -> FunctionStats:
|
1459
1459
|
"""Return a `FunctionStats` object describing the current function's queue and runner counts."""
|
1460
|
-
assert self._client.stub
|
1461
1460
|
resp = await retry_transient_errors(
|
1462
|
-
self.
|
1461
|
+
self.client.stub.FunctionGetCurrentStats,
|
1463
1462
|
api_pb2.FunctionGetCurrentStatsRequest(function_id=self.object_id),
|
1464
1463
|
total_timeout=10.0,
|
1465
1464
|
)
|
@@ -1491,8 +1490,7 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
|
|
1491
1490
|
_is_generator: bool = False
|
1492
1491
|
|
1493
1492
|
def _invocation(self):
|
1494
|
-
|
1495
|
-
return _Invocation(self._client.stub, self.object_id, self._client)
|
1493
|
+
return _Invocation(self.client.stub, self.object_id, self.client)
|
1496
1494
|
|
1497
1495
|
async def get(self, timeout: Optional[float] = None) -> ReturnType:
|
1498
1496
|
"""Get the result of the function call.
|
modal/functions.pyi
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import collections.abc
|
2
2
|
import google.protobuf.message
|
3
|
+
import modal._object
|
3
4
|
import modal._utils.async_utils
|
4
5
|
import modal._utils.function_utils
|
5
6
|
import modal.app
|
@@ -133,7 +134,7 @@ ReturnType = typing.TypeVar("ReturnType", covariant=True)
|
|
133
134
|
|
134
135
|
OriginalReturnType = typing.TypeVar("OriginalReturnType", covariant=True)
|
135
136
|
|
136
|
-
class _Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.
|
137
|
+
class _Function(typing.Generic[P, ReturnType, OriginalReturnType], modal._object._Object):
|
137
138
|
_info: typing.Optional[modal._utils.function_utils.FunctionInfo]
|
138
139
|
_serve_mounts: frozenset[modal.mount._Mount]
|
139
140
|
_app: typing.Optional[modal.app._App]
|
@@ -143,7 +144,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.
|
|
143
144
|
_is_method: bool
|
144
145
|
_spec: typing.Optional[_FunctionSpec]
|
145
146
|
_tag: str
|
146
|
-
_raw_f: typing.Callable[..., typing.Any]
|
147
|
+
_raw_f: typing.Optional[typing.Callable[..., typing.Any]]
|
147
148
|
_build_args: dict
|
148
149
|
_is_generator: typing.Optional[bool]
|
149
150
|
_cluster_size: typing.Optional[int]
|
@@ -197,7 +198,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.
|
|
197
198
|
_experimental_buffer_containers: typing.Optional[int] = None,
|
198
199
|
_experimental_proxy_ip: typing.Optional[str] = None,
|
199
200
|
_experimental_custom_scaling_factor: typing.Optional[float] = None,
|
200
|
-
) ->
|
201
|
+
) -> _Function: ...
|
201
202
|
def _bind_parameters(
|
202
203
|
self,
|
203
204
|
obj: modal.cls._Obj,
|
@@ -311,7 +312,7 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
|
|
311
312
|
_is_method: bool
|
312
313
|
_spec: typing.Optional[_FunctionSpec]
|
313
314
|
_tag: str
|
314
|
-
_raw_f: typing.Callable[..., typing.Any]
|
315
|
+
_raw_f: typing.Optional[typing.Callable[..., typing.Any]]
|
315
316
|
_build_args: dict
|
316
317
|
_is_generator: typing.Optional[bool]
|
317
318
|
_cluster_size: typing.Optional[int]
|
@@ -366,7 +367,7 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
|
|
366
367
|
_experimental_buffer_containers: typing.Optional[int] = None,
|
367
368
|
_experimental_proxy_ip: typing.Optional[str] = None,
|
368
369
|
_experimental_custom_scaling_factor: typing.Optional[float] = None,
|
369
|
-
) ->
|
370
|
+
) -> Function: ...
|
370
371
|
def _bind_parameters(
|
371
372
|
self,
|
372
373
|
obj: modal.cls.Obj,
|
@@ -539,7 +540,7 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
|
|
539
540
|
|
540
541
|
for_each: __for_each_spec
|
541
542
|
|
542
|
-
class _FunctionCall(typing.Generic[ReturnType], modal.
|
543
|
+
class _FunctionCall(typing.Generic[ReturnType], modal._object._Object):
|
543
544
|
_is_generator: bool
|
544
545
|
|
545
546
|
def _invocation(self): ...
|
modal/image.py
CHANGED
@@ -26,6 +26,7 @@ from grpclib.exceptions import GRPCError, StreamTerminatedError
|
|
26
26
|
|
27
27
|
from modal_proto import api_pb2
|
28
28
|
|
29
|
+
from ._object import _Object, live_method_gen
|
29
30
|
from ._resolver import Resolver
|
30
31
|
from ._serialization import serialize
|
31
32
|
from ._utils.async_utils import synchronize_api
|
@@ -46,7 +47,6 @@ from .file_pattern_matcher import NON_PYTHON_FILES, FilePatternMatcher, _ignore_
|
|
46
47
|
from .gpu import GPU_T, parse_gpu_config
|
47
48
|
from .mount import _Mount, python_standalone_mount_name
|
48
49
|
from .network_file_system import _NetworkFileSystem
|
49
|
-
from .object import _Object, live_method_gen
|
50
50
|
from .output import _get_output_manager
|
51
51
|
from .scheduler_placement import SchedulerPlacement
|
52
52
|
from .secret import _Secret
|
@@ -662,13 +662,16 @@ class _Image(_Object, type_prefix="im"):
|
|
662
662
|
return obj
|
663
663
|
|
664
664
|
def copy_mount(self, mount: _Mount, remote_path: Union[str, Path] = ".") -> "_Image":
|
665
|
-
"""
|
665
|
+
"""
|
666
|
+
**Deprecated**: Use image.add_local_dir(..., copy=True) or similar instead.
|
667
|
+
|
668
|
+
Copy the entire contents of a `modal.Mount` into an image.
|
666
669
|
Useful when files only available locally are required during the image
|
667
670
|
build process.
|
668
671
|
|
669
672
|
**Example**
|
670
673
|
|
671
|
-
```python
|
674
|
+
```python notest
|
672
675
|
static_images_dir = "./static"
|
673
676
|
# place all static images in root of mount
|
674
677
|
mount = modal.Mount.from_local_dir(static_images_dir, remote_path="/")
|
@@ -851,14 +854,17 @@ class _Image(_Object, type_prefix="im"):
|
|
851
854
|
# Which follows dockerignore syntax.
|
852
855
|
ignore: Union[Sequence[str], Callable[[Path], bool]] = [],
|
853
856
|
) -> "_Image":
|
854
|
-
"""
|
857
|
+
"""
|
858
|
+
**Deprecated**: Use image.add_local_dir instead
|
859
|
+
|
860
|
+
Copy a directory into the image as a part of building the image.
|
855
861
|
|
856
862
|
This works in a similar way to [`COPY`](https://docs.docker.com/engine/reference/builder/#copy)
|
857
863
|
works in a `Dockerfile`.
|
858
864
|
|
859
865
|
**Usage:**
|
860
866
|
|
861
|
-
```python
|
867
|
+
```python notest
|
862
868
|
from pathlib import Path
|
863
869
|
from modal import FilePatternMatcher
|
864
870
|
|
@@ -2047,11 +2053,11 @@ class _Image(_Object, type_prefix="im"):
|
|
2047
2053
|
try:
|
2048
2054
|
yield
|
2049
2055
|
except Exception as exc:
|
2050
|
-
if self.
|
2051
|
-
# Might be
|
2056
|
+
if not self.is_hydrated:
|
2057
|
+
# Might be hydrated later
|
2052
2058
|
self.inside_exceptions.append(exc)
|
2053
2059
|
elif env_image_id == self.object_id:
|
2054
|
-
# Image is already
|
2060
|
+
# Image is already hydrated (we can remove this case later
|
2055
2061
|
# when we don't hydrate objects so early)
|
2056
2062
|
raise
|
2057
2063
|
if not isinstance(exc, ImportError):
|
@@ -2066,9 +2072,9 @@ class _Image(_Object, type_prefix="im"):
|
|
2066
2072
|
last_entry_id: str = ""
|
2067
2073
|
|
2068
2074
|
request = api_pb2.ImageJoinStreamingRequest(
|
2069
|
-
image_id=self.
|
2075
|
+
image_id=self.object_id, timeout=55, last_entry_id=last_entry_id, include_logs_for_finished=True
|
2070
2076
|
)
|
2071
|
-
async for response in self.
|
2077
|
+
async for response in self.client.stub.ImageJoinStreaming.unary_stream(request):
|
2072
2078
|
if response.result.status:
|
2073
2079
|
return
|
2074
2080
|
if response.entry_id:
|
modal/image.pyi
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import collections.abc
|
2
2
|
import google.protobuf.message
|
3
|
+
import modal._object
|
3
4
|
import modal.client
|
4
5
|
import modal.cloud_bucket_mount
|
5
6
|
import modal.functions
|
@@ -78,7 +79,7 @@ async def _image_await_build_result(
|
|
78
79
|
image_id: str, client: modal.client._Client
|
79
80
|
) -> modal_proto.api_pb2.ImageJoinStreamingResponse: ...
|
80
81
|
|
81
|
-
class _Image(modal.
|
82
|
+
class _Image(modal._object._Object):
|
82
83
|
force_build: bool
|
83
84
|
inside_exceptions: list[Exception]
|
84
85
|
_serve_mounts: frozenset[modal.mount._Mount]
|
modal/mount.py
CHANGED
@@ -20,6 +20,7 @@ import modal.file_pattern_matcher
|
|
20
20
|
from modal_proto import api_pb2
|
21
21
|
from modal_version import __version__
|
22
22
|
|
23
|
+
from ._object import _get_environment_name, _Object
|
23
24
|
from ._resolver import Resolver
|
24
25
|
from ._utils.async_utils import aclosing, async_map, synchronize_api
|
25
26
|
from ._utils.blob_utils import FileUploadSpec, blob_upload_file, get_file_upload_spec_from_path
|
@@ -31,7 +32,6 @@ from .client import _Client
|
|
31
32
|
from .config import config, logger
|
32
33
|
from .exception import InvalidError, ModuleNotMountable
|
33
34
|
from .file_pattern_matcher import FilePatternMatcher
|
34
|
-
from .object import _get_environment_name, _Object
|
35
35
|
|
36
36
|
ROOT_DIR: PurePosixPath = PurePosixPath("/root")
|
37
37
|
MOUNT_PUT_FILE_CLIENT_TIMEOUT = 10 * 60 # 10 min max for transferring files
|
@@ -258,12 +258,15 @@ class NonLocalMountError(Exception):
|
|
258
258
|
|
259
259
|
|
260
260
|
class _Mount(_Object, type_prefix="mo"):
|
261
|
-
"""
|
261
|
+
"""
|
262
|
+
**Deprecated**: Mounts should not be used explicitly anymore, use image.add_local_* commands instead
|
263
|
+
|
264
|
+
Create a mount for a local directory or file that can be attached
|
262
265
|
to one or more Modal functions.
|
263
266
|
|
264
267
|
**Usage**
|
265
268
|
|
266
|
-
```python
|
269
|
+
```python notest
|
267
270
|
import modal
|
268
271
|
import os
|
269
272
|
app = modal.App()
|
@@ -394,11 +397,13 @@ class _Mount(_Object, type_prefix="mo"):
|
|
394
397
|
recursive: bool = True,
|
395
398
|
) -> "_Mount":
|
396
399
|
"""
|
400
|
+
**Deprecated:** Use image.add_local_dir() instead
|
401
|
+
|
397
402
|
Create a `Mount` from a local directory.
|
398
403
|
|
399
404
|
**Usage**
|
400
405
|
|
401
|
-
```python
|
406
|
+
```python notest
|
402
407
|
assets = modal.Mount.from_local_dir(
|
403
408
|
"~/assets",
|
404
409
|
condition=lambda pth: not ".venv" in pth,
|
@@ -449,11 +454,13 @@ class _Mount(_Object, type_prefix="mo"):
|
|
449
454
|
@staticmethod
|
450
455
|
def from_local_file(local_path: Union[str, Path], remote_path: Union[str, PurePosixPath, None] = None) -> "_Mount":
|
451
456
|
"""
|
457
|
+
**Deprecated**: Use image.add_local_file() instead
|
458
|
+
|
452
459
|
Create a `Mount` mounting a single local file.
|
453
460
|
|
454
461
|
**Usage**
|
455
462
|
|
456
|
-
```python
|
463
|
+
```python notest
|
457
464
|
# Mount the DBT profile in user's home directory into container.
|
458
465
|
dbt_profiles = modal.Mount.from_local_file(
|
459
466
|
local_path="~/profiles.yml",
|
@@ -611,6 +618,8 @@ class _Mount(_Object, type_prefix="mo"):
|
|
611
618
|
ignore: Optional[Union[Sequence[str], Callable[[Path], bool]]] = None,
|
612
619
|
) -> "_Mount":
|
613
620
|
"""
|
621
|
+
**Deprecated**: Use image.add_local_python_source instead
|
622
|
+
|
614
623
|
Returns a `modal.Mount` that makes local modules listed in `module_names` available inside the container.
|
615
624
|
This works by mounting the local path of each module's package to a directory inside the container
|
616
625
|
that's on `PYTHONPATH`.
|
modal/mount.pyi
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import collections.abc
|
2
2
|
import google.protobuf.message
|
3
|
+
import modal._object
|
3
4
|
import modal._resolver
|
4
5
|
import modal._utils.blob_utils
|
5
6
|
import modal.client
|
@@ -76,7 +77,7 @@ class _MountedPythonModule(_MountEntry):
|
|
76
77
|
|
77
78
|
class NonLocalMountError(Exception): ...
|
78
79
|
|
79
|
-
class _Mount(modal.
|
80
|
+
class _Mount(modal._object._Object):
|
80
81
|
_entries: typing.Optional[list[_MountEntry]]
|
81
82
|
_deployment_name: typing.Optional[str]
|
82
83
|
_namespace: typing.Optional[int]
|
modal/network_file_system.py
CHANGED
@@ -12,6 +12,13 @@ from synchronicity.async_wrap import asynccontextmanager
|
|
12
12
|
import modal
|
13
13
|
from modal_proto import api_pb2
|
14
14
|
|
15
|
+
from ._object import (
|
16
|
+
EPHEMERAL_OBJECT_HEARTBEAT_SLEEP,
|
17
|
+
_get_environment_name,
|
18
|
+
_Object,
|
19
|
+
live_method,
|
20
|
+
live_method_gen,
|
21
|
+
)
|
15
22
|
from ._resolver import Resolver
|
16
23
|
from ._utils.async_utils import TaskContext, aclosing, async_map, sync_or_async_iter, synchronize_api
|
17
24
|
from ._utils.blob_utils import LARGE_FILE_LIMIT, blob_iter, blob_upload_file
|
@@ -21,13 +28,6 @@ from ._utils.hash_utils import get_sha256_hex
|
|
21
28
|
from ._utils.name_utils import check_object_name
|
22
29
|
from .client import _Client
|
23
30
|
from .exception import InvalidError
|
24
|
-
from .object import (
|
25
|
-
EPHEMERAL_OBJECT_HEARTBEAT_SLEEP,
|
26
|
-
_get_environment_name,
|
27
|
-
_Object,
|
28
|
-
live_method,
|
29
|
-
live_method_gen,
|
30
|
-
)
|
31
31
|
from .volume import FileEntry
|
32
32
|
|
33
33
|
NETWORK_FILE_SYSTEM_PUT_FILE_CLIENT_TIMEOUT = (
|
modal/network_file_system.pyi
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import collections.abc
|
2
|
+
import modal._object
|
2
3
|
import modal.client
|
3
4
|
import modal.object
|
4
5
|
import modal.volume
|
@@ -12,7 +13,7 @@ def network_file_system_mount_protos(
|
|
12
13
|
validated_network_file_systems: list[tuple[str, _NetworkFileSystem]], allow_cross_region_volumes: bool
|
13
14
|
) -> list[modal_proto.api_pb2.SharedVolumeMount]: ...
|
14
15
|
|
15
|
-
class _NetworkFileSystem(modal.
|
16
|
+
class _NetworkFileSystem(modal._object._Object):
|
16
17
|
@staticmethod
|
17
18
|
def from_name(
|
18
19
|
name: str, namespace=1, environment_name: typing.Optional[str] = None, create_if_missing: bool = False
|