modal 1.0.6.dev35__py3-none-any.whl → 1.0.6.dev37__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.
Potentially problematic release.
This version of modal might be problematic. Click here for more details.
- modal/__init__.py +0 -2
- modal/_functions.py +2 -29
- modal/_partial_function.py +1 -56
- modal/client.pyi +2 -2
- modal/image.py +0 -94
- modal/image.pyi +0 -132
- modal/partial_function.py +0 -2
- modal/partial_function.pyi +0 -29
- {modal-1.0.6.dev35.dist-info → modal-1.0.6.dev37.dist-info}/METADATA +1 -1
- {modal-1.0.6.dev35.dist-info → modal-1.0.6.dev37.dist-info}/RECORD +22 -22
- modal_proto/api.proto +14 -0
- modal_proto/api_grpc.py +16 -0
- modal_proto/api_pb2.py +322 -302
- modal_proto/api_pb2.pyi +43 -3
- modal_proto/api_pb2_grpc.py +33 -0
- modal_proto/api_pb2_grpc.pyi +10 -0
- modal_proto/modal_api_grpc.py +1 -0
- modal_version/__init__.py +1 -1
- {modal-1.0.6.dev35.dist-info → modal-1.0.6.dev37.dist-info}/WHEEL +0 -0
- {modal-1.0.6.dev35.dist-info → modal-1.0.6.dev37.dist-info}/entry_points.txt +0 -0
- {modal-1.0.6.dev35.dist-info → modal-1.0.6.dev37.dist-info}/licenses/LICENSE +0 -0
- {modal-1.0.6.dev35.dist-info → modal-1.0.6.dev37.dist-info}/top_level.txt +0 -0
modal/__init__.py
CHANGED
|
@@ -25,7 +25,6 @@ try:
|
|
|
25
25
|
from .partial_function import (
|
|
26
26
|
asgi_app,
|
|
27
27
|
batched,
|
|
28
|
-
build,
|
|
29
28
|
concurrent,
|
|
30
29
|
enter,
|
|
31
30
|
exit,
|
|
@@ -80,7 +79,6 @@ __all__ = [
|
|
|
80
79
|
"Volume",
|
|
81
80
|
"asgi_app",
|
|
82
81
|
"batched",
|
|
83
|
-
"build",
|
|
84
82
|
"concurrent",
|
|
85
83
|
"current_function_call_id",
|
|
86
84
|
"current_input_id",
|
modal/_functions.py
CHANGED
|
@@ -460,6 +460,7 @@ class _InputPlaneInvocation:
|
|
|
460
460
|
token = await client._auth_token_manager.get_token()
|
|
461
461
|
return [("x-modal-input-plane-region", input_plane_region), ("x-modal-auth-token", token)]
|
|
462
462
|
|
|
463
|
+
|
|
463
464
|
# Wrapper type for api_pb2.FunctionStats
|
|
464
465
|
@dataclass(frozen=True)
|
|
465
466
|
class FunctionStats:
|
|
@@ -659,34 +660,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
659
660
|
proxy=proxy,
|
|
660
661
|
)
|
|
661
662
|
|
|
662
|
-
if info.user_cls and not is_auto_snapshot:
|
|
663
|
-
build_functions = _find_partial_methods_for_user_cls(info.user_cls, _PartialFunctionFlags.BUILD).items()
|
|
664
|
-
for k, pf in build_functions:
|
|
665
|
-
build_function = pf.raw_f
|
|
666
|
-
snapshot_info = FunctionInfo(build_function, user_cls=info.user_cls)
|
|
667
|
-
snapshot_function = _Function.from_local(
|
|
668
|
-
snapshot_info,
|
|
669
|
-
app=None,
|
|
670
|
-
image=image,
|
|
671
|
-
secrets=secrets,
|
|
672
|
-
gpu=gpu,
|
|
673
|
-
network_file_systems=network_file_systems,
|
|
674
|
-
volumes=volumes,
|
|
675
|
-
memory=memory,
|
|
676
|
-
timeout=pf.params.build_timeout,
|
|
677
|
-
cpu=cpu,
|
|
678
|
-
ephemeral_disk=ephemeral_disk,
|
|
679
|
-
is_builder_function=True,
|
|
680
|
-
is_auto_snapshot=True,
|
|
681
|
-
scheduler_placement=scheduler_placement,
|
|
682
|
-
include_source=include_source,
|
|
683
|
-
)
|
|
684
|
-
image = _Image._from_args(
|
|
685
|
-
base_images={"base": image},
|
|
686
|
-
build_function=snapshot_function,
|
|
687
|
-
force_build=image.force_build or bool(pf.params.force_build),
|
|
688
|
-
)
|
|
689
|
-
|
|
690
663
|
# Note that we also do these checks in FunctionCreate; could drop them here
|
|
691
664
|
if min_containers is not None and not isinstance(min_containers, int):
|
|
692
665
|
raise InvalidError(f"`min_containers` must be an int, not {type(min_containers).__name__}")
|
|
@@ -746,7 +719,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
746
719
|
validated_network_file_systems = validate_network_file_systems(network_file_systems)
|
|
747
720
|
|
|
748
721
|
# Validate image
|
|
749
|
-
if image is not None and not isinstance(image, _Image):
|
|
722
|
+
if image is not None and not isinstance(image, _Image): # type: ignore[unreachable]
|
|
750
723
|
raise InvalidError(f"Expected modal.Image object. Got {type(image)}.")
|
|
751
724
|
|
|
752
725
|
method_definitions: Optional[dict[str, api_pb2.MethodDefinition]] = None
|
modal/_partial_function.py
CHANGED
|
@@ -31,7 +31,6 @@ if typing.TYPE_CHECKING:
|
|
|
31
31
|
|
|
32
32
|
class _PartialFunctionFlags(enum.IntFlag):
|
|
33
33
|
# Lifecycle method flags
|
|
34
|
-
BUILD = 1 # Deprecated, will be removed
|
|
35
34
|
ENTER_PRE_SNAPSHOT = 2
|
|
36
35
|
ENTER_POST_SNAPSHOT = 4
|
|
37
36
|
EXIT = 8
|
|
@@ -55,8 +54,7 @@ class _PartialFunctionFlags(enum.IntFlag):
|
|
|
55
54
|
@staticmethod
|
|
56
55
|
def lifecycle_flags() -> int:
|
|
57
56
|
return (
|
|
58
|
-
_PartialFunctionFlags.
|
|
59
|
-
| _PartialFunctionFlags.ENTER_PRE_SNAPSHOT
|
|
57
|
+
_PartialFunctionFlags.ENTER_PRE_SNAPSHOT
|
|
60
58
|
| _PartialFunctionFlags.ENTER_POST_SNAPSHOT
|
|
61
59
|
| _PartialFunctionFlags.EXIT
|
|
62
60
|
)
|
|
@@ -646,59 +644,6 @@ def _web_server(
|
|
|
646
644
|
return wrapper
|
|
647
645
|
|
|
648
646
|
|
|
649
|
-
def _build(
|
|
650
|
-
_warn_parentheses_missing=None, *, force: bool = False, timeout: int = 86400
|
|
651
|
-
) -> Callable[[Union[_PartialFunction, NullaryMethod]], _PartialFunction]:
|
|
652
|
-
"""mdmd:hidden
|
|
653
|
-
Decorator for methods that execute at _build time_ to create a new Image layer.
|
|
654
|
-
|
|
655
|
-
**Deprecated**: This function is deprecated. We recommend using `modal.Volume`
|
|
656
|
-
to store large assets (such as model weights) instead of writing them to the
|
|
657
|
-
Image during the build process. For other use cases, you can replace this
|
|
658
|
-
decorator with the `Image.run_function` method.
|
|
659
|
-
|
|
660
|
-
**Usage**
|
|
661
|
-
|
|
662
|
-
```python notest
|
|
663
|
-
@app.cls(gpu="A10G")
|
|
664
|
-
class AlpacaLoRAModel:
|
|
665
|
-
@build()
|
|
666
|
-
def download_models(self):
|
|
667
|
-
model = LlamaForCausalLM.from_pretrained(
|
|
668
|
-
base_model,
|
|
669
|
-
)
|
|
670
|
-
PeftModel.from_pretrained(model, lora_weights)
|
|
671
|
-
LlamaTokenizer.from_pretrained(base_model)
|
|
672
|
-
```
|
|
673
|
-
"""
|
|
674
|
-
if _warn_parentheses_missing is not None:
|
|
675
|
-
raise InvalidError(
|
|
676
|
-
"Positional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.build()`."
|
|
677
|
-
)
|
|
678
|
-
|
|
679
|
-
deprecation_warning(
|
|
680
|
-
(2025, 1, 15),
|
|
681
|
-
"The `@modal.build` decorator is deprecated and will be removed in a future release."
|
|
682
|
-
"\n\nWe now recommend storing large assets (such as model weights) using a `modal.Volume`"
|
|
683
|
-
" instead of writing them directly into the `modal.Image` filesystem."
|
|
684
|
-
" For other use cases we recommend using `Image.run_function` instead."
|
|
685
|
-
"\n\nSee https://modal.com/docs/guide/modal-1-0-migration for more information.",
|
|
686
|
-
)
|
|
687
|
-
|
|
688
|
-
flags = _PartialFunctionFlags.BUILD
|
|
689
|
-
params = _PartialFunctionParams(force_build=force, build_timeout=timeout)
|
|
690
|
-
|
|
691
|
-
def wrapper(obj: Union[_PartialFunction, NullaryMethod]) -> _PartialFunction:
|
|
692
|
-
if isinstance(obj, _PartialFunction):
|
|
693
|
-
pf = obj.stack(flags, params)
|
|
694
|
-
else:
|
|
695
|
-
pf = _PartialFunction(obj, flags, params)
|
|
696
|
-
pf.validate_obj_compatibility("build")
|
|
697
|
-
return pf
|
|
698
|
-
|
|
699
|
-
return wrapper
|
|
700
|
-
|
|
701
|
-
|
|
702
647
|
def _enter(
|
|
703
648
|
_warn_parentheses_missing=None,
|
|
704
649
|
*,
|
modal/client.pyi
CHANGED
|
@@ -33,7 +33,7 @@ class _Client:
|
|
|
33
33
|
server_url: str,
|
|
34
34
|
client_type: int,
|
|
35
35
|
credentials: typing.Optional[tuple[str, str]],
|
|
36
|
-
version: str = "1.0.6.
|
|
36
|
+
version: str = "1.0.6.dev37",
|
|
37
37
|
):
|
|
38
38
|
"""mdmd:hidden
|
|
39
39
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -163,7 +163,7 @@ class Client:
|
|
|
163
163
|
server_url: str,
|
|
164
164
|
client_type: int,
|
|
165
165
|
credentials: typing.Optional[tuple[str, str]],
|
|
166
|
-
version: str = "1.0.6.
|
|
166
|
+
version: str = "1.0.6.dev37",
|
|
167
167
|
):
|
|
168
168
|
"""mdmd:hidden
|
|
169
169
|
The Modal client object is not intended to be instantiated directly by users.
|
modal/image.py
CHANGED
|
@@ -799,28 +799,6 @@ class _Image(_Object, type_prefix="im"):
|
|
|
799
799
|
mount = _Mount._add_local_dir(Path(local_path), PurePosixPath(remote_path), ignore=_ignore_fn(ignore))
|
|
800
800
|
return self._add_mount_layer_or_copy(mount, copy=copy)
|
|
801
801
|
|
|
802
|
-
def copy_local_file(self, local_path: Union[str, Path], remote_path: Union[str, Path] = "./") -> "_Image":
|
|
803
|
-
"""mdmd:hidden
|
|
804
|
-
Copy a file into the image as a part of building it.
|
|
805
|
-
|
|
806
|
-
This works in a similar way to [`COPY`](https://docs.docker.com/engine/reference/builder/#copy)
|
|
807
|
-
works in a `Dockerfile`.
|
|
808
|
-
"""
|
|
809
|
-
deprecation_warning(
|
|
810
|
-
(2025, 1, 13),
|
|
811
|
-
COPY_DEPRECATION_MESSAGE_PATTERN.format(replacement="image.add_local_file"),
|
|
812
|
-
)
|
|
813
|
-
basename = str(Path(local_path).name)
|
|
814
|
-
|
|
815
|
-
def build_dockerfile(version: ImageBuilderVersion) -> DockerfileSpec:
|
|
816
|
-
return DockerfileSpec(commands=["FROM base", f"COPY {basename} {remote_path}"], context_files={})
|
|
817
|
-
|
|
818
|
-
return _Image._from_args(
|
|
819
|
-
base_images={"base": self},
|
|
820
|
-
dockerfile_function=build_dockerfile,
|
|
821
|
-
context_mount_function=lambda: _Mount._from_local_file(local_path, remote_path=f"/{basename}"),
|
|
822
|
-
)
|
|
823
|
-
|
|
824
802
|
def add_local_python_source(
|
|
825
803
|
self, *modules: str, copy: bool = False, ignore: Union[Sequence[str], Callable[[Path], bool]] = NON_PYTHON_FILES
|
|
826
804
|
) -> "_Image":
|
|
@@ -865,78 +843,6 @@ class _Image(_Object, type_prefix="im"):
|
|
|
865
843
|
img._added_python_source_set |= set(modules)
|
|
866
844
|
return img
|
|
867
845
|
|
|
868
|
-
def copy_local_dir(
|
|
869
|
-
self,
|
|
870
|
-
local_path: Union[str, Path],
|
|
871
|
-
remote_path: Union[str, Path] = ".",
|
|
872
|
-
# Predicate filter function for file exclusion, which should accept a filepath and return `True` for exclusion.
|
|
873
|
-
# Defaults to excluding no files. If a Sequence is provided, it will be converted to a FilePatternMatcher.
|
|
874
|
-
# Which follows dockerignore syntax.
|
|
875
|
-
ignore: Union[Sequence[str], Callable[[Path], bool]] = [],
|
|
876
|
-
) -> "_Image":
|
|
877
|
-
"""mdmd:hidden
|
|
878
|
-
**Deprecated**: Use image.add_local_dir instead
|
|
879
|
-
|
|
880
|
-
Copy a directory into the image as a part of building the image.
|
|
881
|
-
|
|
882
|
-
This works in a similar way to [`COPY`](https://docs.docker.com/engine/reference/builder/#copy)
|
|
883
|
-
works in a `Dockerfile`.
|
|
884
|
-
|
|
885
|
-
**Usage:**
|
|
886
|
-
|
|
887
|
-
```python notest
|
|
888
|
-
from pathlib import Path
|
|
889
|
-
from modal import FilePatternMatcher
|
|
890
|
-
|
|
891
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
892
|
-
"~/assets",
|
|
893
|
-
remote_path="/assets",
|
|
894
|
-
ignore=["**/*.venv"],
|
|
895
|
-
)
|
|
896
|
-
|
|
897
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
898
|
-
"~/assets",
|
|
899
|
-
remote_path="/assets",
|
|
900
|
-
ignore=lambda p: p.is_relative_to(".venv"),
|
|
901
|
-
)
|
|
902
|
-
|
|
903
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
904
|
-
"~/assets",
|
|
905
|
-
remote_path="/assets",
|
|
906
|
-
ignore=FilePatternMatcher("**/*.txt"),
|
|
907
|
-
)
|
|
908
|
-
|
|
909
|
-
# When including files is simpler than excluding them, you can use the `~` operator to invert the matcher.
|
|
910
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
911
|
-
"~/assets",
|
|
912
|
-
remote_path="/assets",
|
|
913
|
-
ignore=~FilePatternMatcher("**/*.py"),
|
|
914
|
-
)
|
|
915
|
-
|
|
916
|
-
# You can also read ignore patterns from a file.
|
|
917
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
918
|
-
"~/assets",
|
|
919
|
-
remote_path="/assets",
|
|
920
|
-
ignore=FilePatternMatcher.from_file("/path/to/ignorefile"),
|
|
921
|
-
)
|
|
922
|
-
```
|
|
923
|
-
"""
|
|
924
|
-
deprecation_warning(
|
|
925
|
-
(2025, 1, 13),
|
|
926
|
-
COPY_DEPRECATION_MESSAGE_PATTERN.format(replacement="image.add_local_dir"),
|
|
927
|
-
)
|
|
928
|
-
|
|
929
|
-
def build_dockerfile(version: ImageBuilderVersion) -> DockerfileSpec:
|
|
930
|
-
return DockerfileSpec(commands=["FROM base", f"COPY . {remote_path}"], context_files={})
|
|
931
|
-
|
|
932
|
-
return _Image._from_args(
|
|
933
|
-
base_images={"base": self},
|
|
934
|
-
dockerfile_function=build_dockerfile,
|
|
935
|
-
context_mount_function=lambda: _Mount._add_local_dir(
|
|
936
|
-
Path(local_path), PurePosixPath("/"), ignore=_ignore_fn(ignore)
|
|
937
|
-
),
|
|
938
|
-
)
|
|
939
|
-
|
|
940
846
|
@staticmethod
|
|
941
847
|
async def from_id(image_id: str, client: Optional[_Client] = None) -> "_Image":
|
|
942
848
|
"""Construct an Image from an id and look up the Image result.
|
modal/image.pyi
CHANGED
|
@@ -266,17 +266,6 @@ class _Image(modal._object._Object):
|
|
|
266
266
|
"""
|
|
267
267
|
...
|
|
268
268
|
|
|
269
|
-
def copy_local_file(
|
|
270
|
-
self, local_path: typing.Union[str, pathlib.Path], remote_path: typing.Union[str, pathlib.Path] = "./"
|
|
271
|
-
) -> _Image:
|
|
272
|
-
"""mdmd:hidden
|
|
273
|
-
Copy a file into the image as a part of building it.
|
|
274
|
-
|
|
275
|
-
This works in a similar way to [`COPY`](https://docs.docker.com/engine/reference/builder/#copy)
|
|
276
|
-
works in a `Dockerfile`.
|
|
277
|
-
"""
|
|
278
|
-
...
|
|
279
|
-
|
|
280
269
|
def add_local_python_source(
|
|
281
270
|
self,
|
|
282
271
|
*module_names: str,
|
|
@@ -321,61 +310,6 @@ class _Image(modal._object._Object):
|
|
|
321
310
|
"""
|
|
322
311
|
...
|
|
323
312
|
|
|
324
|
-
def copy_local_dir(
|
|
325
|
-
self,
|
|
326
|
-
local_path: typing.Union[str, pathlib.Path],
|
|
327
|
-
remote_path: typing.Union[str, pathlib.Path] = ".",
|
|
328
|
-
ignore: typing.Union[collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]] = [],
|
|
329
|
-
) -> _Image:
|
|
330
|
-
"""mdmd:hidden
|
|
331
|
-
**Deprecated**: Use image.add_local_dir instead
|
|
332
|
-
|
|
333
|
-
Copy a directory into the image as a part of building the image.
|
|
334
|
-
|
|
335
|
-
This works in a similar way to [`COPY`](https://docs.docker.com/engine/reference/builder/#copy)
|
|
336
|
-
works in a `Dockerfile`.
|
|
337
|
-
|
|
338
|
-
**Usage:**
|
|
339
|
-
|
|
340
|
-
```python notest
|
|
341
|
-
from pathlib import Path
|
|
342
|
-
from modal import FilePatternMatcher
|
|
343
|
-
|
|
344
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
345
|
-
"~/assets",
|
|
346
|
-
remote_path="/assets",
|
|
347
|
-
ignore=["**/*.venv"],
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
351
|
-
"~/assets",
|
|
352
|
-
remote_path="/assets",
|
|
353
|
-
ignore=lambda p: p.is_relative_to(".venv"),
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
357
|
-
"~/assets",
|
|
358
|
-
remote_path="/assets",
|
|
359
|
-
ignore=FilePatternMatcher("**/*.txt"),
|
|
360
|
-
)
|
|
361
|
-
|
|
362
|
-
# When including files is simpler than excluding them, you can use the `~` operator to invert the matcher.
|
|
363
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
364
|
-
"~/assets",
|
|
365
|
-
remote_path="/assets",
|
|
366
|
-
ignore=~FilePatternMatcher("**/*.py"),
|
|
367
|
-
)
|
|
368
|
-
|
|
369
|
-
# You can also read ignore patterns from a file.
|
|
370
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
371
|
-
"~/assets",
|
|
372
|
-
remote_path="/assets",
|
|
373
|
-
ignore=FilePatternMatcher.from_file("/path/to/ignorefile"),
|
|
374
|
-
)
|
|
375
|
-
```
|
|
376
|
-
"""
|
|
377
|
-
...
|
|
378
|
-
|
|
379
313
|
@staticmethod
|
|
380
314
|
async def from_id(image_id: str, client: typing.Optional[modal.client._Client] = None) -> _Image:
|
|
381
315
|
"""Construct an Image from an id and look up the Image result.
|
|
@@ -1154,17 +1088,6 @@ class Image(modal.object.Object):
|
|
|
1154
1088
|
"""
|
|
1155
1089
|
...
|
|
1156
1090
|
|
|
1157
|
-
def copy_local_file(
|
|
1158
|
-
self, local_path: typing.Union[str, pathlib.Path], remote_path: typing.Union[str, pathlib.Path] = "./"
|
|
1159
|
-
) -> Image:
|
|
1160
|
-
"""mdmd:hidden
|
|
1161
|
-
Copy a file into the image as a part of building it.
|
|
1162
|
-
|
|
1163
|
-
This works in a similar way to [`COPY`](https://docs.docker.com/engine/reference/builder/#copy)
|
|
1164
|
-
works in a `Dockerfile`.
|
|
1165
|
-
"""
|
|
1166
|
-
...
|
|
1167
|
-
|
|
1168
1091
|
def add_local_python_source(
|
|
1169
1092
|
self,
|
|
1170
1093
|
*module_names: str,
|
|
@@ -1209,61 +1132,6 @@ class Image(modal.object.Object):
|
|
|
1209
1132
|
"""
|
|
1210
1133
|
...
|
|
1211
1134
|
|
|
1212
|
-
def copy_local_dir(
|
|
1213
|
-
self,
|
|
1214
|
-
local_path: typing.Union[str, pathlib.Path],
|
|
1215
|
-
remote_path: typing.Union[str, pathlib.Path] = ".",
|
|
1216
|
-
ignore: typing.Union[collections.abc.Sequence[str], collections.abc.Callable[[pathlib.Path], bool]] = [],
|
|
1217
|
-
) -> Image:
|
|
1218
|
-
"""mdmd:hidden
|
|
1219
|
-
**Deprecated**: Use image.add_local_dir instead
|
|
1220
|
-
|
|
1221
|
-
Copy a directory into the image as a part of building the image.
|
|
1222
|
-
|
|
1223
|
-
This works in a similar way to [`COPY`](https://docs.docker.com/engine/reference/builder/#copy)
|
|
1224
|
-
works in a `Dockerfile`.
|
|
1225
|
-
|
|
1226
|
-
**Usage:**
|
|
1227
|
-
|
|
1228
|
-
```python notest
|
|
1229
|
-
from pathlib import Path
|
|
1230
|
-
from modal import FilePatternMatcher
|
|
1231
|
-
|
|
1232
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
1233
|
-
"~/assets",
|
|
1234
|
-
remote_path="/assets",
|
|
1235
|
-
ignore=["**/*.venv"],
|
|
1236
|
-
)
|
|
1237
|
-
|
|
1238
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
1239
|
-
"~/assets",
|
|
1240
|
-
remote_path="/assets",
|
|
1241
|
-
ignore=lambda p: p.is_relative_to(".venv"),
|
|
1242
|
-
)
|
|
1243
|
-
|
|
1244
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
1245
|
-
"~/assets",
|
|
1246
|
-
remote_path="/assets",
|
|
1247
|
-
ignore=FilePatternMatcher("**/*.txt"),
|
|
1248
|
-
)
|
|
1249
|
-
|
|
1250
|
-
# When including files is simpler than excluding them, you can use the `~` operator to invert the matcher.
|
|
1251
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
1252
|
-
"~/assets",
|
|
1253
|
-
remote_path="/assets",
|
|
1254
|
-
ignore=~FilePatternMatcher("**/*.py"),
|
|
1255
|
-
)
|
|
1256
|
-
|
|
1257
|
-
# You can also read ignore patterns from a file.
|
|
1258
|
-
image = modal.Image.debian_slim().copy_local_dir(
|
|
1259
|
-
"~/assets",
|
|
1260
|
-
remote_path="/assets",
|
|
1261
|
-
ignore=FilePatternMatcher.from_file("/path/to/ignorefile"),
|
|
1262
|
-
)
|
|
1263
|
-
```
|
|
1264
|
-
"""
|
|
1265
|
-
...
|
|
1266
|
-
|
|
1267
1135
|
class __from_id_spec(typing_extensions.Protocol):
|
|
1268
1136
|
def __call__(self, /, image_id: str, client: typing.Optional[modal.client.Client] = None) -> Image:
|
|
1269
1137
|
"""Construct an Image from an id and look up the Image result.
|
modal/partial_function.py
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from ._partial_function import (
|
|
4
4
|
_asgi_app,
|
|
5
5
|
_batched,
|
|
6
|
-
_build,
|
|
7
6
|
_concurrent,
|
|
8
7
|
_enter,
|
|
9
8
|
_exit,
|
|
@@ -25,7 +24,6 @@ fastapi_endpoint = synchronize_api(_fastapi_endpoint, target_module=__name__)
|
|
|
25
24
|
asgi_app = synchronize_api(_asgi_app, target_module=__name__)
|
|
26
25
|
wsgi_app = synchronize_api(_wsgi_app, target_module=__name__)
|
|
27
26
|
web_server = synchronize_api(_web_server, target_module=__name__)
|
|
28
|
-
build = synchronize_api(_build, target_module=__name__)
|
|
29
27
|
enter = synchronize_api(_enter, target_module=__name__)
|
|
30
28
|
exit = synchronize_api(_exit, target_module=__name__)
|
|
31
29
|
batched = synchronize_api(_batched, target_module=__name__)
|
modal/partial_function.pyi
CHANGED
|
@@ -269,35 +269,6 @@ def web_server(
|
|
|
269
269
|
"""
|
|
270
270
|
...
|
|
271
271
|
|
|
272
|
-
def build(
|
|
273
|
-
_warn_parentheses_missing=None, *, force: bool = False, timeout: int = 86400
|
|
274
|
-
) -> collections.abc.Callable[
|
|
275
|
-
[typing.Union[PartialFunction, collections.abc.Callable[[typing.Any], typing.Any]]], PartialFunction
|
|
276
|
-
]:
|
|
277
|
-
"""mdmd:hidden
|
|
278
|
-
Decorator for methods that execute at _build time_ to create a new Image layer.
|
|
279
|
-
|
|
280
|
-
**Deprecated**: This function is deprecated. We recommend using `modal.Volume`
|
|
281
|
-
to store large assets (such as model weights) instead of writing them to the
|
|
282
|
-
Image during the build process. For other use cases, you can replace this
|
|
283
|
-
decorator with the `Image.run_function` method.
|
|
284
|
-
|
|
285
|
-
**Usage**
|
|
286
|
-
|
|
287
|
-
```python notest
|
|
288
|
-
@app.cls(gpu="A10G")
|
|
289
|
-
class AlpacaLoRAModel:
|
|
290
|
-
@build()
|
|
291
|
-
def download_models(self):
|
|
292
|
-
model = LlamaForCausalLM.from_pretrained(
|
|
293
|
-
base_model,
|
|
294
|
-
)
|
|
295
|
-
PeftModel.from_pretrained(model, lora_weights)
|
|
296
|
-
LlamaTokenizer.from_pretrained(base_model)
|
|
297
|
-
```
|
|
298
|
-
"""
|
|
299
|
-
...
|
|
300
|
-
|
|
301
272
|
def enter(
|
|
302
273
|
_warn_parentheses_missing=None, *, snap: bool = False
|
|
303
274
|
) -> collections.abc.Callable[
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
modal/__init__.py,sha256=
|
|
1
|
+
modal/__init__.py,sha256=WMaRW-2IJRGA9ioNAaBhJYuyLvu-GS01L8wQD90fKBs,2682
|
|
2
2
|
modal/__main__.py,sha256=sTJcc9EbDuCKSwg3tL6ZckFw9WWdlkXW8mId1IvJCNc,2846
|
|
3
3
|
modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
|
|
4
4
|
modal/_clustered_functions.pyi,sha256=_QKM87tdYwcALSGth8a0-9qXl02fZK6zMfEGEoYz7eA,1007
|
|
5
5
|
modal/_container_entrypoint.py,sha256=1qBMNY_E9ICC_sRCtillMxmKPsmxJl1J0_qOAG8rH-0,28288
|
|
6
|
-
modal/_functions.py,sha256=
|
|
6
|
+
modal/_functions.py,sha256=8_gNjCCgB-fzZ1SJPKq9P-UzhUazqNWuNGM8vDgsA-o,81153
|
|
7
7
|
modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
|
|
8
8
|
modal/_location.py,sha256=joiX-0ZeutEUDTrrqLF1GHXCdVLF-rHzstocbMcd_-k,366
|
|
9
9
|
modal/_object.py,sha256=QWyUGjrGLupITkyvJru2cekizsaVdteAhwMQlw_tE4k,11172
|
|
10
10
|
modal/_output.py,sha256=LRM9KroHuR7t5pq8iLYjpFz1sQrHYan2kvRDjT6KAw4,26082
|
|
11
|
-
modal/_partial_function.py,sha256=
|
|
11
|
+
modal/_partial_function.py,sha256=yq--_U7jU7nkZNLWFImVvin9P5A-FiOZLUVEuw9xKoE,36989
|
|
12
12
|
modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
|
|
13
13
|
modal/_resolver.py,sha256=-nolqj_p_mx5czVYj1Mazh2IQWpSMrTOGughVJqYfo8,7579
|
|
14
14
|
modal/_resources.py,sha256=NMAp0GCLutiZI4GuKSIVnRHVlstoD3hNGUabjTUtzf4,1794
|
|
@@ -22,7 +22,7 @@ modal/app.py,sha256=U0sPiHpphcRHLnoLYh2IrU2RSpRFX9BE5uHb7h42STs,47478
|
|
|
22
22
|
modal/app.pyi,sha256=cXiSTu2bwu6csAUdkOlh7mr9tPvtaS2qWSEhlC1UxAg,43787
|
|
23
23
|
modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
|
|
24
24
|
modal/client.py,sha256=5QyM7VJjsFbHf6E91ar3A2KY9mx03wdtGlNJvfTKUVs,17087
|
|
25
|
-
modal/client.pyi,sha256=
|
|
25
|
+
modal/client.pyi,sha256=rm8Gh8Gmu3Jm-3bDXTvT-5aeqw12hbKHr0b2zEa62Ug,15270
|
|
26
26
|
modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
|
|
27
27
|
modal/cloud_bucket_mount.pyi,sha256=-qSfYAQvIoO_l2wsCCGTG5ZUwQieNKXdAO00yP1-LYU,7394
|
|
28
28
|
modal/cls.py,sha256=EFrM949jNXJpmwB2G_1d28b8IpHShfKIEIaiPkZqeOU,39881
|
|
@@ -41,8 +41,8 @@ modal/file_pattern_matcher.py,sha256=urAue8es8jxqX94k9EYoZxxhtfgOlsEES8lbFHOorzc
|
|
|
41
41
|
modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
|
|
42
42
|
modal/functions.pyi,sha256=FJe_91dSrMCRNVT-YV1UhtxFKzIvL_C5q8xdk08-wT8,34840
|
|
43
43
|
modal/gpu.py,sha256=Fe5ORvVPDIstSq1xjmM6OoNgLYFWvogP9r5BgmD3hYg,6769
|
|
44
|
-
modal/image.py,sha256=
|
|
45
|
-
modal/image.pyi,sha256=
|
|
44
|
+
modal/image.py,sha256=dqiVVxKTh77pM5I9M7ty5nFSBtd3JQME0_RAROIBJuw,101717
|
|
45
|
+
modal/image.pyi,sha256=oJYcnVAY-hSLWlA_B4pFNDh3b6ss4wqGuHj9puPPnV4,67552
|
|
46
46
|
modal/io_streams.py,sha256=FUDpBsVK8isqwyC7DtAcQZhaHlMFSaNZGhYJOg-SFW0,15590
|
|
47
47
|
modal/io_streams.pyi,sha256=5b3b93ztZeR8IpJtNIGffX24QLPgocE4-gAps8y7CKU,13824
|
|
48
48
|
modal/mount.py,sha256=q-pPeVxAmte-G_LDpbFwaNs2Rb2MIpscfnCXzkhxrOI,36734
|
|
@@ -54,8 +54,8 @@ modal/object.pyi,sha256=751TV6BntarPsErf0HDQPsvePjWFf0JZK8ZAiRpM1yg,6627
|
|
|
54
54
|
modal/output.py,sha256=q4T9uHduunj4NwY-YSwkHGgjZlCXMuJbfQ5UFaAGRAc,1968
|
|
55
55
|
modal/parallel_map.py,sha256=hoyGd6DPz87f3WiwsncB2jls3qA1aIYK7G8e1SyO-wQ,40903
|
|
56
56
|
modal/parallel_map.pyi,sha256=-t3nZ-SvKEK8_xC4A_AmAq6UVpt4ZFtq7rPnWzHGhfg,10290
|
|
57
|
-
modal/partial_function.py,sha256=
|
|
58
|
-
modal/partial_function.pyi,sha256
|
|
57
|
+
modal/partial_function.py,sha256=aIdlGfTjjgqY6Fpr-biCjvRU9W542_S5N2xkNN_rYGM,1127
|
|
58
|
+
modal/partial_function.pyi,sha256=lqqOzZ9-QvHTDWKQ_oAYYOvsXgTOBKhO9u-RI98JbUk,13986
|
|
59
59
|
modal/proxy.py,sha256=NQJJMGo-D2IfmeU0vb10WWaE4oTLcuf9jTeEJvactOg,1446
|
|
60
60
|
modal/proxy.pyi,sha256=yWGWwADCRGrC2w81B7671UTH4Uv3HMZKy5vVqlJUZoA,1417
|
|
61
61
|
modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -149,7 +149,7 @@ modal/requirements/2025.06.txt,sha256=KxDaVTOwatHvboDo4lorlgJ7-n-MfAwbPwxJ0zcJqr
|
|
|
149
149
|
modal/requirements/PREVIEW.txt,sha256=KxDaVTOwatHvboDo4lorlgJ7-n-MfAwbPwxJ0zcJqrs,312
|
|
150
150
|
modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
|
|
151
151
|
modal/requirements/base-images.json,sha256=JYSDAgHTl-WrV_TZW5icY-IJEnbe2eQ4CZ_KN6EOZKU,1304
|
|
152
|
-
modal-1.0.6.
|
|
152
|
+
modal-1.0.6.dev37.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
|
153
153
|
modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
|
|
154
154
|
modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
|
|
155
155
|
modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
|
|
@@ -157,13 +157,13 @@ modal_docs/mdmd/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,2
|
|
|
157
157
|
modal_docs/mdmd/mdmd.py,sha256=eW5MzrEl7mSclDo4Uv64sQ1-4IyLggldbgUJdBVLDdI,6449
|
|
158
158
|
modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
|
|
159
159
|
modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
|
|
160
|
-
modal_proto/api.proto,sha256=
|
|
161
|
-
modal_proto/api_grpc.py,sha256=
|
|
162
|
-
modal_proto/api_pb2.py,sha256=
|
|
163
|
-
modal_proto/api_pb2.pyi,sha256=
|
|
164
|
-
modal_proto/api_pb2_grpc.py,sha256=
|
|
165
|
-
modal_proto/api_pb2_grpc.pyi,sha256=
|
|
166
|
-
modal_proto/modal_api_grpc.py,sha256=
|
|
160
|
+
modal_proto/api.proto,sha256=NxnajWiJMn8KuIYlM_Er-lgt2TZX5NDM7zQBriIo4e0,99354
|
|
161
|
+
modal_proto/api_grpc.py,sha256=F7Hu-1Yg7p5a2SbKw9yR4AgpyU0ntvgZTaVbIJMR0DE,122366
|
|
162
|
+
modal_proto/api_pb2.py,sha256=IMsL_9MKeCNTaByHg-eH_6UqK8m3aSGUzJId6tCRPhQ,349638
|
|
163
|
+
modal_proto/api_pb2.pyi,sha256=PUhlvse2LZV6v6rOEMyaPOlT852GWsy2P5SrLHiGAG8,476220
|
|
164
|
+
modal_proto/api_pb2_grpc.py,sha256=pIFrNmCOgRRcIW8A1Ekja9Po6fHcsj54ExDZFzTpYe4,264347
|
|
165
|
+
modal_proto/api_pb2_grpc.pyi,sha256=vtxrQ9xnQG6ZRXjp2uk43Mb7wV7F4qGYuVl5JUBc8jI,61968
|
|
166
|
+
modal_proto/modal_api_grpc.py,sha256=Yl_fGbSIuX2FAEnURkYpKqshs7kbNqtz5HlTJEXkbhE,18487
|
|
167
167
|
modal_proto/modal_options_grpc.py,sha256=qJ1cuwA54oRqrdTyPTbvfhFZYd9HhJKK5UCwt523r3Y,120
|
|
168
168
|
modal_proto/options.proto,sha256=zp9h5r61ivsp0XwEWwNBsVqNTbRA1VSY_UtN7sEcHtE,549
|
|
169
169
|
modal_proto/options_grpc.py,sha256=M18X3d-8F_cNYSVM3I25dUTO5rZ0rd-vCCfynfh13Nc,125
|
|
@@ -172,10 +172,10 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
|
|
|
172
172
|
modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
|
173
173
|
modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
|
|
174
174
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
175
|
-
modal_version/__init__.py,sha256=
|
|
175
|
+
modal_version/__init__.py,sha256=ZE-TfIoWGtiHCeJoew1F6p-o1i_vEbaFmI2UhTRyXPY,121
|
|
176
176
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
|
177
|
-
modal-1.0.6.
|
|
178
|
-
modal-1.0.6.
|
|
179
|
-
modal-1.0.6.
|
|
180
|
-
modal-1.0.6.
|
|
181
|
-
modal-1.0.6.
|
|
177
|
+
modal-1.0.6.dev37.dist-info/METADATA,sha256=H68KdOQ6msWY0JGSWxA-s2ncWW00f_0-GWitlNXdAOg,2462
|
|
178
|
+
modal-1.0.6.dev37.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
|
179
|
+
modal-1.0.6.dev37.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
|
180
|
+
modal-1.0.6.dev37.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
|
|
181
|
+
modal-1.0.6.dev37.dist-info/RECORD,,
|
modal_proto/api.proto
CHANGED
|
@@ -2514,6 +2514,9 @@ message Sandbox {
|
|
|
2514
2514
|
|
|
2515
2515
|
// If set, the sandbox will be created with verbose logging enabled.
|
|
2516
2516
|
bool verbose = 29;
|
|
2517
|
+
|
|
2518
|
+
// If set, the sandbox will be created with a name.
|
|
2519
|
+
optional string name = 30;
|
|
2517
2520
|
}
|
|
2518
2521
|
|
|
2519
2522
|
message SandboxCreateRequest {
|
|
@@ -2526,6 +2529,15 @@ message SandboxCreateResponse {
|
|
|
2526
2529
|
string sandbox_id = 1;
|
|
2527
2530
|
}
|
|
2528
2531
|
|
|
2532
|
+
message SandboxGetFromNameRequest {
|
|
2533
|
+
string sandbox_name = 1;
|
|
2534
|
+
string environment_name = 2;
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
message SandboxGetFromNameResponse {
|
|
2538
|
+
string sandbox_id = 1;
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2529
2541
|
message SandboxGetLogsRequest {
|
|
2530
2542
|
string sandbox_id = 1;
|
|
2531
2543
|
FileDescriptor file_descriptor = 2;
|
|
@@ -2575,6 +2587,7 @@ message SandboxInfo {
|
|
|
2575
2587
|
TaskInfo task_info = 4;
|
|
2576
2588
|
string app_id = 5;
|
|
2577
2589
|
repeated SandboxTag tags = 6; // TODO: Not yet exposed in client library.
|
|
2590
|
+
string name = 7;
|
|
2578
2591
|
|
|
2579
2592
|
reserved 2; // modal.client.Sandbox definition
|
|
2580
2593
|
}
|
|
@@ -3397,6 +3410,7 @@ service ModalClient {
|
|
|
3397
3410
|
|
|
3398
3411
|
// Sandboxes
|
|
3399
3412
|
rpc SandboxCreate(SandboxCreateRequest) returns (SandboxCreateResponse);
|
|
3413
|
+
rpc SandboxGetFromName(SandboxGetFromNameRequest) returns (SandboxGetFromNameResponse);
|
|
3400
3414
|
rpc SandboxGetLogs(SandboxGetLogsRequest) returns (stream TaskLogsBatch);
|
|
3401
3415
|
rpc SandboxGetResourceUsage(SandboxGetResourceUsageRequest) returns (SandboxGetResourceUsageResponse);
|
|
3402
3416
|
rpc SandboxGetTaskId(SandboxGetTaskIdRequest) returns (SandboxGetTaskIdResponse); // needed for modal container exec
|
modal_proto/api_grpc.py
CHANGED
|
@@ -442,6 +442,10 @@ class ModalClientBase(abc.ABC):
|
|
|
442
442
|
async def SandboxCreate(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxCreateRequest, modal_proto.api_pb2.SandboxCreateResponse]') -> None:
|
|
443
443
|
pass
|
|
444
444
|
|
|
445
|
+
@abc.abstractmethod
|
|
446
|
+
async def SandboxGetFromName(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxGetFromNameRequest, modal_proto.api_pb2.SandboxGetFromNameResponse]') -> None:
|
|
447
|
+
pass
|
|
448
|
+
|
|
445
449
|
@abc.abstractmethod
|
|
446
450
|
async def SandboxGetLogs(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxGetLogsRequest, modal_proto.api_pb2.TaskLogsBatch]') -> None:
|
|
447
451
|
pass
|
|
@@ -1288,6 +1292,12 @@ class ModalClientBase(abc.ABC):
|
|
|
1288
1292
|
modal_proto.api_pb2.SandboxCreateRequest,
|
|
1289
1293
|
modal_proto.api_pb2.SandboxCreateResponse,
|
|
1290
1294
|
),
|
|
1295
|
+
'/modal.client.ModalClient/SandboxGetFromName': grpclib.const.Handler(
|
|
1296
|
+
self.SandboxGetFromName,
|
|
1297
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
|
1298
|
+
modal_proto.api_pb2.SandboxGetFromNameRequest,
|
|
1299
|
+
modal_proto.api_pb2.SandboxGetFromNameResponse,
|
|
1300
|
+
),
|
|
1291
1301
|
'/modal.client.ModalClient/SandboxGetLogs': grpclib.const.Handler(
|
|
1292
1302
|
self.SandboxGetLogs,
|
|
1293
1303
|
grpclib.const.Cardinality.UNARY_STREAM,
|
|
@@ -2242,6 +2252,12 @@ class ModalClientStub:
|
|
|
2242
2252
|
modal_proto.api_pb2.SandboxCreateRequest,
|
|
2243
2253
|
modal_proto.api_pb2.SandboxCreateResponse,
|
|
2244
2254
|
)
|
|
2255
|
+
self.SandboxGetFromName = grpclib.client.UnaryUnaryMethod(
|
|
2256
|
+
channel,
|
|
2257
|
+
'/modal.client.ModalClient/SandboxGetFromName',
|
|
2258
|
+
modal_proto.api_pb2.SandboxGetFromNameRequest,
|
|
2259
|
+
modal_proto.api_pb2.SandboxGetFromNameResponse,
|
|
2260
|
+
)
|
|
2245
2261
|
self.SandboxGetLogs = grpclib.client.UnaryStreamMethod(
|
|
2246
2262
|
channel,
|
|
2247
2263
|
'/modal.client.ModalClient/SandboxGetLogs',
|