modal 1.0.0.dev17__py3-none-any.whl → 1.0.0.dev19__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/__init__.py CHANGED
@@ -20,7 +20,6 @@ try:
20
20
  from .file_pattern_matcher import FilePatternMatcher
21
21
  from .functions import Function, FunctionCall
22
22
  from .image import Image
23
- from .mount import Mount
24
23
  from .network_file_system import NetworkFileSystem
25
24
  from .output import enable_output
26
25
  from .partial_function import (
@@ -67,7 +66,6 @@ __all__ = [
67
66
  "Function",
68
67
  "FunctionCall",
69
68
  "Image",
70
- "Mount",
71
69
  "NetworkFileSystem",
72
70
  "Period",
73
71
  "Proxy",
modal/_functions.py CHANGED
@@ -6,7 +6,7 @@ import textwrap
6
6
  import time
7
7
  import typing
8
8
  import warnings
9
- from collections.abc import AsyncGenerator, Collection, Sequence, Sized
9
+ from collections.abc import AsyncGenerator, Sequence, Sized
10
10
  from dataclasses import dataclass
11
11
  from pathlib import PurePosixPath
12
12
  from typing import TYPE_CHECKING, Any, Callable, Optional, Union
@@ -99,7 +99,6 @@ if TYPE_CHECKING:
99
99
  import modal.cls
100
100
  import modal.partial_function
101
101
 
102
- MAX_INTERNAL_FAILURE_COUNT = 100
103
102
 
104
103
  @dataclasses.dataclass
105
104
  class _RetryContext:
@@ -349,14 +348,10 @@ class _InputPlaneInvocation:
349
348
  stub: ModalClientModal,
350
349
  attempt_token: str,
351
350
  client: _Client,
352
- input_item: api_pb2.FunctionPutInputsItem,
353
- function_id: str
354
351
  ):
355
352
  self.stub = stub
356
353
  self.client = client # Used by the deserializer.
357
354
  self.attempt_token = attempt_token
358
- self.input_item = input_item
359
- self.function_id = function_id
360
355
 
361
356
  @staticmethod
362
357
  async def create(
@@ -370,53 +365,36 @@ class _InputPlaneInvocation:
370
365
  stub = await client.get_stub(input_plane_url)
371
366
 
372
367
  function_id = function.object_id
373
- input_item = await _create_input(args, kwargs, stub, method_name=function._use_method_name)
368
+ item = await _create_input(args, kwargs, stub, method_name=function._use_method_name)
374
369
 
375
370
  request = api_pb2.AttemptStartRequest(
376
371
  function_id=function_id,
377
372
  parent_input_id=current_input_id() or "",
378
- input=input_item,
373
+ input=item,
379
374
  )
380
375
  response = await retry_transient_errors(stub.AttemptStart, request)
381
376
  attempt_token = response.attempt_token
382
377
 
383
- return _InputPlaneInvocation(stub, attempt_token, client, input_item, function_id)
378
+ return _InputPlaneInvocation(stub, attempt_token, client)
384
379
 
385
380
  async def run_function(self) -> Any:
386
- # This will retry when the server returns GENERIC_STATUS_INTERNAL_FAILURE, i.e. lost inputs or worker preemption
387
- # TODO(ryan): add logic to retry for user defined
388
- internal_failure_count = 0
381
+ # TODO(nathan): add retry logic
389
382
  while True:
390
- await_request = api_pb2.AttemptAwaitRequest(
383
+ request = api_pb2.AttemptAwaitRequest(
391
384
  attempt_token=self.attempt_token,
392
385
  timeout_secs=OUTPUTS_TIMEOUT,
393
386
  requested_at=time.time(),
394
387
  )
395
- await_response: api_pb2.AttemptAwaitResponse = await retry_transient_errors(
388
+ response: api_pb2.AttemptAwaitResponse = await retry_transient_errors(
396
389
  self.stub.AttemptAwait,
397
- await_request,
390
+ request,
398
391
  attempt_timeout=OUTPUTS_TIMEOUT + ATTEMPT_TIMEOUT_GRACE_PERIOD,
399
392
  )
400
393
 
401
- try:
394
+ if response.HasField("output"):
402
395
  return await _process_result(
403
- await_response.output.result, await_response.output.data_format, self.stub, self.client
404
- )
405
- except InternalFailure as e:
406
- internal_failure_count += 1
407
- # Limit the number of times we retry
408
- if internal_failure_count >= MAX_INTERNAL_FAILURE_COUNT:
409
- raise e
410
- # For system failures on the server, we retry immediately,
411
- # and the failure does not count towards the retry policy.
412
- retry_request = api_pb2.AttemptRetryRequest(
413
- function_id=self.function_id,
414
- parent_input_id=current_input_id() or "",
415
- input=self.input_item,
416
- attempt_token=self.attempt_token
396
+ response.output.result, response.output.data_format, self.stub, self.client
417
397
  )
418
- retry_response = await retry_transient_errors(self.stub.AttemptRetry, retry_request)
419
- self.attempt_token = retry_response.attempt_token
420
398
 
421
399
 
422
400
  # Wrapper type for api_pb2.FunctionStats
@@ -527,7 +505,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
527
505
  is_generator: bool = False,
528
506
  gpu: Union[GPU_T, list[GPU_T]] = None,
529
507
  # TODO: maybe break this out into a separate decorator for notebooks.
530
- mounts: Collection[_Mount] = (),
531
508
  network_file_systems: dict[Union[str, PurePosixPath], _NetworkFileSystem] = {},
532
509
  volumes: dict[Union[str, PurePosixPath], Union[_Volume, _CloudBucketMount]] = {},
533
510
  webhook_config: Optional[api_pb2.WebhookConfig] = None,
@@ -583,8 +560,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
583
560
  assert not webhook_config
584
561
  assert not schedule
585
562
 
586
- explicit_mounts = mounts
587
-
588
563
  include_source_mode = get_include_source_mode(include_source)
589
564
  if include_source_mode != IncludeSourceMode.INCLUDE_NOTHING:
590
565
  entrypoint_mounts = info.get_entrypoint_mount()
@@ -593,7 +568,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
593
568
 
594
569
  all_mounts = [
595
570
  _get_client_mount(),
596
- *explicit_mounts,
597
571
  *entrypoint_mounts.values(),
598
572
  ]
599
573
 
@@ -633,7 +607,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
633
607
  image=image,
634
608
  secrets=secrets,
635
609
  gpu=gpu,
636
- mounts=mounts,
637
610
  network_file_systems=network_file_systems,
638
611
  volumes=volumes,
639
612
  memory=memory,
@@ -741,16 +714,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
741
714
 
742
715
  def _deps(only_explicit_mounts=False) -> list[_Object]:
743
716
  deps: list[_Object] = list(secrets)
744
- if only_explicit_mounts:
745
- # TODO: this is a bit hacky, but all_mounts may differ in the container vs locally
746
- # We don't want the function dependencies to change, so we have this way to force it to
747
- # only include its declared dependencies.
748
- # Only objects that need interaction within a user's container actually need to be
749
- # included when only_explicit_mounts=True, so omitting auto mounts here
750
- # wouldn't be a problem as long as Mounts are "passive" and only loaded by the
751
- # worker runtime
752
- deps += list(explicit_mounts)
753
- else:
717
+ if not only_explicit_mounts:
754
718
  deps += list(all_mounts)
755
719
  if proxy:
756
720
  deps.append(proxy)
@@ -1018,7 +982,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1018
982
  obj._build_args = dict( # See get_build_def
1019
983
  secrets=repr(secrets),
1020
984
  gpu_config=repr([parse_gpu_config(_gpu) for _gpu in gpus]),
1021
- mounts=repr(mounts),
1022
985
  network_file_systems=repr(network_file_systems),
1023
986
  )
1024
987
  # these key are excluded if empty to avoid rebuilds on client upgrade
@@ -466,10 +466,7 @@ async def _process_result(result: api_pb2.GenericResult, data_format: int, stub,
466
466
 
467
467
  if result.status == api_pb2.GenericResult.GENERIC_STATUS_TIMEOUT:
468
468
  raise FunctionTimeoutError(result.exception)
469
- elif result.status in [
470
- api_pb2.GenericResult.GENERIC_STATUS_INTERNAL_FAILURE,
471
- api_pb2.GenericResult.GENERIC_STATUS_TERMINATED,
472
- ]:
469
+ elif result.status == api_pb2.GenericResult.GENERIC_STATUS_INTERNAL_FAILURE:
473
470
  raise InternalFailure(result.exception)
474
471
  elif result.status != api_pb2.GenericResult.GENERIC_STATUS_SUCCESS:
475
472
  if data:
modal/app.py CHANGED
@@ -44,7 +44,6 @@ from .exception import ExecutionError, InvalidError
44
44
  from .functions import Function
45
45
  from .gpu import GPU_T
46
46
  from .image import _Image
47
- from .mount import _Mount
48
47
  from .network_file_system import _NetworkFileSystem
49
48
  from .partial_function import PartialFunction
50
49
  from .proxy import _Proxy
@@ -156,7 +155,6 @@ class _App:
156
155
  _classes: dict[str, _Cls]
157
156
 
158
157
  _image: Optional[_Image]
159
- _mounts: Sequence[_Mount]
160
158
  _secrets: Sequence[_Secret]
161
159
  _volumes: dict[Union[str, PurePosixPath], _Volume]
162
160
  _web_endpoints: list[str] # Used by the CLI
@@ -174,7 +172,6 @@ class _App:
174
172
  name: Optional[str] = None,
175
173
  *,
176
174
  image: Optional[_Image] = None, # default image for all functions (default is `modal.Image.debian_slim()`)
177
- mounts: Sequence[_Mount] = [], # default mounts for all functions
178
175
  secrets: Sequence[_Secret] = [], # default secrets for all functions
179
176
  volumes: dict[Union[str, PurePosixPath], _Volume] = {}, # default volumes for all functions
180
177
  include_source: Optional[bool] = None,
@@ -195,7 +192,6 @@ class _App:
195
192
  self._description = name
196
193
  self._include_source_default = include_source
197
194
 
198
- check_sequence(mounts, _Mount, "`mounts=` has to be a list or tuple of `modal.Mount` objects")
199
195
  check_sequence(secrets, _Secret, "`secrets=` has to be a list or tuple of `modal.Secret` objects")
200
196
  validate_volumes(volumes)
201
197
 
@@ -205,7 +201,6 @@ class _App:
205
201
  self._functions = {}
206
202
  self._classes = {}
207
203
  self._image = image
208
- self._mounts = mounts
209
204
  self._secrets = secrets
210
205
  self._volumes = volumes
211
206
  self._local_entrypoints = {}
@@ -446,9 +441,7 @@ class _App:
446
441
  if not self._running_app:
447
442
  raise ExecutionError("`_get_watch_mounts` requires a running app.")
448
443
 
449
- all_mounts = [
450
- *self._mounts,
451
- ]
444
+ all_mounts = []
452
445
  for function in self.registered_functions.values():
453
446
  all_mounts.extend(function._serve_mounts)
454
447
 
@@ -612,7 +605,6 @@ class _App:
612
605
  GPU_T, list[GPU_T]
613
606
  ] = None, # GPU request as string ("any", "T4", ...), object (`modal.GPU.A100()`, ...), or a list of either
614
607
  serialized: bool = False, # Whether to send the function over using cloudpickle.
615
- mounts: Sequence[_Mount] = (), # Modal Mounts added to the container
616
608
  network_file_systems: dict[
617
609
  Union[str, PurePosixPath], _NetworkFileSystem
618
610
  ] = {}, # Mountpoints for Modal NetworkFileSystems
@@ -792,7 +784,6 @@ class _App:
792
784
  schedule=schedule,
793
785
  is_generator=is_generator,
794
786
  gpu=gpu,
795
- mounts=[*self._mounts, *mounts],
796
787
  network_file_systems=network_file_systems,
797
788
  volumes={**self._volumes, **volumes},
798
789
  cpu=cpu,
@@ -843,7 +834,6 @@ class _App:
843
834
  GPU_T, list[GPU_T]
844
835
  ] = None, # GPU request as string ("any", "T4", ...), object (`modal.GPU.A100()`, ...), or a list of either
845
836
  serialized: bool = False, # Whether to send the function over using cloudpickle.
846
- mounts: Sequence[_Mount] = (),
847
837
  network_file_systems: dict[
848
838
  Union[str, PurePosixPath], _NetworkFileSystem
849
839
  ] = {}, # Mountpoints for Modal NetworkFileSystems
@@ -965,7 +955,6 @@ class _App:
965
955
  image=image or self._get_default_image(),
966
956
  secrets=[*self._secrets, *secrets],
967
957
  gpu=gpu,
968
- mounts=[*self._mounts, *mounts],
969
958
  network_file_systems=network_file_systems,
970
959
  volumes={**self._volumes, **volumes},
971
960
  cpu=cpu,
modal/app.pyi CHANGED
@@ -8,7 +8,6 @@ import modal.cls
8
8
  import modal.functions
9
9
  import modal.gpu
10
10
  import modal.image
11
- import modal.mount
12
11
  import modal.network_file_system
13
12
  import modal.partial_function
14
13
  import modal.proxy
@@ -77,7 +76,6 @@ class _App:
77
76
  _functions: dict[str, modal._functions._Function]
78
77
  _classes: dict[str, modal.cls._Cls]
79
78
  _image: typing.Optional[modal.image._Image]
80
- _mounts: collections.abc.Sequence[modal.mount._Mount]
81
79
  _secrets: collections.abc.Sequence[modal.secret._Secret]
82
80
  _volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume._Volume]
83
81
  _web_endpoints: list[str]
@@ -92,7 +90,6 @@ class _App:
92
90
  name: typing.Optional[str] = None,
93
91
  *,
94
92
  image: typing.Optional[modal.image._Image] = None,
95
- mounts: collections.abc.Sequence[modal.mount._Mount] = [],
96
93
  secrets: collections.abc.Sequence[modal.secret._Secret] = [],
97
94
  volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume._Volume] = {},
98
95
  include_source: typing.Optional[bool] = None,
@@ -164,7 +161,6 @@ class _App:
164
161
  secrets: collections.abc.Sequence[modal.secret._Secret] = (),
165
162
  gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
166
163
  serialized: bool = False,
167
- mounts: collections.abc.Sequence[modal.mount._Mount] = (),
168
164
  network_file_systems: dict[
169
165
  typing.Union[str, pathlib.PurePosixPath], modal.network_file_system._NetworkFileSystem
170
166
  ] = {},
@@ -216,7 +212,6 @@ class _App:
216
212
  secrets: collections.abc.Sequence[modal.secret._Secret] = (),
217
213
  gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
218
214
  serialized: bool = False,
219
- mounts: collections.abc.Sequence[modal.mount._Mount] = (),
220
215
  network_file_systems: dict[
221
216
  typing.Union[str, pathlib.PurePosixPath], modal.network_file_system._NetworkFileSystem
222
217
  ] = {},
@@ -272,7 +267,6 @@ class App:
272
267
  _functions: dict[str, modal.functions.Function]
273
268
  _classes: dict[str, modal.cls.Cls]
274
269
  _image: typing.Optional[modal.image.Image]
275
- _mounts: collections.abc.Sequence[modal.mount.Mount]
276
270
  _secrets: collections.abc.Sequence[modal.secret.Secret]
277
271
  _volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume.Volume]
