modal 0.75.7__py3-none-any.whl → 0.76.0__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/_functions.py CHANGED
@@ -1075,7 +1075,9 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1075
1075
  serialized_params = serialize_proto_params(kwargs_with_defaults)
1076
1076
  can_use_parent = len(parent._class_parameter_info.schema) == 0 # no parameters
1077
1077
  else:
1078
- can_use_parent = len(args) + len(kwargs) == 0 and options is None
1078
+ from modal.cls import _ServiceOptions # Should probably define this dataclass here?
1079
+
1080
+ can_use_parent = len(args) + len(kwargs) == 0 and (options == _ServiceOptions())
1079
1081
  serialized_params = serialize((args, kwargs))
1080
1082
 
1081
1083
  if can_use_parent:
@@ -1098,14 +1100,18 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1098
1100
  options_pb = api_pb2.FunctionOptions(
1099
1101
  secret_ids=[s.object_id for s in options.secrets],
1100
1102
  replace_secret_ids=bool(options.secrets),
1103
+ replace_volume_mounts=len(volume_mounts) > 0,
1104
+ volume_mounts=volume_mounts,
1101
1105
  resources=options.resources,
1102
1106
  retry_policy=options.retry_policy,
1103
- concurrency_limit=options.concurrency_limit,
1107
+ concurrency_limit=options.max_containers,
1108
+ buffer_containers=options.buffer_containers,
1109
+ task_idle_timeout_secs=options.scaledown_window,
1104
1110
  timeout_secs=options.timeout_secs,
1105
- task_idle_timeout_secs=options.task_idle_timeout_secs,
1106
- replace_volume_mounts=len(volume_mounts) > 0,
1107
- volume_mounts=volume_mounts,
1111
+ max_concurrent_inputs=options.max_concurrent_inputs,
1108
1112
  target_concurrent_inputs=options.target_concurrent_inputs,
1113
+ batch_max_size=options.batch_max_size,
1114
+ batch_linger_ms=options.batch_wait_ms,
1109
1115
  )
1110
1116
  else:
1111
1117
  options_pb = None
@@ -1399,7 +1405,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1399
1405
  definition_id=self._definition_id,
1400
1406
  method_handle_metadata=self._method_handle_metadata,
1401
1407
  function_schema=self._metadata.function_schema if self._metadata else None,
1402
- input_plane_url=self._input_plane_url
1408
+ input_plane_url=self._input_plane_url,
1403
1409
  )
1404
1410
 
1405
1411
  def _check_no_web_url(self, fn_name: str):
modal/client.pyi CHANGED
@@ -27,7 +27,7 @@ class _Client:
27
27
  _snapshotted: bool
28
28
 
29
29
  def __init__(
30
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.75.7"
30
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.76.0"
31
31
  ): ...
32
32
  def is_closed(self) -> bool: ...
33
33
  @property
@@ -86,7 +86,7 @@ class Client:
86
86
  _snapshotted: bool
87
87
 
88
88
  def __init__(
89
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.75.7"
89
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.76.0"
90
90
  ): ...
91
91
  def is_closed(self) -> bool: ...
92
92
  @property
modal/cls.py CHANGED
@@ -75,14 +75,18 @@ def _get_class_constructor_signature(user_cls: type) -> inspect.Signature:
75
75
 
76
76
  @dataclasses.dataclass()
77
77
  class _ServiceOptions:
78
- secrets: typing.Collection[_Secret]
79
- resources: Optional[api_pb2.Resources]
80
- retry_policy: Optional[api_pb2.FunctionRetryPolicy]
81
- concurrency_limit: Optional[int]
82
- timeout_secs: Optional[int]
83
- task_idle_timeout_secs: Optional[int]
84
- validated_volumes: typing.Sequence[tuple[str, _Volume]]
85
- target_concurrent_inputs: Optional[int]
78
+ secrets: typing.Collection[_Secret] = ()
79
+ validated_volumes: typing.Sequence[tuple[str, _Volume]] = ()
80
+ resources: Optional[api_pb2.Resources] = None
81
+ retry_policy: Optional[api_pb2.FunctionRetryPolicy] = None
82
+ max_containers: Optional[int] = None
83
+ buffer_containers: Optional[int] = None
84
+ scaledown_window: Optional[int] = None
85
+ timeout_secs: Optional[int] = None
86
+ max_concurrent_inputs: Optional[int] = None
87
+ target_concurrent_inputs: Optional[int] = None
88
+ batch_max_size: Optional[int] = None
89
+ batch_wait_ms: Optional[int] = None
86
90
 
