modal 0.73.128__py3-none-any.whl → 0.73.131__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.
@@ -16,12 +16,10 @@ import modal_proto
16
16
  from modal_proto import api_pb2
17
17
 
18
18
  from .._serialization import (
19
- PROTO_TYPE_INFO,
20
- PYTHON_TO_PROTO_TYPE,
21
19
  deserialize,
22
20
  deserialize_data_format,
23
- get_proto_parameter_type,
24
21
  serialize,
22
+ signature_to_parameter_specs,
25
23
  )
26
24
  from .._traceback import append_modal_tb
27
25
  from ..config import config, logger
@@ -106,24 +104,6 @@ def get_function_type(is_generator: Optional[bool]) -> "api_pb2.Function.Functio
106
104
  return api_pb2.Function.FUNCTION_TYPE_GENERATOR if is_generator else api_pb2.Function.FUNCTION_TYPE_FUNCTION
107
105
 
108
106
 
109
- def signature_to_protobuf_schema(signature: inspect.Signature) -> list[api_pb2.ClassParameterSpec]:
110
- modal_parameters: list[api_pb2.ClassParameterSpec] = []
111
- for param in signature.parameters.values():
112
- has_default = param.default is not param.empty
113
- class_param_spec = api_pb2.ClassParameterSpec(name=param.name, has_default=has_default)
114
- if param.annotation not in PYTHON_TO_PROTO_TYPE:
115
- class_param_spec.type = api_pb2.PARAM_TYPE_UNKNOWN
116
- else:
117
- proto_type = PYTHON_TO_PROTO_TYPE[param.annotation]
118
- class_param_spec.type = proto_type
119
- proto_type_info = PROTO_TYPE_INFO[proto_type]
120
- if has_default and proto_type is not api_pb2.PARAM_TYPE_UNKNOWN:
121
- setattr(class_param_spec, proto_type_info.default_field, param.default)
122
-
123
- modal_parameters.append(class_param_spec)
124
- return modal_parameters
125
-
126
-
127
107
  class FunctionInfo:
128
108
  """Utility that determines serialization/deserialization mechanisms for functions
129
109
 
@@ -310,15 +290,12 @@ class FunctionInfo:
310
290
  # annotation parameters trigger strictly typed parametrization
311
291
  # which enables web endpoint for parametrized classes
312
292
  signature = _get_class_constructor_signature(self.user_cls)
313
- # validate that the schema has no unspecified fields/unsupported class parameter types
314
- for param in signature.parameters.values():
315
- get_proto_parameter_type(param.annotation)
316
-
317
- protobuf_schema = signature_to_protobuf_schema(signature)
293
+ # at this point, the types in the signature should already have been validated (see Cls.from_local())
294
+ parameter_specs = signature_to_parameter_specs(signature)
318
295
 
319
296
  return api_pb2.ClassParameterInfo(
320
297
  format=api_pb2.ClassParameterInfo.PARAM_SERIALIZATION_FORMAT_PROTO,
321
- schema=protobuf_schema,
298
+ schema=parameter_specs,
322
299
  )
323
300
 
324
301
  def get_entrypoint_mount(self) -> dict[str, _Mount]:
modal/app.py CHANGED
@@ -678,12 +678,6 @@ class _App:
678
678
  is_generator = f.is_generator
679
679
  batch_max_size = f.batch_max_size
680
680
  batch_wait_ms = f.batch_wait_ms
681
- if f.max_concurrent_inputs: # Using @modal.concurrent()
682
- max_concurrent_inputs = f.max_concurrent_inputs
683
- target_concurrent_inputs = f.target_concurrent_inputs
684
- else:
685
- max_concurrent_inputs = allow_concurrent_inputs
686
- target_concurrent_inputs = None
687
681
  else:
688
682
  if not is_global_object(f.__qualname__) and not serialized:
689
683
  raise InvalidError(
@@ -715,12 +709,10 @@ class _App:
715
709
  )
716
710
 
717
711
  info = FunctionInfo(f, serialized=serialized, name_override=name)
718
- raw_f = f
719
712
  webhook_config = None
720
713
  batch_max_size = None
721
714
  batch_wait_ms = None
722
- max_concurrent_inputs = allow_concurrent_inputs
723
- target_concurrent_inputs = None
715
+ raw_f = f
724
716
 
725
717
  cluster_size = None # Experimental: Clustered functions
726
718
  i6pn_enabled = i6pn
@@ -761,8 +753,7 @@ class _App:
761
753
  max_containers=max_containers,
762
754
  buffer_containers=buffer_containers,
763
755
  scaledown_window=scaledown_window,
764
- max_concurrent_inputs=max_concurrent_inputs,
765
- target_concurrent_inputs=target_concurrent_inputs,
756
+ allow_concurrent_inputs=allow_concurrent_inputs,
766
757
  batch_max_size=batch_max_size,
767
758
  batch_wait_ms=batch_wait_ms,
768
759
  timeout=timeout,
@@ -841,7 +832,7 @@ class _App:
841
832
  concurrency_limit: Optional[int] = None, # Replaced with `max_containers`
842
833
  container_idle_timeout: Optional[int] = None, # Replaced with `scaledown_window`
843
834
  _experimental_buffer_containers: Optional[int] = None, # Now stable API with `buffer_containers`
844
- ) -> Callable[[Union[CLS_T, _PartialFunction]], CLS_T]:
835
+ ) -> Callable[[CLS_T], CLS_T]:
845
836
  """