278
272
  _web_endpoints: list[str]
@@ -287,7 +281,6 @@ class App:
287
281
  name: typing.Optional[str] = None,
288
282
  *,
289
283
  image: typing.Optional[modal.image.Image] = None,
290
- mounts: collections.abc.Sequence[modal.mount.Mount] = [],
291
284
  secrets: collections.abc.Sequence[modal.secret.Secret] = [],
292
285
  volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume.Volume] = {},
293
286
  include_source: typing.Optional[bool] = None,
@@ -410,7 +403,6 @@ class App:
410
403
  secrets: collections.abc.Sequence[modal.secret.Secret] = (),
411
404
  gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
412
405
  serialized: bool = False,
413
- mounts: collections.abc.Sequence[modal.mount.Mount] = (),
414
406
  network_file_systems: dict[
415
407
  typing.Union[str, pathlib.PurePosixPath], modal.network_file_system.NetworkFileSystem
416
408
  ] = {},
@@ -462,7 +454,6 @@ class App:
462
454
  secrets: collections.abc.Sequence[modal.secret.Secret] = (),
463
455
  gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
464
456
  serialized: bool = False,
465
- mounts: collections.abc.Sequence[modal.mount.Mount] = (),
466
457
  network_file_systems: dict[
467
458
  typing.Union[str, pathlib.PurePosixPath], modal.network_file_system.NetworkFileSystem
468
459
  ] = {},
