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 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
@@ -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.BUILD # Deprecated, will be removed
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.dev35",
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.dev35",
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__)
@@ -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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.6.dev35
3
+ Version: 1.0.6.dev37
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -1,14 +1,14 @@
1
- modal/__init__.py,sha256=1131svUxi876UMFC6Z68qe5Z031ZfZ9NrduvGwHphj8,2710
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=hQ92Vv8wlyecDw2I_essrmYO1Sa6AIPySBogf14Dkr0,82416
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=RqBRBqezecNDK_Ve_X00Oaw5Loub7OaknfoWb7dcgSg,39176
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=FtnPVcn_ibs8N3ZbmQBNMFMxGz8MIXZzPpIUywolqdk,15270
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=BkoXdm3hqsps8OJPUbvKv_tpW37qbQroDWspgkwtdzc,105329
45
- modal/image.pyi,sha256=Dutty6aFyba_AHL1sq11WnSiZaRI1b-qOxudUx1P-bU,71970
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=SwuAAj2wj4SO6F6nkSnwNZrczEmm9w9YdlQTHh6hr04,1195
58
- modal/partial_function.pyi,sha256=-rhLIgXtLpP5weJw7U4aMcDxtFMwXJ1wf-nncPowUMg,14991
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.dev35.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
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=1vEvIEQPXGD-2wMjL9qej-k0-qGomntWM4HFIYX7gDI,98999
161
- modal_proto/api_grpc.py,sha256=TgtXNRYDq_l3ttq2Nkgf3skx68TLQXpTIgqspKiqe2A,121554
162
- modal_proto/api_pb2.py,sha256=1eEc_Kbw0RbyoytzTwb-AwbRQ5RYrSQMYv4XU_EF5ks,348135
163
- modal_proto/api_pb2.pyi,sha256=A63YAw1MhgdvRr6r5RzWFqcwZRSyU7DOjBX-YSVZMWU,474612
164
- modal_proto/api_pb2_grpc.py,sha256=43ApAOCiKeXXXYt1uZ744QCQ0Wh2pXNhwhPDzQ60o5w,262636
165
- modal_proto/api_pb2_grpc.pyi,sha256=Flv0eGcwO53q7FaNx7JpYFdjYGRDgEFGzdW0OLu-2Jg,61567
166
- modal_proto/modal_api_grpc.py,sha256=pM8bh6F9uiC1nJiLsK8LuPFnzR8qPy8J9x87xW5CoEY,18369
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=lOl746IZNj-Ic3Vi6oCzy2IuszcJkff4r7sPXgkKDKI,121
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.dev35.dist-info/METADATA,sha256=hLiw38PEdO-arLLnLtTPnu9wWAhQYRpywfdZokOQTdA,2462
178
- modal-1.0.6.dev35.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
179
- modal-1.0.6.dev35.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
180
- modal-1.0.6.dev35.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
181
- modal-1.0.6.dev35.dist-info/RECORD,,
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',