846
837
  Decorator to register a new Modal [Cls](/docs/reference/modal.Cls) with this App.
847
838
  """
@@ -854,21 +845,8 @@ class _App:
854
845
  raise InvalidError("`region` and `_experimental_scheduler_placement` cannot be used together")
855
846
  scheduler_placement = SchedulerPlacement(region=region)
856
847
 
857
- def wrapper(wrapped_cls: Union[CLS_T, _PartialFunction]) -> CLS_T:
848
+ def wrapper(user_cls: CLS_T) -> CLS_T:
858
849
  # Check if the decorated object is a class
859
- if isinstance(wrapped_cls, _PartialFunction):
860
- wrapped_cls.wrapped = True
861
- user_cls = wrapped_cls.raw_f
862
- if wrapped_cls.max_concurrent_inputs: # Using @modal.concurrent()
863
- max_concurrent_inputs = wrapped_cls.max_concurrent_inputs
864
- target_concurrent_inputs = wrapped_cls.target_concurrent_inputs
865
- else:
866
- max_concurrent_inputs = allow_concurrent_inputs
867
- target_concurrent_inputs = None
868
- else:
869
- user_cls = wrapped_cls
870
- max_concurrent_inputs = allow_concurrent_inputs
871
- target_concurrent_inputs = None
872
850
  if not inspect.isclass(user_cls):
873
851
  raise TypeError("The @app.cls decorator must be used on a class.")
874
852
 
@@ -893,12 +871,6 @@ class _App:
893
871
  ):
894
872
  raise InvalidError("A class must have `enable_memory_snapshot=True` to use `snap=True` on its methods.")
895
873
 
896
- for method in _find_partial_methods_for_user_cls(user_cls, _PartialFunctionFlags.FUNCTION).values():
897
- if method.max_concurrent_inputs:
898
- raise InvalidError(
899
- "The `@modal.concurrent` decorator cannot be used on methods; decorate the class instead."
900
- )
901
-
902
874
  info = FunctionInfo(None, serialized=serialized, user_cls=user_cls)
903
875
 
904
876
  cls_func = _Function.from_local(
@@ -920,8 +892,7 @@ class _App:
920
892
  scaledown_window=scaledown_window,
921
893
  proxy=proxy,
922
894
  retries=retries,
923
- max_concurrent_inputs=max_concurrent_inputs,
924
- target_concurrent_inputs=target_concurrent_inputs,
895
+ allow_concurrent_inputs=allow_concurrent_inputs,
925
896
  batch_max_size=batch_max_size,
926
897
  batch_wait_ms=batch_wait_ms,
927
898
  timeout=timeout,
modal/app.pyi CHANGED
@@ -1,7 +1,6 @@
1
1
  import collections.abc
2
2
  import modal._functions
3
3
  import modal._object
4
- import modal._partial_function
5
4
  import modal._utils.function_utils
6
5
  import modal.client
7
6
  import modal.cloud_bucket_mount
@@ -248,7 +247,7 @@ class _App:
248
247
  concurrency_limit: typing.Optional[int] = None,
249
248
  container_idle_timeout: typing.Optional[int] = None,
250
249
  _experimental_buffer_containers: typing.Optional[int] = None,
251
- ) -> collections.abc.Callable[[typing.Union[CLS_T, modal._partial_function._PartialFunction]], CLS_T]: ...
250
+ ) -> collections.abc.Callable[[CLS_T], CLS_T]: ...
252
251
  async def spawn_sandbox(
253
252
  self,
254
253
  *entrypoint_args: str,
@@ -488,7 +487,7 @@ class App:
488
487
  concurrency_limit: typing.Optional[int] = None,
489
488
  container_idle_timeout: typing.Optional[int] = None,
490
489
  _experimental_buffer_containers: typing.Optional[int] = None,
491
- ) -> collections.abc.Callable[[typing.Union[CLS_T, modal.partial_function.PartialFunction]], CLS_T]: ...
490
+ ) -> collections.abc.Callable[[CLS_T], CLS_T]: ...
492
491
 
493
492
  class __spawn_sandbox_spec(typing_extensions.Protocol[SUPERSELF]):
494
493
  def __call__(
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 = "0.73.128",
34
+ version: str = "0.73.131",
35
35
  ): ...
36
36
  def is_closed(self) -> bool: ...
37
37
  @property
@@ -93,7 +93,7 @@ class Client:
93
93
  server_url: str,
94
94
  client_type: int,
95
95
  credentials: typing.Optional[tuple[str, str]],
96
- version: str = "0.73.128",
96
+ version: str = "0.73.131",
97
97
  ): ...
98
98
  def is_closed(self) -> bool: ...
99
99
  @property
modal/cls.py CHANGED
@@ -21,8 +21,9 @@ from ._partial_function import (
21
21
  )
22
22
  from ._resolver import Resolver
23
23
  from ._resources import convert_fn_config_to_resources_config
24
- from ._serialization import check_valid_cls_constructor_arg, get_proto_parameter_type
24
+ from ._serialization import check_valid_cls_constructor_arg
25
25
  from ._traceback import print_server_warnings
26
+ from ._type_manager import parameter_serde_registry
26
27
  from ._utils.async_utils import synchronize_api, synchronizer
27
28
  from ._utils.deprecation import deprecation_warning, renamed_parameter, warn_on_renamed_autoscaler_settings
28
29
  from ._utils.grpc_utils import retry_transient_errors
@@ -462,7 +463,10 @@ class _Cls(_Object, type_prefix="cs"):
462
463
 
463
464
  annotated_params = {k: t for k, t in annotations.items() if k in params}
464
465
  for k, t in annotated_params.items():
465
- get_proto_parameter_type(t)
466
+ try:
467
+ parameter_serde_registry.validate_parameter_type(t)
468
+ except TypeError as exc:
469
+ raise InvalidError(f"Class parameter '{k}': {exc}")
466
470
 
467
471
  @staticmethod
468
472
  def from_local(user_cls, app: "modal.app._App", class_service_function: _Function) -> "_Cls":
modal/functions.pyi CHANGED
@@ -82,8 +82,7 @@ class Function(
82
82
  max_containers: typing.Optional[int] = None,
83
83
  buffer_containers: typing.Optional[int] = None,
84
84
  scaledown_window: typing.Optional[int] = None,
85
- max_concurrent_inputs: typing.Optional[int] = None,
86
- target_concurrent_inputs: typing.Optional[int] = None,
85
+ allow_concurrent_inputs: typing.Optional[int] = None,
87
86
  batch_max_size: typing.Optional[int] = None,
88
87
  batch_wait_ms: typing.Optional[int] = None,
89
88
  cloud: typing.Optional[str] = None,
@@ -199,11 +198,11 @@ class Function(
199
198
 
200
199
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
201
200
 
202
- class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
201
+ class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
203
202
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
204
203
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
205
204
 
206
- remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
205
+ remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
207
206
 
208
207
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
209
208
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -218,19 +217,19 @@ class Function(
218
217
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
219
218
  ) -> modal._functions.OriginalReturnType: ...
220
219
 
221
- class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
220
+ class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
222
221
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
223
222
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
224
223
 
225
224
  _experimental_spawn: ___experimental_spawn_spec[
226
- modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
225
+ modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
227
226
  ]
228
227
 
229
- class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
228
+ class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
230
229
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
231
230
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
232
231
 
233
- spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
232
+ spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
234
233
 
235
234
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
236
235
 
modal/partial_function.py CHANGED
@@ -5,7 +5,6 @@ from ._partial_function import (
5
5
  _asgi_app,
6
6
  _batched,
7
7
  _build,
8
- _concurrent,
9
8
  _enter,
10
9
  _exit,
11
10
  _fastapi_endpoint,
@@ -29,4 +28,3 @@ build = synchronize_api(_build, target_module=__name__)
29
28
  enter = synchronize_api(_enter, target_module=__name__)
30
29
  exit = synchronize_api(_exit, target_module=__name__)
31
30
  batched = synchronize_api(_batched, target_module=__name__)
32
- concurrent = synchronize_api(_concurrent, target_module=__name__)
@@ -18,8 +18,6 @@ class PartialFunction(
18
18
  force_build: bool
19
19
  cluster_size: typing.Optional[int]
20
20
  build_timeout: typing.Optional[int]
21
- max_concurrent_inputs: typing.Optional[int]
22
- target_concurrent_inputs: typing.Optional[int]
23
21
 
24
22
  def __init__(
25
23
  self,
@@ -33,8 +31,6 @@ class PartialFunction(
33
31
  cluster_size: typing.Optional[int] = None,
34
32
  force_build: bool = False,
35
33
  build_timeout: typing.Optional[int] = None,
36
- max_concurrent_inputs: typing.Optional[int] = None,
37
- target_concurrent_inputs: typing.Optional[int] = None,
38
34
  ): ...
39
35
  def _get_raw_f(self) -> collections.abc.Callable[modal._partial_function.P, modal._partial_function.ReturnType]: ...
40
36
  def _is_web_endpoint(self) -> bool: ...
@@ -122,8 +118,3 @@ def exit(
122
118
  def batched(
123
119
  _warn_parentheses_missing=None, *, max_batch_size: int, wait_ms: int
124
120
  ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], PartialFunction]: ...
125
- def concurrent(
126
- _warn_parentheses_missing=None, *, max_inputs: int, target_inputs: typing.Optional[int] = None
127
- ) -> collections.abc.Callable[
128
- [typing.Union[collections.abc.Callable[..., typing.Any], PartialFunction]], PartialFunction
129
- ]: ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: modal
3
- Version: 0.73.128
3
+ Version: 0.73.131
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -1,31 +1,32 @@
1
- modal/__init__.py,sha256=7wz1AT_bpWJJEzXsAo3QMb7i87y7UGXwfneb0bGDhRg,2502
1
+ modal/__init__.py,sha256=KcoVQVCfwuHmIJ74OxQPn66MHfiJcWi8V5srBW12jTA,2464
2
2
  modal/__main__.py,sha256=CgIjP8m1xJjjd4AXc-delmR6LdBCZclw2A_V38CFIio,2870
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
5
5
  modal/_container_entrypoint.py,sha256=arhkIoF8nQNfa4iwYGSoqN3QMDg5M38QNAODXC8TlKc,29301
6
- modal/_functions.py,sha256=L-8wuokczWuD3xRqZKT4NkgO4tqKV3Cze_9KITgHdmc,73441
6
+ modal/_functions.py,sha256=CNglAqO1gHLCAZiH1L6wD-PflzdPgtezNMK_jDwkIyE,73358
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=JBIECWdfpRKCaCxVWZbC3Q1kF5Whk_EKvY9f4Y6AFyg,11446
10
10
  modal/_output.py,sha256=Z0nngPh2mKHMQc4MQ92YjVPc3ewOLa3I4dFBlL9nvQY,25656
11
- modal/_partial_function.py,sha256=Qr4smy6ndZUDwEHpe_T9KJZ-z8DpoH_Ipj9PqAIifx8,33044
11
+ modal/_partial_function.py,sha256=ytUhfUEVPMccVD3wMekr2JRo5R0YylaE0LgPsSA05aQ,30508
12
12
  modal/_proxy_tunnel.py,sha256=gnKyCfmVB7x2d1A6c-JDysNIP3kEFxmXzhcXhPrzPn0,1906
13
13
  modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
14
- modal/_resolver.py,sha256=RtoXoYzSllPlFu0D1vel_FWiEmDO7RyToiC2bxeN8ZY,6917
14
+ modal/_resolver.py,sha256=95emhRvKHQF_f5jQ2PVvis2lbtuWUuXI591wua71fR4,7029
15
15
  modal/_resources.py,sha256=5qmcirXUI8dSH926nwkUaeX9H25mqYu9mXD_KuT79-o,1733
16
- modal/_serialization.py,sha256=DUM-RljUSoKYezLWlckn8GH46A3IWkx9QIUukWYhCxU,22021
16
+ modal/_serialization.py,sha256=SQMKtmjvjOLM6ErxTboeJiW970LySqjxDWk0humBR1U,21939
17
17
  modal/_traceback.py,sha256=IZQzB3fVlUfMHOSyKUgw0H6qv4yHnpyq-XVCNZKfUdA,5023
18
18
  modal/_tunnel.py,sha256=zTBxBiuH1O22tS1OliAJdIsSmaZS8PlnifS_6S5z-mk,6320
19
19
  modal/_tunnel.pyi,sha256=JmmDYAy9F1FpgJ_hWx0xkom2nTOFQjn4mTPYlU3PFo4,1245
20
+ modal/_type_manager.py,sha256=SvDvX9JK1jLp8TA_psLd-hNYPALlG9KtSOmlbHqdtQE,8284
20
21
  modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
21
- modal/app.py,sha256=NKH7Cw1M6eyyrMXFbhWfdo3uRd28-8kv0Pcw56kPiPU,47312
22
- modal/app.pyi,sha256=pUEqciyGZ446sc_QoG8XcQ_oc6oU-U4dqjkxjhgOX98,26968
22
+ modal/app.py,sha256=ojhuLZuNZAQ1OsbDH0k6G4pm1W7bOIvZfXbaKlvQ-Ao,45622
23
+ modal/app.pyi,sha256=tZFbcsu20SuvfB2puxCyuXLFNJ9bQulzag55rVpgZmc,26827
23
24
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
25
  modal/client.py,sha256=j9D3hNis1lfhnz9lVFGgJgowbH3PaGUzNKgHPWYG778,15372
25
- modal/client.pyi,sha256=nZCWs5u7jbU0Bnr2FXjfkhvNtNbJ7gKRdbe6gH2tT3g,7661
26
+ modal/client.pyi,sha256=ksmfGdK8S4mWOdzp-UKMBVwkjKWx9uYfrsUDg9W9YUk,7661
26
27
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
28
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
28
- modal/cls.py,sha256=PWXqCcBVOuYnp0Q5GY-bEldVyv_AnelApMyPiESYwrU,31410
29
+ modal/cls.py,sha256=PJimWA9q_sbQJNLbYy7fzjZGBm_hdfXuuZ7O_pKLXdk,31586
29
30
  modal/cls.pyi,sha256=ZJUwtRaQBGlM6tphvnv49FHBVDSgttMdD_LnYyRSKJM,10302
30
31
  modal/config.py,sha256=Zx7YsllgIJzMRKeIkaGSLLtMFV4kTUvGxpptnmqlP1U,11623
31
32
  modal/container_process.py,sha256=WTqLn01dJPVkPpwR_0w_JH96ceN5mV4TGtiu1ZR2RRA,6108
@@ -41,7 +42,7 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
41
42
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
42
43
  modal/file_pattern_matcher.py,sha256=trosX-Bp7dOubudN1bLLhRAoidWy1TcoaR4Pv8CedWw,6497
43
44
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
44
- modal/functions.pyi,sha256=PqApQjvICj11NIMEVCmaUIUyJUfEIuY_KkEzCZ4t6iI,14438
45
+ modal/functions.pyi,sha256=D-PDJfSbwqMDXdq7Bxu2ErZRENo-tRgu_zPoB-jl0OU,14377
45
46
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
46
47
  modal/image.py,sha256=6hDizLZvRIjRy2cMWGT06Kj1uqW_L5B9GR6x3AKr4v4,92341
47
48
  modal/image.pyi,sha256=DQ4DLOCPr6_yV7z4LS0bTY0rOyvQP9-dQOrzaW7pPG8,25260
@@ -56,8 +57,8 @@ modal/object.pyi,sha256=kyJkRQcVv3ct7zSAxvvXcuhBVeH914v80uSlqeS7cA4,5632
56
57
  modal/output.py,sha256=q4T9uHduunj4NwY-YSwkHGgjZlCXMuJbfQ5UFaAGRAc,1968
57
58
  modal/parallel_map.py,sha256=AB4YH4ZBGmCOe-X_1kB3hm-kNoRnOxCMzpkTUim4tT8,33586
58
59
  modal/parallel_map.pyi,sha256=-D_z-K1GOpQcMSUMVHRVLr2rgEA5CXlX6dU5P6msa58,5671
59
- modal/partial_function.py,sha256=y0h-EvlPnfvZr7nlJLOFk7NB-K-ZO41XJnsGtQTesAI,1200
60
- modal/partial_function.pyi,sha256=-xWrvFMhLT6ulx9B82u1g8kL69vt3nYAvp8pV0d__uw,5407
60
+ modal/partial_function.py,sha256=uu8zvIV0Big0jiTlC4-VPL16dOScNB5jhfPeqxvvCrI,1117
61
+ modal/partial_function.pyi,sha256=-MAK61qJRi6Wjym-Measz5_9moJurYrJfdi7uSQZa5M,4936
61
62
  modal/proxy.py,sha256=NrOevrWxG3G7-zlyRzG6BcIvop7AWLeyahZxitbBaOk,1418
62
63
  modal/proxy.pyi,sha256=1OEKIVUyC-xb7fHMzngakQso0nTsK60TVhXtlcMj6Wk,390
63
64
  modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -98,7 +99,7 @@ modal/_utils/blob_utils.py,sha256=RB1G6T7eC1Poe-O45qYLaxwCr2jkM-Q6Nexk1J3wk_w,14
98
99
  modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
99
100
  modal/_utils/deprecation.py,sha256=EXP1beU4pmEqEzWMLw6E3kUfNfpmNA_VOp6i0EHi93g,4856
100
101
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
101
- modal/_utils/function_utils.py,sha256=oWpeCvDQgsbjz3jUZPJ5LVgZO63OqY1ut3BNh8HJ-JM,27732
102
+ modal/_utils/function_utils.py,sha256=t5uVhvmQKFmLmJko_Vv8g99-PGqm1a4QQWIQNt44jKg,26688
102
103
  modal/_utils/git_utils.py,sha256=qtUU6JAttF55ZxYq51y55OR58B0tDPZsZWK5dJe6W5g,3182
103
104
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
104
105
  modal/_utils/grpc_utils.py,sha256=wmMydVKN9YbugTwUXuOuzxbpzYvxkTDaFRxlBtIDE_0,8526
@@ -154,10 +155,10 @@ modal_docs/mdmd/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,2
154
155
  modal_docs/mdmd/mdmd.py,sha256=Irx49MCCTlBOP4FBdLR--JrpA3-WhsVeriq0LGgsRic,6232
155
156
  modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
156
157
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
157
- modal_proto/api.proto,sha256=94F7C-OQg0Xj_By2XztAGkQD4zRus5o7gy26viQADFo,87786
158
+ modal_proto/api.proto,sha256=2JGv25RJbX4oTCGRzjED-tQJsGwYkuQMa1ftAh04hLo,88280
158
159
  modal_proto/api_grpc.py,sha256=SJOfs3Y1cOzzF_ZcDj-UNnOWz59sfU8a4JISp4Y_1Kw,109923
159
- modal_proto/api_pb2.py,sha256=UzgHEmSdZwWJxsoho67clTWH8uXlpICe7p_jtaHPRrA,315544
160
- modal_proto/api_pb2.pyi,sha256=WBRQRWufW08Nw8r9qlRZFiBgWsDMI5PN7gNXZKS7D08,426646
160
+ modal_proto/api_pb2.py,sha256=gMhNEVF-siK8NkHBTcdlNhYYAaAdydhVolyaJdnMP-I,316437
161
+ modal_proto/api_pb2.pyi,sha256=5JqfsirPOW4IVqrj8ufcEyEWu7TQAWV5BnNj-T12YKM,428292
161
162
  modal_proto/api_pb2_grpc.py,sha256=0XeCIL2B6UGLBh1MEGPFPz1k8qLWNyp-yj_cJrK3NE8,237541
162
163
  modal_proto/api_pb2_grpc.pyi,sha256=BsnRBinG0KC9Cp70UkdxuzgZA9KLCTl7T5ze0RK-Mmk,55323
163
164
  modal_proto/modal_api_grpc.py,sha256=i9HTreJ5FpBvtz9NwuTC52fZTWZO_M_DWdIYT2lOjs8,14666
@@ -171,10 +172,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
171
172
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
173
  modal_version/__init__.py,sha256=wiJQ53c-OMs0Xf1UeXOxQ7FwlV1VzIjnX6o-pRYZ_Pk,470
173
174
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
174
- modal_version/_version_generated.py,sha256=UV2vFNSRCipcz3159A83mk2Cakl8UFhOaMaL-i9YTPY,150
175
- modal-0.73.128.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
176
- modal-0.73.128.dist-info/METADATA,sha256=5Xr1wyl6HVCsIC2KYo1Kmb93AF0F0Fzfbza3EEGIHro,2453
177
- modal-0.73.128.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
178
- modal-0.73.128.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
179
- modal-0.73.128.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
180
- modal-0.73.128.dist-info/RECORD,,
175
+ modal_version/_version_generated.py,sha256=YNKdjP2iUBwdkG8jk2i7rPime-g-zng71E6FA9DBvlw,150
176
+ modal-0.73.131.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
177
+ modal-0.73.131.dist-info/METADATA,sha256=KbNxcfaUiUQg253uRRCgmk_Ct1j9Hyoo70GCVKxgRek,2453
178
+ modal-0.73.131.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
179
+ modal-0.73.131.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
180
+ modal-0.73.131.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
181
+ modal-0.73.131.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -170,9 +170,12 @@ enum ParameterType {
170
170
  PARAM_TYPE_UNSPECIFIED = 0;
171
171
  PARAM_TYPE_STRING = 1;
172
172
  PARAM_TYPE_INT = 2;
173
- PARAM_TYPE_PICKLE = 3;
173
+ PARAM_TYPE_PICKLE = 3; // currently unused
174
174
  PARAM_TYPE_BYTES = 4;
175
175
  PARAM_TYPE_UNKNOWN = 5; // used in schemas to signify unrecognized or un-annotated types
176
+ PARAM_TYPE_LIST = 6;
177
+ PARAM_TYPE_DICT = 7;
178
+ PARAM_TYPE_NONE = 8;
176
179
  }
177
180
 
178
181
  enum ProgressType {
@@ -697,19 +700,22 @@ message ClassParameterSet {
697
700
  repeated ClassParameterValue parameters = 1;
698
701
  }
699
702
 
700
- message ClassParameterSpec {
703
+ message ClassParameterSpec { // TODO: rename into NamedPayloadType or similar
701
704
  string name = 1;
702
- ParameterType type = 2;
705
+ ParameterType type = 2; // TODO: deprecate - use full_type instead
703
706
  bool has_default = 3;
704
707
  oneof default_oneof {
708
+ // Default *values* are only registered for class parameters
705
709
  string string_default = 4;
706
710
  int64 int_default = 5;
707
711
  bytes pickle_default = 6;
708
712
  bytes bytes_default = 7;
709
713
  }
714
+ GenericPayloadType full_type = 8; // supersedes `type`
710
715
  }
711
716
 
712
- message ClassParameterValue {
717
+
718
+ message ClassParameterValue { // TODO: rename into NamedPayloadValue
713
719
  // NOTE: adding additional *fields* here can invalidate function lookups
714
720
  // since we use the serialized message as the bound function identifier
715
721
  // for parameter-bound classes. Modify with *caution*
@@ -1216,7 +1222,7 @@ message Function {
1216
1222
 
1217
1223
  repeated VolumeMount volume_mounts = 33;
1218
1224
 
1219
- uint32 max_concurrent_inputs = 34;
1225
+ uint32 target_concurrent_inputs = 34;
1220
1226
 
1221
1227
  repeated CustomDomainInfo custom_domain_info = 35;
1222
1228
 
@@ -1266,7 +1272,7 @@ message Function {
1266
1272
  uint64 batch_linger_ms = 61; // Miliseconds to block before a response is needed
1267
1273
  bool i6pn_enabled = 62;
1268
1274
  bool _experimental_concurrent_cancellations = 63;
1269
- uint32 target_concurrent_inputs = 64;
1275
+ uint32 max_concurrent_inputs = 64;
1270
1276
 
1271
1277
  // TODO(irfansharif): Remove, once https://github.com/modal-labs/modal/pull/15645 lands.
1272
1278
  bool _experimental_task_templates_enabled = 65; // forces going through the new gpu-fallbacks integration path, even if no fallback options are specified
@@ -1728,6 +1734,11 @@ message GeneratorDone { // Sent as the output when a generator finishes running
1728
1734
  uint64 items_total = 1;
1729
1735
  }
1730
1736
 
1737
+ message GenericPayloadType {
1738
+ ParameterType base_type = 1;
1739
+ repeated GenericPayloadType sub_types = 2; // sub-type for generic types like lists
1740
+ }
1741
+
1731
1742
  message GenericResult { // Used for both tasks and function outputs
1732
1743
  enum GenericStatus {
1733
1744
  GENERIC_STATUS_UNSPECIFIED = 0;