modal/client.pyi CHANGED
@@ -31,7 +31,7 @@ class _Client:
31
31
  server_url: str,
32
32
  client_type: int,
33
33
  credentials: typing.Optional[tuple[str, str]],
34
- version: str = "1.0.0.dev17",
34
+ version: str = "1.0.0.dev19",
35
35
  ): ...
36
36
  def is_closed(self) -> bool: ...
37
37
  @property
@@ -94,7 +94,7 @@ class Client:
94
94
  server_url: str,
95
95
  client_type: int,
96
96
  credentials: typing.Optional[tuple[str, str]],
97
- version: str = "1.0.0.dev17",
97
+ version: str = "1.0.0.dev19",
98
98
  ): ...
99
99
  def is_closed(self) -> bool: ...
100
100
  @property
modal/functions.pyi CHANGED
@@ -63,7 +63,6 @@ class Function(
63
63
  schedule: typing.Optional[modal.schedule.Schedule] = None,
64
64
  is_generator: bool = False,
65
65
  gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
66
- mounts: collections.abc.Collection[modal.mount.Mount] = (),
67
66
  network_file_systems: dict[
68
67
  typing.Union[str, pathlib.PurePosixPath], modal.network_file_system.NetworkFileSystem
69
68
  ] = {},
@@ -228,11 +227,11 @@ class Function(
228
227
 
229
228
  _call_generator: ___call_generator_spec[typing_extensions.Self]
230
229
 
231
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
230
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
232
231
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
233
232
  async def aio(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
234
233
 
235
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
234
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
236
235
 
237
236
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
238
237
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -247,12 +246,12 @@ class Function(
247
246
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
248
247
  ) -> modal._functions.OriginalReturnType: ...
249
248
 
250
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
249
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
251
250
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
252
251
  async def aio(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
253
252
 
254
253
  _experimental_spawn: ___experimental_spawn_spec[
255
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
254
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
256
255
  ]
257
256
 
258
257
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
@@ -261,11 +260,11 @@ class Function(
261
260
 
262
261
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
263
262
 
264
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
263
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
265
264
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
266
265
  async def aio(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
267
266
 
268
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
267
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
269
268
 
270
269
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
271
270
 
modal/image.py CHANGED
@@ -437,7 +437,7 @@ class _Image(_Object, type_prefix="im"):
437
437
 
438
438
  def _add_mount_layer_or_copy(self, mount: _Mount, copy: bool = False):
439
439
  if copy:
440
- return self.copy_mount(mount, remote_path="/")
440
+ return self._copy_mount(mount, remote_path="/")
441
441
 
442
442
  base_image = self
443
443
 
@@ -672,23 +672,9 @@ class _Image(_Object, type_prefix="im"):
672
672
  )
673
673
  return obj
674
674
 
675
- def copy_mount(self, mount: _Mount, remote_path: Union[str, Path] = ".") -> "_Image":
675
+ def _copy_mount(self, mount: _Mount, remote_path: Union[str, Path] = ".") -> "_Image":
676
676
  """mdmd:hidden
677
- **Deprecated**: Use image.add_local_dir(..., copy=True) or similar instead.
678
-
679
- Copy the entire contents of a `modal.Mount` into an image.
680
- Useful when files only available locally are required during the image
681
- build process.
682
-
683
- **Example**
684
-
685
- ```python notest
686
- static_images_dir = "./static"
687
- # place all static images in root of mount
688
- mount = modal.Mount.from_local_dir(static_images_dir, remote_path="/")
689
- # place mount's contents into /static directory of image.
690
- image = modal.Image.debian_slim().copy_mount(mount, remote_path="/static")
691
- ```
677
+ Internal
692
678
  """
693
679
  if not isinstance(mount, _Mount):
694
680
  raise InvalidError("The mount argument to copy has to be a Modal Mount object")
@@ -1892,7 +1878,6 @@ class _Image(_Object, type_prefix="im"):
1892
1878
  *,
1893
1879
  secrets: Sequence[_Secret] = (), # Optional Modal Secret objects with environment variables for the container
1894
1880
  gpu: Union[GPU_T, list[GPU_T]] = None, # Requested GPU or or list of acceptable GPUs( e.g. ["A10", "A100"])
1895
- mounts: Sequence[_Mount] = (), # Mounts attached to the function
1896
1881
  volumes: dict[Union[str, PurePosixPath], Union[_Volume, _CloudBucketMount]] = {}, # Volume mount paths
1897
1882
  network_file_systems: dict[Union[str, PurePosixPath], _NetworkFileSystem] = {}, # NFS mount paths
1898
1883
  cpu: Optional[float] = None, # How many CPU cores to request. This is a soft limit.
@@ -1950,7 +1935,6 @@ class _Image(_Object, type_prefix="im"):
1950
1935
  image=self, # type: ignore[reportArgumentType] # TODO: probably conflict with type stub?
1951
1936
  secrets=secrets,
1952
1937
  gpu=gpu,
1953
- mounts=mounts,
1954
1938
  volumes=volumes,
1955
1939
  network_file_systems=network_file_systems,
1956
1940
  cloud=cloud,
modal/image.pyi CHANGED
@@ -120,7 +120,7 @@ class _Image(modal._object._Object):
120
120
  _namespace: int = 1,
121
121
  _do_assert_no_mount_layers: bool = True,
122
122
  ): ...
123
- def copy_mount(self, mount: modal.mount._Mount, remote_path: typing.Union[str, pathlib.Path] = ".") -> _Image: ...
123
+ def _copy_mount(self, mount: modal.mount._Mount, remote_path: typing.Union[str, pathlib.Path] = ".") -> _Image: ...
124
124
  def add_local_file(
125
125
  self, local_path: typing.Union[str, pathlib.Path], remote_path: str, *, copy: bool = False
126
126
  ) -> _Image: ...
@@ -316,7 +316,6 @@ class _Image(modal._object._Object):
316
316
  *,
317
317
  secrets: collections.abc.Sequence[modal.secret._Secret] = (),
318
318
  gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
319
- mounts: collections.abc.Sequence[modal.mount._Mount] = (),
320
319
  volumes: dict[
321
320
  typing.Union[str, pathlib.PurePosixPath],
322
321
  typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
@@ -377,7 +376,7 @@ class Image(modal.object.Object):
377
376
  _namespace: int = 1,
378
377
  _do_assert_no_mount_layers: bool = True,
379
378
  ): ...
380
- def copy_mount(self, mount: modal.mount.Mount, remote_path: typing.Union[str, pathlib.Path] = ".") -> Image: ...
379
+ def _copy_mount(self, mount: modal.mount.Mount, remote_path: typing.Union[str, pathlib.Path] = ".") -> Image: ...
381
380
  def add_local_file(
382
381
  self, local_path: typing.Union[str, pathlib.Path], remote_path: str, *, copy: bool = False
383
382
  ) -> Image: ...
@@ -578,7 +577,6 @@ class Image(modal.object.Object):
578
577
  *,
579
578
  secrets: collections.abc.Sequence[modal.secret.Secret] = (),
580
579
  gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
581
- mounts: collections.abc.Sequence[modal.mount.Mount] = (),
582
580
  volumes: dict[
583
581
  typing.Union[str, pathlib.PurePosixPath],
584
582
  typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
modal/runner.py CHANGED
@@ -601,8 +601,9 @@ async def _interactive_shell(
601
601
  "MODAL_ENVIRONMENT": _get_environment_name(),
602
602
  }
603
603
  secrets = kwargs.pop("secrets", []) + [_Secret.from_dict(sandbox_env)]
604
+
604
605
  with enable_output(): # show any image build logs
605
- sandbox = await _Sandbox.create(
606
+ sandbox = await _Sandbox._create(
606
607
  "sleep",
607
608
  "100000",
608
609
  app=_app,
modal/sandbox.py CHANGED
@@ -12,6 +12,7 @@ from grpclib import GRPCError, Status
12
12
 
13
13
  from modal._tunnel import Tunnel
14
14
  from modal.cloud_bucket_mount import _CloudBucketMount, cloud_bucket_mounts_to_proto
15
+ from modal.mount import _Mount
15
16
  from modal.volume import _Volume
16
17
  from modal_proto import api_pb2
17
18
 
@@ -29,7 +30,6 @@ from .file_io import FileWatchEvent, FileWatchEventType, _FileIO
29
30
  from .gpu import GPU_T
30
31
  from .image import _Image
31
32
  from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
32
- from .mount import _Mount
33
33
  from .network_file_system import _NetworkFileSystem, network_file_system_mount_protos
34
34
  from .proxy import _Proxy
35
35
  from .scheduler_placement import SchedulerPlacement
@@ -85,7 +85,6 @@ class _Sandbox(_Object, type_prefix="sb"):
85
85
  def _new(
86
86
  entrypoint_args: Sequence[str],
87
87
  image: _Image,
88
- mounts: Sequence[_Mount],
89
88
  secrets: Sequence[_Secret],
90
89
  timeout: Optional[int] = None,
91
90
  workdir: Optional[str] = None,
@@ -94,6 +93,7 @@ class _Sandbox(_Object, type_prefix="sb"):
94
93
  region: Optional[Union[str, Sequence[str]]] = None,
95
94
  cpu: Optional[float] = None,
96
95
  memory: Optional[Union[int, tuple[int, int]]] = None,
96
+ mounts: Sequence[_Mount] = (),
97
97
  network_file_systems: dict[Union[str, os.PathLike], _NetworkFileSystem] = {},
98
98
  block_network: bool = False,
99
99
  cidr_allowlist: Optional[Sequence[str]] = None,
@@ -217,7 +217,6 @@ class _Sandbox(_Object, type_prefix="sb"):
217
217
  app: Optional["modal.app._App"] = None, # Optionally associate the sandbox with an app
218
218
  environment_name: Optional[str] = None, # Optionally override the default environment
219
219
  image: Optional[_Image] = None, # The image to run as the container for the sandbox.
220
- mounts: Sequence[_Mount] = (), # Mounts to attach to the sandbox.
221
220
  secrets: Sequence[_Secret] = (), # Environment variables to inject into the sandbox.
222
221
  network_file_systems: dict[Union[str, os.PathLike], _NetworkFileSystem] = {},
223
222
  timeout: Optional[int] = None, # Maximum execution time of the sandbox in seconds.
@@ -264,6 +263,76 @@ class _Sandbox(_Object, type_prefix="sb"):
264
263
  sandbox.wait()
265
264
  ```
266
265
  """
266
+ return await _Sandbox._create(
267
+ *entrypoint_args,
268
+ app=app,
269
+ environment_name=environment_name,
270
+ image=image,
271
+ secrets=secrets,
272
+ network_file_systems=network_file_systems,
273
+ timeout=timeout,
274
+ workdir=workdir,
275
+ gpu=gpu,
276
+ cloud=cloud,
277
+ region=region,
278
+ cpu=cpu,
279
+ memory=memory,
280
+ block_network=block_network,
281
+ cidr_allowlist=cidr_allowlist,
282
+ volumes=volumes,
283
+ pty_info=pty_info,
284
+ encrypted_ports=encrypted_ports,
285
+ unencrypted_ports=unencrypted_ports,
286
+ proxy=proxy,
287
+ _experimental_enable_snapshot=_experimental_enable_snapshot,
288
+ _experimental_scheduler_placement=_experimental_scheduler_placement,
289
+ client=client,
290
+ )
291
+
292
+ @staticmethod
293
+ async def _create(
294
+ *entrypoint_args: str,
295
+ app: Optional["modal.app._App"] = None, # Optionally associate the sandbox with an app
296
+ environment_name: Optional[str] = None, # Optionally override the default environment
297
+ image: Optional[_Image] = None, # The image to run as the container for the sandbox.
298
+ secrets: Sequence[_Secret] = (), # Environment variables to inject into the sandbox.
299
+ mounts: Sequence[_Mount] = (),
300
+ network_file_systems: dict[Union[str, os.PathLike], _NetworkFileSystem] = {},
301
+ timeout: Optional[int] = None, # Maximum execution time of the sandbox in seconds.
302
+ workdir: Optional[str] = None, # Working directory of the sandbox.
303
+ gpu: GPU_T = None,
304
+ cloud: Optional[str] = None,
305
+ region: Optional[Union[str, Sequence[str]]] = None, # Region or regions to run the sandbox on.
306
+ # Specify, in fractional CPU cores, how many CPU cores to request.
307
+ # Or, pass (request, limit) to additionally specify a hard limit in fractional CPU cores.
308
+ # CPU throttling will prevent a container from exceeding its specified limit.
309
+ cpu: Optional[Union[float, tuple[float, float]]] = None,
310
+ # Specify, in MiB, a memory request which is the minimum memory required.
311
+ # Or, pass (request, limit) to additionally specify a hard limit in MiB.
312
+ memory: Optional[Union[int, tuple[int, int]]] = None,
313
+ block_network: bool = False, # Whether to block network access
314
+ # List of CIDRs the sandbox is allowed to access. If None, all CIDRs are allowed.
315
+ cidr_allowlist: Optional[Sequence[str]] = None,
316
+ volumes: dict[
317
+ Union[str, os.PathLike], Union[_Volume, _CloudBucketMount]
318
+ ] = {}, # Mount points for Modal Volumes and CloudBucketMounts
319
+ pty_info: Optional[api_pb2.PTYInfo] = None,
320
+ # List of ports to tunnel into the sandbox. Encrypted ports are tunneled with TLS.
321
+ encrypted_ports: Sequence[int] = [],
322
+ # List of ports to tunnel into the sandbox without encryption.
323
+ unencrypted_ports: Sequence[int] = [],
324
+ # Reference to a Modal Proxy to use in front of this Sandbox.
325
+ proxy: Optional[_Proxy] = None,
326
+ # Enable memory snapshots.
327
+ _experimental_enable_snapshot: bool = False,
328
+ _experimental_scheduler_placement: Optional[
329
+ SchedulerPlacement
330
+ ] = None, # Experimental controls over fine-grained scheduling (alpha).
331
+ client: Optional[_Client] = None,
332
+ ):
333
+ # This method exposes some internal arguments (currently `mounts`) which are not in the public API
334
+ # `mounts` is currently only used by modal shell (cli) to provide a function's mounts to the
335
+ # sandbox that runs the shell session
267
336
  from .app import _App
268
337
 
269
338
  environment_name = _get_environment_name(environment_name)
@@ -274,7 +343,6 @@ class _Sandbox(_Object, type_prefix="sb"):
274
343
  obj = _Sandbox._new(
275
344
  entrypoint_args,
276
345
  image=image or _default_image,
277
- mounts=mounts,
278
346
  secrets=secrets,
279
347
  timeout=timeout,
280
348
  workdir=workdir,
@@ -283,6 +351,7 @@ class _Sandbox(_Object, type_prefix="sb"):
283
351
  region=region,
284
352
  cpu=cpu,
285
353
  memory=memory,
354
+ mounts=mounts,
286
355
  network_file_systems=network_file_systems,
287
356
  block_network=block_network,
288
357
  cidr_allowlist=cidr_allowlist,
modal/sandbox.pyi CHANGED
@@ -40,7 +40,6 @@ class _Sandbox(modal._object._Object):
40
40
  def _new(
41
41
  entrypoint_args: collections.abc.Sequence[str],
42
42
  image: modal.image._Image,
43
- mounts: collections.abc.Sequence[modal.mount._Mount],
44
43
  secrets: collections.abc.Sequence[modal.secret._Secret],
45
44
  timeout: typing.Optional[int] = None,
46
45
  workdir: typing.Optional[str] = None,
@@ -49,6 +48,7 @@ class _Sandbox(modal._object._Object):
49
48
  region: typing.Union[str, collections.abc.Sequence[str], None] = None,
50
49
  cpu: typing.Optional[float] = None,
51
50
  memory: typing.Union[int, tuple[int, int], None] = None,
51
+ mounts: collections.abc.Sequence[modal.mount._Mount] = (),
52
52
  network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system._NetworkFileSystem] = {},
53
53
  block_network: bool = False,
54
54
  cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
@@ -69,7 +69,6 @@ class _Sandbox(modal._object._Object):
69
69
  app: typing.Optional[modal.app._App] = None,
70
70
  environment_name: typing.Optional[str] = None,
71
71
  image: typing.Optional[modal.image._Image] = None,
72
- mounts: collections.abc.Sequence[modal.mount._Mount] = (),
73
72
  secrets: collections.abc.Sequence[modal.secret._Secret] = (),
74
73
  network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system._NetworkFileSystem] = {},
75
74
  timeout: typing.Optional[int] = None,
@@ -93,6 +92,36 @@ class _Sandbox(modal._object._Object):
93
92
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
94
93
  client: typing.Optional[modal.client._Client] = None,
95
94
  ) -> _Sandbox: ...
95
+ @staticmethod
96
+ async def _create(
97
+ *entrypoint_args: str,
98
+ app: typing.Optional[modal.app._App] = None,
99
+ environment_name: typing.Optional[str] = None,
100
+ image: typing.Optional[modal.image._Image] = None,
101
+ secrets: collections.abc.Sequence[modal.secret._Secret] = (),
102
+ mounts: collections.abc.Sequence[modal.mount._Mount] = (),
103
+ network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system._NetworkFileSystem] = {},
104
+ timeout: typing.Optional[int] = None,
105
+ workdir: typing.Optional[str] = None,
106
+ gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
107
+ cloud: typing.Optional[str] = None,
108
+ region: typing.Union[str, collections.abc.Sequence[str], None] = None,
109
+ cpu: typing.Union[float, tuple[float, float], None] = None,
110
+ memory: typing.Union[int, tuple[int, int], None] = None,
111
+ block_network: bool = False,
112
+ cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
113
+ volumes: dict[
114
+ typing.Union[str, os.PathLike],
115
+ typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
116
+ ] = {},
117
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
118
+ encrypted_ports: collections.abc.Sequence[int] = [],
119
+ unencrypted_ports: collections.abc.Sequence[int] = [],
120
+ proxy: typing.Optional[modal.proxy._Proxy] = None,
121
+ _experimental_enable_snapshot: bool = False,
122
+ _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
123
+ client: typing.Optional[modal.client._Client] = None,
124
+ ): ...
96
125
  def _hydrate_metadata(self, handle_metadata: typing.Optional[google.protobuf.message.Message]): ...
97
126
  @staticmethod
98
127
  async def from_id(sandbox_id: str, client: typing.Optional[modal.client._Client] = None) -> _Sandbox: ...
@@ -182,7 +211,6 @@ class Sandbox(modal.object.Object):
182
211
  def _new(
183
212
  entrypoint_args: collections.abc.Sequence[str],
184
213
  image: modal.image.Image,
185
- mounts: collections.abc.Sequence[modal.mount.Mount],
186
214
  secrets: collections.abc.Sequence[modal.secret.Secret],
187
215
  timeout: typing.Optional[int] = None,
188
216
  workdir: typing.Optional[str] = None,
@@ -191,6 +219,7 @@ class Sandbox(modal.object.Object):
191
219
  region: typing.Union[str, collections.abc.Sequence[str], None] = None,
192
220
  cpu: typing.Optional[float] = None,
193
221
  memory: typing.Union[int, tuple[int, int], None] = None,
222
+ mounts: collections.abc.Sequence[modal.mount.Mount] = (),
194
223
  network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem] = {},
195
224
  block_network: bool = False,
196
225
  cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
@@ -213,7 +242,6 @@ class Sandbox(modal.object.Object):
213
242
  app: typing.Optional[modal.app.App] = None,
214
243
  environment_name: typing.Optional[str] = None,
215
244
  image: typing.Optional[modal.image.Image] = None,
216
- mounts: collections.abc.Sequence[modal.mount.Mount] = (),
217
245
  secrets: collections.abc.Sequence[modal.secret.Secret] = (),
218
246
  network_file_systems: dict[
219
247
  typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
@@ -246,7 +274,6 @@ class Sandbox(modal.object.Object):
246
274
  app: typing.Optional[modal.app.App] = None,
247
275
  environment_name: typing.Optional[str] = None,
248
276
  image: typing.Optional[modal.image.Image] = None,
249
- mounts: collections.abc.Sequence[modal.mount.Mount] = (),
250
277
  secrets: collections.abc.Sequence[modal.secret.Secret] = (),
251
278
  network_file_systems: dict[
252
279
  typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
@@ -275,6 +302,76 @@ class Sandbox(modal.object.Object):
275
302
 
276
303
  create: __create_spec
277
304
 
305
+ class ___create_spec(typing_extensions.Protocol):
306
+ def __call__(
307
+ self,
308
+ /,
309
+ *entrypoint_args: str,
310
+ app: typing.Optional[modal.app.App] = None,
311
+ environment_name: typing.Optional[str] = None,
312
+ image: typing.Optional[modal.image.Image] = None,
313
+ secrets: collections.abc.Sequence[modal.secret.Secret] = (),
314
+ mounts: collections.abc.Sequence[modal.mount.Mount] = (),
315
+ network_file_systems: dict[
316
+ typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
317
+ ] = {},
318
+ timeout: typing.Optional[int] = None,
319
+ workdir: typing.Optional[str] = None,
320
+ gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
321
+ cloud: typing.Optional[str] = None,
322
+ region: typing.Union[str, collections.abc.Sequence[str], None] = None,
323
+ cpu: typing.Union[float, tuple[float, float], None] = None,
324
+ memory: typing.Union[int, tuple[int, int], None] = None,
325
+ block_network: bool = False,
326
+ cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
327
+ volumes: dict[
328
+ typing.Union[str, os.PathLike],
329
+ typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
330
+ ] = {},
331
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
332
+ encrypted_ports: collections.abc.Sequence[int] = [],
333
+ unencrypted_ports: collections.abc.Sequence[int] = [],
334
+ proxy: typing.Optional[modal.proxy.Proxy] = None,
335
+ _experimental_enable_snapshot: bool = False,
336
+ _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
337
+ client: typing.Optional[modal.client.Client] = None,
338
+ ): ...
339
+ async def aio(
340
+ self,
341
+ /,
342
+ *entrypoint_args: str,
343
+ app: typing.Optional[modal.app.App] = None,
344
+ environment_name: typing.Optional[str] = None,
345
+ image: typing.Optional[modal.image.Image] = None,
346
+ secrets: collections.abc.Sequence[modal.secret.Secret] = (),
347
+ mounts: collections.abc.Sequence[modal.mount.Mount] = (),
348
+ network_file_systems: dict[
349
+ typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
350
+ ] = {},
351
+ timeout: typing.Optional[int] = None,
352
+ workdir: typing.Optional[str] = None,
353
+ gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
354
+ cloud: typing.Optional[str] = None,
355
+ region: typing.Union[str, collections.abc.Sequence[str], None] = None,
356
+ cpu: typing.Union[float, tuple[float, float], None] = None,
357
+ memory: typing.Union[int, tuple[int, int], None] = None,
358
+ block_network: bool = False,
359
+ cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
360
+ volumes: dict[
361
+ typing.Union[str, os.PathLike],
362
+ typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
363
+ ] = {},
364
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
365
+ encrypted_ports: collections.abc.Sequence[int] = [],
366
+ unencrypted_ports: collections.abc.Sequence[int] = [],
367
+ proxy: typing.Optional[modal.proxy.Proxy] = None,
368
+ _experimental_enable_snapshot: bool = False,
369
+ _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
370
+ client: typing.Optional[modal.client.Client] = None,
371
+ ): ...
372
+
373
+ _create: ___create_spec
374
+
278
375
  def _hydrate_metadata(self, handle_metadata: typing.Optional[google.protobuf.message.Message]): ...
279
376
 
280
377
  class __from_id_spec(typing_extensions.Protocol):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.0.dev17
3
+ Version: 1.0.0.dev19
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -1,9 +1,9 @@
1
- modal/__init__.py,sha256=AaO8fXHO6BYltmFoYOwCB2pSjEECXVvGK5p2Vfo_SpU,2752
1
+ modal/__init__.py,sha256=1131svUxi876UMFC6Z68qe5Z031ZfZ9NrduvGwHphj8,2710
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=2aWxN2v5WUnj-R-sk6BzJ-3AvggkQGQjwhtvbDH3pds,777
5
5
  modal/_container_entrypoint.py,sha256=2Zx9O_EMJg0H77EdnC2vGKs6uFMWwbP1NLFf-qYmWmU,28962
6
- modal/_functions.py,sha256=kIyUjK1v6C8RWXSkkJI5kTO3mz--gkO-3aA9f40aaog,79212
6
+ modal/_functions.py,sha256=HSQ8BVar2RsMD4ud83iUKvE7NSyEoVsTc-3quW8YObA,77149
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=KzzzZoM41UQUiY9TKOrft9BtZKgjWG_ukdlyLGjB4UY,10758
@@ -18,11 +18,11 @@ modal/_tunnel.py,sha256=zTBxBiuH1O22tS1OliAJdIsSmaZS8PlnifS_6S5z-mk,6320
18
18
  modal/_tunnel.pyi,sha256=a4Ea0RQ5jaJB0A4LH9FANGB44ObqkHHGVDV4RwtokzU,1251
19
19
  modal/_type_manager.py,sha256=DWjgmjYJuOagw2erin506UUbG2H5UzZCFEekS-7hmfA,9087
20
20
  modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
21
- modal/app.py,sha256=Wz9DIFzO2ByObuqoh3zk9B76WTWcPqYoQDuPU-yrLTU,47100
22
- modal/app.pyi,sha256=1dHHI6RgvJ1y5Ouzb1_S-wpjfjCL7QHz0gqE4BxMw10,23192
21
+ modal/app.py,sha256=NZ_rJ9TuMfiNiLg8-gOFgufD5flGtXWPHOZI0gdD3hE,46585
22
+ modal/app.pyi,sha256=4-b_vbe3lNAqQPcMRpQCEDsE1zsVkQRJGUql9B7HvbM,22659
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=o-aQThHpvDHUzg_kUafyhWzACViUBhY2WLZ2EitnSHA,16787
25
- modal/client.pyi,sha256=Ddk29klkblcqrIS02IgWDkKgrLTgAXIqYTAF2PFmDSM,8459
25
+ modal/client.pyi,sha256=SQcb7cVcVA9JvRHfZe0elbkd32wV3mwWyUl50N6lI-I,8459
26
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
27
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
28
28
  modal/cls.py,sha256=dBbeARwOWftlKd1cwtM0cHFtQWSWkwVXwVmOV4w0SyI,37907
@@ -39,10 +39,10 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
39
39
  modal/file_io.pyi,sha256=oB7x-rKq7bmm8cA7Z7W9C9yeko7KK9m9i5GidFnkGK4,9569
40
40
  modal/file_pattern_matcher.py,sha256=wov-otB5M1oTdrYDtR2_VgacYin2srdtAP4McA1Cqzw,6516
41
41
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
42
- modal/functions.pyi,sha256=YE2ZjUSY-sToZK0cRtmSrIp9fI3kr39-6EGhMLVy5pQ,16304
42
+ modal/functions.pyi,sha256=iqdp5ixtOOlm8bF-QYbD_G8VKqSRt_AVLT7AWjpn6pQ,16236
43
43
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
44
- modal/image.py,sha256=glnu6LDf3iFq71CGVstHx40CKVN4rw8tukPLAy5JgTQ,92464
45
- modal/image.pyi,sha256=NbegOjy6QX_SL-eTxtJm1_4gOJHW04Ja449QHZIdKgU,25586
44
+ modal/image.py,sha256=yfOaKHS0YQtaAB1lb9Dv22fV5jqp_7qeIYLtz5vVc6w,91751
45
+ modal/image.pyi,sha256=V0IKbs_fAvkxzFrceJm5W_Dl4s5ATy4LEy8L2tMuemQ,25455
46
46
  modal/io_streams.py,sha256=YDZVQSDv05DeXg5TwcucC9Rj5hQBx2GXdluan9rIUpw,15467
47
47
  modal/io_streams.pyi,sha256=1UK6kWLREASQfq-wL9wSp5iqjLU0egRZPDn4LXs1PZY,5136
48
48
  modal/mount.py,sha256=HbpGQbqqT5pTP4dh8j6USWXb2Fr1ro3V1uHIardkya4,30726
@@ -62,11 +62,11 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
62
  modal/queue.py,sha256=lu-QYW8GTqhZgX0TPTndmltT9uIWgLFV5mKZ_yTfmd4,18829
63
63
  modal/queue.pyi,sha256=O0f0S5kM1P0GVgzUzgsN0XsI46B9cJem4kkWluFndjM,10632
64
64
  modal/retries.py,sha256=IvNLDM0f_GLUDD5VgEDoN09C88yoxSrCquinAuxT1Sc,5205
65
- modal/runner.py,sha256=BqqN9rWfr-Bwuv9fVNZqAwZnM8OSC9H-HTJC1KQPRMg,24150
65
+ modal/runner.py,sha256=nvpnU7U2O5d2WqME1QUTTwu-NkSLLwblytlGk7HXPAw,24152
66
66
  modal/runner.pyi,sha256=1AnEu48SUPnLWp3raQ2zJCV5lc85EGLkX2nL0bHWaB0,5162
67
67
  modal/running_app.py,sha256=v61mapYNV1-O-Uaho5EfJlryMLvIT9We0amUOSvSGx8,1188
68
- modal/sandbox.py,sha256=RuTA3VjnOTNDRAxIzW9ffxHhUG4PDK5SUyNVWYeqSBw,31941
69
- modal/sandbox.pyi,sha256=BD1VfQGFY6X6sismOWGd8_UMTPE7-gs3eSfNFw44u2M,22931
68
+ modal/sandbox.py,sha256=VwbbQPK6e03kp11M8SQWbe6SLWSOwMaFwoQLYdP5EV0,35573
69
+ modal/sandbox.pyi,sha256=stxwoLcyQNToPISj6umlU8sDUgqzeooLdMs3BwIr740,28195
70
70
  modal/schedule.py,sha256=ewa7hb9NKYnoeSCW2PujZAbGGJL8btX6X3KalCFpc_M,2626
71
71
  modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
72
72
  modal/secret.py,sha256=I2z-rgKWl_Ix107d2_Y2OWGXdFOuJ7zMOyDfIOdFI1A,10374
@@ -96,7 +96,7 @@ modal/_utils/blob_utils.py,sha256=IexC2Jbtqp_Tkmy62ayfgzTYte0UPCNufB_v-DO21g8,18
96
96
  modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
97
97
  modal/_utils/deprecation.py,sha256=EXP1beU4pmEqEzWMLw6E3kUfNfpmNA_VOp6i0EHi93g,4856
98
98
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
99
- modal/_utils/function_utils.py,sha256=qi_ubD5jvOpksKvaxitJDXxfVl1R2Kph6eX8k3y5Hz4,27052
99
+ modal/_utils/function_utils.py,sha256=bhrjyOHPPXm6fAyJx3bzI1Yh56j6xh8eeMSFKdAWrHQ,26978
100
100
  modal/_utils/git_utils.py,sha256=qtUU6JAttF55ZxYq51y55OR58B0tDPZsZWK5dJe6W5g,3182
101
101
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
102
102
  modal/_utils/grpc_utils.py,sha256=xSFosSJYQ4m6cH9WtChcSXqsnyk6DMeVvOHI4N3914g,10922
@@ -146,7 +146,7 @@ modal/requirements/2024.10.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddR
146
146
  modal/requirements/PREVIEW.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddRo,296
147
147
  modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
148
148
  modal/requirements/base-images.json,sha256=57vMSqzMbLBxw5tFWSaMiIkkVEps4JfX5PAtXGnkS4U,740
149
- modal-1.0.0.dev17.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
149
+ modal-1.0.0.dev19.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
150
150
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
151
151
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
152
152
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -169,10 +169,10 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
169
169
  modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
170
170
  modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
171
171
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
- modal_version/__init__.py,sha256=GHKCCzDIY8EaRLgeTTWDfXOXRlxYUKA7fhfqAieG_2M,121
172
+ modal_version/__init__.py,sha256=FR4_HseRm9npOtRt6PAqTMeTh0iZcSgepflnoYAz040,121
173
173
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
174
- modal-1.0.0.dev17.dist-info/METADATA,sha256=FKF7xQQABbtG_5NXNR-eXh7lsACZ0fmK0pAs_sWbWlE,2455
175
- modal-1.0.0.dev17.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
176
- modal-1.0.0.dev17.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
177
- modal-1.0.0.dev17.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
178
- modal-1.0.0.dev17.dist-info/RECORD,,
174
+ modal-1.0.0.dev19.dist-info/METADATA,sha256=onMFcBbloX_n7iUnqwySK_5uAg3gJyoC7JoDWiigpMM,2455
175
+ modal-1.0.0.dev19.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
176
+ modal-1.0.0.dev19.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
177
+ modal-1.0.0.dev19.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
178
+ modal-1.0.0.dev19.dist-info/RECORD,,
modal_version/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.0.0.dev17"
4
+ __version__ = "1.0.0.dev19"