87
91
 
88
92
  def _bind_instance_method(cls: "_Cls", service_function: _Function, method_name: str):
@@ -421,7 +425,7 @@ class _Cls(_Object, type_prefix="cs"):
421
425
  """
422
426
 
423
427
  _class_service_function: Optional[_Function] # The _Function (read "service") serving *all* methods of the class
424
- _options: Optional[_ServiceOptions]
428
+ _options: _ServiceOptions
425
429
 
426
430
  _app: Optional["modal.app._App"] = None # not set for lookups
427
431
  _name: Optional[str]
@@ -437,7 +441,7 @@ class _Cls(_Object, type_prefix="cs"):
437
441
  def _initialize_from_empty(self):
438
442
  self._user_cls = None
439
443
  self._class_service_function = None
440
- self._options = None
444
+ self._options = _ServiceOptions()
441
445
  self._callables = {}
442
446
  self._name = None
443
447
 
@@ -659,17 +663,15 @@ More information on class parameterization can be found here: https://modal.com/
659
663
  volumes: dict[Union[str, os.PathLike], _Volume] = {},
660
664
  retries: Optional[Union[int, Retries]] = None,
661
665
  max_containers: Optional[int] = None, # Limit on the number of containers that can be concurrently running.
666
+ buffer_containers: Optional[int] = None, # Additional containers to scale up while Function is active.
662
667
  scaledown_window: Optional[int] = None, # Max amount of time a container can remain idle before scaling down.
663
668
  timeout: Optional[int] = None,
664
- allow_concurrent_inputs: Optional[int] = None,
665
669
  # The following parameters are deprecated
666
670
  concurrency_limit: Optional[int] = None, # Now called `max_containers`
667
671
  container_idle_timeout: Optional[int] = None, # Now called `scaledown_window`
672
+ allow_concurrent_inputs: Optional[int] = None, # See `.with_concurrency`
668
673
  ) -> "_Cls":
669
- """
670
- **Beta:** Allows for the runtime modification of a modal.Cls's configuration.
671
-
672
- This is a beta feature and may be unstable.
674
+ """Create an instance of the Cls with configuration options overridden with new values.
673
675
 
674
676
  **Usage:**
675
677
 
@@ -685,6 +687,13 @@ More information on class parameterization can be found here: https://modal.com/
685
687
  else:
686
688
  resources = None
687
689
 
690
+ if allow_concurrent_inputs is not None:
691
+ deprecation_warning(
692
+ (2025, 5, 9),
693
+ "The `allow_concurrent_inputs` argument is deprecated;"
694
+ " please use the `.with_concurrency` method instead.",
695
+ )
696
+
688
697
  async def _load_from_base(new_cls, resolver, existing_object_id):
689
698
  # this is a bit confusing, the cls will always have the same metadata
690
699
  # since it has the same *class* service function (i.e. "template")
@@ -703,19 +712,79 @@ More information on class parameterization can be found here: https://modal.com/
703
712
 
704
713
  cls = _Cls._from_loader(_load_from_base, rep=f"{self._name}.with_options(...)", is_another_app=True, deps=_deps)
705
714
  cls._initialize_from_other(self)
706
- cls._options = _ServiceOptions(
715
+ cls._options = dataclasses.replace(
716
+ cls._options,
707
717
  secrets=secrets,
708
718
  resources=resources,
709
719
  retry_policy=retry_policy,
710
- # TODO(michael) Update the protos to use the new terminology
711
- concurrency_limit=max_containers,
712
- task_idle_timeout_secs=scaledown_window,
720
+ max_containers=max_containers,
721
+ buffer_containers=buffer_containers,
722
+ scaledown_window=scaledown_window,
713
723
  timeout_secs=timeout,
714
724
  validated_volumes=validate_volumes(volumes),
725
+ # Note: set both for backwards / forwards compatibility
726
+ # But going forward `.with_concurrency` is the preferred method with distinct parameterization
727
+ max_concurrent_inputs=allow_concurrent_inputs,
715
728
  target_concurrent_inputs=allow_concurrent_inputs,
716
729
  )
717
730
  return cls
718
731
 
732
+ def with_concurrency(self: "_Cls", *, max_inputs: int, target_inputs: Optional[int] = None) -> "_Cls":
733
+ """Create an instance of the Cls with input concurrency enabled or overridden with new values.
734
+
735
+ **Usage:**
736
+
737
+ ```python notest
738
+ Model = modal.Cls.from_name("my_app", "Model")
739
+ ModelUsingGPU = Model.with_options(gpu="A100").with_concurrency(max_inputs=100)
740
+ ModelUsingGPU().generate.remote(42) # will run on an A100 GPU with input concurrency enabled
741
+ ```
742
+ """
743
+
744
+ async def _load_from_base(new_cls, resolver, existing_object_id):
745
+ if not self.is_hydrated:
746
+ await resolver.load(self)
747
+ new_cls._initialize_from_other(self)
748
+
749
+ def _deps():
750
+ return []
751
+
752
+ cls = _Cls._from_loader(
753
+ _load_from_base, rep=f"{self._name}.with_concurrency(...)", is_another_app=True, deps=_deps
754
+ )
755
+ cls._initialize_from_other(self)
756
+ cls._options = dataclasses.replace(
757
+ cls._options, max_concurrent_inputs=max_inputs, target_concurrent_inputs=target_inputs
758
+ )
759
+ return cls
760
+
761
+ def with_batching(self: "_Cls", *, max_batch_size: int, wait_ms: int) -> "_Cls":
762
+ """Create an instance of the Cls with dynamic batching enabled or overridden with new values.
763
+
764
+ **Usage:**
765
+
766
+ ```python notest
767
+ Model = modal.Cls.from_name("my_app", "Model")
768
+ ModelUsingGPU = Model.with_options(gpu="A100").with_batching(max_batch_size=100, batch_wait_ms=1000)
769
+ ModelUsingGPU().generate.remote(42) # will run on an A100 GPU with input concurrency enabled
770
+ ```
771
+ """
772
+
773
+ async def _load_from_base(new_cls, resolver, existing_object_id):
774
+ if not self.is_hydrated:
775
+ await resolver.load(self)
776
+ new_cls._initialize_from_other(self)
777
+
778
+ def _deps():
779
+ return []
780
+
781
+ cls = _Cls._from_loader(
782
+ _load_from_base, rep=f"{self._name}.with_concurrency(...)", is_another_app=True, deps=_deps
783
+ )
784
+ cls._initialize_from_other(self)
785
+ cls._options = dataclasses.replace(cls._options, batch_max_size=max_batch_size, batch_wait_ms=wait_ms)
786
+ return cls
787
+
719
788
  @staticmethod
720
789
  @renamed_parameter((2024, 12, 18), "tag", "name")
721
790
  async def lookup(
modal/cls.pyi CHANGED
@@ -25,24 +25,32 @@ def _get_class_constructor_signature(user_cls: type) -> inspect.Signature: ...
25
25
 
26
26
  class _ServiceOptions:
27
27
  secrets: typing.Collection[modal.secret._Secret]
28
+ validated_volumes: typing.Sequence[tuple[str, modal.volume._Volume]]
28
29
  resources: typing.Optional[modal_proto.api_pb2.Resources]
29
30
  retry_policy: typing.Optional[modal_proto.api_pb2.FunctionRetryPolicy]
30
- concurrency_limit: typing.Optional[int]
31
+ max_containers: typing.Optional[int]
32
+ buffer_containers: typing.Optional[int]
33
+ scaledown_window: typing.Optional[int]
31
34
  timeout_secs: typing.Optional[int]
32
- task_idle_timeout_secs: typing.Optional[int]
33
- validated_volumes: typing.Sequence[tuple[str, modal.volume._Volume]]
35
+ max_concurrent_inputs: typing.Optional[int]
34
36
  target_concurrent_inputs: typing.Optional[int]
37
+ batch_max_size: typing.Optional[int]
38
+ batch_wait_ms: typing.Optional[int]
35
39
 
36
40
  def __init__(
37
41
  self,
38
- secrets: typing.Collection[modal.secret._Secret],
39
- resources: typing.Optional[modal_proto.api_pb2.Resources],
40
- retry_policy: typing.Optional[modal_proto.api_pb2.FunctionRetryPolicy],
41
- concurrency_limit: typing.Optional[int],
42
- timeout_secs: typing.Optional[int],
43
- task_idle_timeout_secs: typing.Optional[int],
44
- validated_volumes: typing.Sequence[tuple[str, modal.volume._Volume]],
45
- target_concurrent_inputs: typing.Optional[int],
42
+ secrets: typing.Collection[modal.secret._Secret] = (),
43
+ validated_volumes: typing.Sequence[tuple[str, modal.volume._Volume]] = (),
44
+ resources: typing.Optional[modal_proto.api_pb2.Resources] = None,
45
+ retry_policy: typing.Optional[modal_proto.api_pb2.FunctionRetryPolicy] = None,
46
+ max_containers: typing.Optional[int] = None,
47
+ buffer_containers: typing.Optional[int] = None,
48
+ scaledown_window: typing.Optional[int] = None,
49
+ timeout_secs: typing.Optional[int] = None,
50
+ max_concurrent_inputs: typing.Optional[int] = None,
51
+ target_concurrent_inputs: typing.Optional[int] = None,
52
+ batch_max_size: typing.Optional[int] = None,
53
+ batch_wait_ms: typing.Optional[int] = None,
46
54
  ) -> None: ...
47
55
  def __repr__(self): ...
48
56
  def __eq__(self, other): ...
@@ -141,7 +149,7 @@ class Obj:
141
149
 
142
150
  class _Cls(modal._object._Object):
143
151
  _class_service_function: typing.Optional[modal._functions._Function]
144
- _options: typing.Optional[_ServiceOptions]
152
+ _options: _ServiceOptions
145
153
  _app: typing.Optional[modal.app._App]
146
154
  _name: typing.Optional[str]
147
155
  _method_metadata: typing.Optional[dict[str, modal_proto.api_pb2.FunctionHandleMetadata]]
@@ -182,12 +190,15 @@ class _Cls(modal._object._Object):
182
190
  volumes: dict[typing.Union[str, os.PathLike], modal.volume._Volume] = {},
183
191
  retries: typing.Union[int, modal.retries.Retries, None] = None,
184
192
  max_containers: typing.Optional[int] = None,
193
+ buffer_containers: typing.Optional[int] = None,
185
194
  scaledown_window: typing.Optional[int] = None,
186
195
  timeout: typing.Optional[int] = None,
187
- allow_concurrent_inputs: typing.Optional[int] = None,
188
196
  concurrency_limit: typing.Optional[int] = None,
189
197
  container_idle_timeout: typing.Optional[int] = None,
198
+ allow_concurrent_inputs: typing.Optional[int] = None,
190
199
  ) -> _Cls: ...
200
+ def with_concurrency(self: _Cls, *, max_inputs: int, target_inputs: typing.Optional[int] = None) -> _Cls: ...
201
+ def with_batching(self: _Cls, *, max_batch_size: int, wait_ms: int) -> _Cls: ...
191
202
  @staticmethod
192
203
  async def lookup(
193
204
  app_name: str,
@@ -203,7 +214,7 @@ class _Cls(modal._object._Object):
203
214
 
204
215
  class Cls(modal.object.Object):
205
216
  _class_service_function: typing.Optional[modal.functions.Function]
206
- _options: typing.Optional[_ServiceOptions]
217
+ _options: _ServiceOptions
207
218
  _app: typing.Optional[modal.app.App]
208
219
  _name: typing.Optional[str]
209
220
  _method_metadata: typing.Optional[dict[str, modal_proto.api_pb2.FunctionHandleMetadata]]
@@ -245,12 +256,15 @@ class Cls(modal.object.Object):
245
256
  volumes: dict[typing.Union[str, os.PathLike], modal.volume.Volume] = {},
246
257
  retries: typing.Union[int, modal.retries.Retries, None] = None,
247
258
  max_containers: typing.Optional[int] = None,
259
+ buffer_containers: typing.Optional[int] = None,
248
260
  scaledown_window: typing.Optional[int] = None,
249
261
  timeout: typing.Optional[int] = None,
250
- allow_concurrent_inputs: typing.Optional[int] = None,
251
262
  concurrency_limit: typing.Optional[int] = None,
252
263
  container_idle_timeout: typing.Optional[int] = None,
264
+ allow_concurrent_inputs: typing.Optional[int] = None,
253
265
  ) -> Cls: ...
266
+ def with_concurrency(self: Cls, *, max_inputs: int, target_inputs: typing.Optional[int] = None) -> Cls: ...
267
+ def with_batching(self: Cls, *, max_batch_size: int, wait_ms: int) -> Cls: ...
254
268
 
255
269
  class __lookup_spec(typing_extensions.Protocol):
256
270
  def __call__(
@@ -84,7 +84,7 @@ class FilePatternMatcher(_AbstractPatternMatcher):
84
84
  def _set_patterns(self, patterns: Sequence[str]) -> None:
85
85
  self.patterns = []
86
86
  for pattern in list(patterns):
87
- pattern = pattern.strip()
87
+ pattern = pattern.strip().strip(os.path.sep)
88
88
  if not pattern:
89
89
  continue
90
90
  pattern = os.path.normpath(pattern)
modal/image.py CHANGED
@@ -279,8 +279,9 @@ def _create_context_mount(
279
279
  include_fn = FilePatternMatcher(*copy_patterns)
280
280
 
281
281
  def ignore_with_include(source: Path) -> bool:
282
- relative_source = source.relative_to(context_dir)
283
- if not include_fn(relative_source) or ignore_fn(relative_source):
282
+ if source.is_absolute():
283
+ source = source.relative_to(context_dir)
284
+ if not include_fn(source) or ignore_fn(source):
284
285
  return True
285
286
 
286
287
  return False
modal/mount.py CHANGED
@@ -153,9 +153,9 @@ class _MountDir(_MountEntry):
153
153
 
154
154
  for local_filename in gen:
155
155
  local_path = Path(local_filename)
156
- if not self.ignore(local_path):
157
- local_relpath = local_path.expanduser().absolute().relative_to(local_dir)
158
- mount_path = self.remote_path / local_relpath.as_posix()
156
+ rel_local_path = local_path.relative_to(local_dir)
157
+ if not self.ignore(rel_local_path):
158
+ mount_path = self.remote_path / rel_local_path.as_posix()
159
159
  yield local_path.resolve(), mount_path
160
160
 
161
161
  def watch_entry(self):
@@ -339,8 +339,8 @@ class _Mount(_Object, type_prefix="mo"):
339
339
  return _Mount._new()._extend(
340
340
  _MountDir(
341
341
  local_dir=local_path,
342
- ignore=ignore,
343
342
  remote_path=remote_path,
343
+ ignore=ignore,
344
344
  recursive=True,
345
345
  ),
346
346
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 0.75.7
3
+ Version: 0.76.0
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -3,7 +3,7 @@ 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=7Cec6Q7_ND6Ejlwn0c6Y2OufOmsg6huWqeRTZY6faYM,80527
6
+ modal/_functions.py,sha256=MbH2KMEpzcurMnwUZijf8UStcEiUDEEUHvB2ZbhRYzQ,80892
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=6ve4sI2nRAnjPCuAXdSoUplaXfzC9MqRlF_ZLULwwy0,11472
@@ -22,11 +22,11 @@ modal/app.py,sha256=xojuGZv4LaQwZU5ntj7WbmMjeNuB9Gll8Mzqe2LyiEs,51323
22
22
  modal/app.pyi,sha256=zNwR1_2LpmQc9AhemuAeVdk90XNYDw9keOkXAwAATeA,28732
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=qw-zVt9oNSmGtZ4Crjb5Y3-RYABJZ5v0h9pXvvwpQvs,8383
25
+ modal/client.pyi,sha256=F8vKCSiXZoUO5CYO342bpOzML_gF9IYqXU8GhMyGKLM,8383
26
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
27
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
28
- modal/cls.py,sha256=aHoMEWMZUN7bOezs3tRPxzS1FP3gTxZBORVjbPmtxyg,35338
29
- modal/cls.pyi,sha256=klQkXHXhl5gTjRo_XDV6PGecnJeFOudSMXid_kanumI,12090
28
+ modal/cls.py,sha256=LZMQdFZ06LpbLDbsCJknniU-393Jb44E1lqveLVM8F8,38365
29
+ modal/cls.pyi,sha256=BmFCoiFS4EQjkx36iybAFNpxu6xaq24lyJpQuCsB-ko,12990
30
30
  modal/config.py,sha256=OOMEJ5LHNFbHRW5wUpuhl0TH6EPW8D1XV9I3OJXrZrk,12668
31
31
  modal/container_process.py,sha256=vvyK3DVPUMsuqvkKdUiQ49cDLF9JawGrxpglLk5vfgI,6208
32
32
  modal/container_process.pyi,sha256=cR4aRHTbcVvmxGCc1_k2Ey8JllJIAQYq9PBKx0_1TuI,2916
@@ -37,15 +37,15 @@ modal/environments.pyi,sha256=4HbI0kywveaUVI7HqDtZ4HphCTGXYi_wie2hz87up5A,3425
37
37
  modal/exception.py,sha256=4JyO-SACaLNDe2QC48EjsK8GMkZ8AgEurZ8j1YdRu8E,5263
38
38
  modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
39
39
  modal/file_io.pyi,sha256=oB7x-rKq7bmm8cA7Z7W9C9yeko7KK9m9i5GidFnkGK4,9569
40
- modal/file_pattern_matcher.py,sha256=trosX-Bp7dOubudN1bLLhRAoidWy1TcoaR4Pv8CedWw,6497
40
+ modal/file_pattern_matcher.py,sha256=wov-otB5M1oTdrYDtR2_VgacYin2srdtAP4McA1Cqzw,6516
41
41
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
42
42
  modal/functions.pyi,sha256=xc6igwNS77kYkyuVpWOlMPkanxriesIaKFTYlvmuXp0,16993
43
43
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
44
- modal/image.py,sha256=ZCghS6l1O7pezXcdMHk6RoJpW3qWszfWGJTW38lNXaU,92797
44
+ modal/image.py,sha256=lg3XxIWNYV8je88oEPbihzSEq_9gumc0NLbzZLAhm74,92807
45
45
  modal/image.pyi,sha256=MDq7tNJevElK78VxFYrZRe_00kz9gPdg98MN5c6fFoE,25644
46
46
  modal/io_streams.py,sha256=YDZVQSDv05DeXg5TwcucC9Rj5hQBx2GXdluan9rIUpw,15467
47
47
  modal/io_streams.pyi,sha256=1UK6kWLREASQfq-wL9wSp5iqjLU0egRZPDn4LXs1PZY,5136
48
- modal/mount.py,sha256=_YoJ1TYgttZYGCS-698e8XpExt-mYr994-cMBSOU6EE,32696
48
+ modal/mount.py,sha256=lGxbu6tTEA8EdePQWYs2uu0Z3f3H_PjiXwDXOmStwrM,32674
49
49
  modal/mount.pyi,sha256=PHs-N9LGSDfYWw70UrhvGZW_6uWwyx-1GAieROzCNNs,12583
50
50
  modal/network_file_system.py,sha256=9_4EFTM1tKSTdwk0f4beSlWCiat6gC6ZjbsOWje07TM,14779
51
51
  modal/network_file_system.pyi,sha256=58DiUqHGlARmI3cz-Yo7IFObKKFIiGh5UIU5JxGNFfc,8333
@@ -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-0.75.7.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
149
+ modal-0.76.0.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,11 +169,11 @@ 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=PenIvZdwt-HVdbetAyxuPoyZTtzx2moKZoJLK8iZ804,470
172
+ modal_version/__init__.py,sha256=u-X2s_2GMkprLryPgSYm4nwqxeDjYDm_2mJ3SGySns4,470
173
173
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
174
- modal_version/_version_generated.py,sha256=6BcCuYUedZHHqWpjNiOKZgZruTK1fa-CqRO57DLf9yw,148
175
- modal-0.75.7.dist-info/METADATA,sha256=YyRzyMBDSH3pwd0JXc_xUh6CfzWSlOA7UOdYa7prIAQ,2450
176
- modal-0.75.7.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
177
- modal-0.75.7.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
- modal-0.75.7.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
- modal-0.75.7.dist-info/RECORD,,
174
+ modal_version/_version_generated.py,sha256=luY94U3OY0dEDjZ9HnZ2LEvyaSY6Jm8G6CvyRe3GMcU,148
175
+ modal-0.76.0.dist-info/METADATA,sha256=pBNdZGQNS6qMJVS1cRxzqyH0_PAHwyEUmAVF_9kQCoY,2450
176
+ modal-0.76.0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
177
+ modal-0.76.0.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
+ modal-0.76.0.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
+ modal-0.76.0.dist-info/RECORD,,
modal_version/__init__.py CHANGED
@@ -7,7 +7,7 @@ from ._version_generated import build_number
7
7
  major_number = 0
8
8
 
9
9
  # Bump this manually on breaking changes, then reset the number in _version_generated.py
10
- minor_number = 75
10
+ minor_number = 76
11
11
 
12
12
  # Right now, automatically increment the patch number in CI
13
13
  __version__ = f"{major_number}.{minor_number}.{max(build_number, 0)}"
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
 
3
3
  # Note: Reset this value to -1 whenever you make a minor `0.X` release of the client.
4
- build_number = 7 # git: ebed27f
4
+ build_number = 0 # git: 1b997c3
File without changes