modal 0.73.150__py3-none-any.whl → 0.73.151__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/_functions.py CHANGED
@@ -27,6 +27,7 @@ from ._resources import convert_fn_config_to_resources_config
27
27
  from ._runtime.execution_context import current_input_id, is_local
28
28
  from ._serialization import (
29
29
  apply_defaults,
30
+ get_callable_schema,
30
31
  serialize,
31
32
  serialize_proto_params,
32
33
  validate_parameter_values,
@@ -415,6 +416,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
415
416
  _method_handle_metadata: Optional[dict[str, "api_pb2.FunctionHandleMetadata"]] = (
416
417
  None # set for 0.67+ class service functions
417
418
  )
419
+ _metadata: Optional[api_pb2.FunctionHandleMetadata] = None
418
420
 
419
421
  @staticmethod
420
422
  def from_local(
@@ -650,10 +652,17 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
650
652
  for method_name, partial_function in interface_methods.items():
651
653
  function_type = get_function_type(partial_function.params.is_generator)
652
654
  function_name = f"{info.user_cls.__name__}.{method_name}"
655
+ method_schema = get_callable_schema(
656
+ partial_function._get_raw_f(),
657
+ is_web_endpoint=partial_function._is_web_endpoint(),
658
+ ignore_first_argument=True,
659
+ )
660
+
653
661
  method_definition = api_pb2.MethodDefinition(
654
662
  webhook_config=partial_function.params.webhook_config,
655
663
  function_type=function_type,
656
664
  function_name=function_name,
665
+ function_schema=method_schema,
657
666
  )
658
667
  method_definitions[method_name] = method_definition
659
668
 
@@ -695,6 +704,9 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
695
704
  function_name=info.function_name,
696
705
  function_type=function_type,
697
706
  existing_function_id=existing_object_id or "",
707
+ function_schema=get_callable_schema(info.raw_f, is_web_endpoint=bool(webhook_config))
708
+ if info.raw_f
709
+ else None,
698
710
  )
699
711
  if method_definitions:
700
712
  for method_name, method_definition in method_definitions.items():
@@ -763,8 +775,9 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
763
775
  object_dependencies.append(api_pb2.ObjectDependency(object_id=dep.object_id))
764
776
 
765
777
  function_data: Optional[api_pb2.FunctionData] = None
766
- function_definition: Optional[api_pb2.Function] = None
767
-
778
+ function_schema = (
779
+ get_callable_schema(info.raw_f, is_web_endpoint=bool(webhook_config)) if info.raw_f else None
780
+ )
768
781
  # Create function remotely
769
782
  function_definition = api_pb2.Function(
770
783
  module_name=info.module_name or "",
@@ -823,6 +836,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
823
836
  _experimental_buffer_containers=buffer_containers or 0,
824
837
  task_idle_timeout_secs=scaledown_window or 0,
825
838
  # ---
839
+ function_schema=function_schema,
826
840
  )
827
841
 
828
842
  if isinstance(gpu, list):
@@ -855,6 +869,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
855
869
  _experimental_proxy_ip=function_definition._experimental_proxy_ip,
856
870
  snapshot_debug=function_definition.snapshot_debug,
857
871
  runtime_perf_record=function_definition.runtime_perf_record,
872
+ function_schema=function_schema,
858
873
  )
859
874
 
860
875
  ranked_functions = []
@@ -1225,12 +1240,15 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1225
1240
  self._function_name = None
1226
1241
  self._info = None
1227
1242
  self._serve_mounts = frozenset()
1243
+ self._metadata = None
1228
1244
 
1229
1245
  def _hydrate_metadata(self, metadata: Optional[Message]):
1230
1246
  # Overridden concrete implementation of base class method
1231
1247
  assert metadata and isinstance(metadata, api_pb2.FunctionHandleMetadata), (
1232
1248
  f"{type(metadata)} is not FunctionHandleMetadata"
1233
1249
  )
1250
+ self._metadata = metadata
1251
+ # TODO: replace usage of all below with direct ._metadata access
1234
1252
  self._is_generator = metadata.function_type == api_pb2.Function.FUNCTION_TYPE_GENERATOR
1235
1253
  self._web_url = metadata.web_url
1236
1254
  self._function_name = metadata.function_name
@@ -1252,6 +1270,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1252
1270
  class_parameter_info=self._class_parameter_info,
1253
1271
  definition_id=self._definition_id,
1254
1272
  method_handle_metadata=self._method_handle_metadata,
1273
+ function_schema=self._metadata.function_schema if self._metadata else None,
1255
1274
  )
1256
1275
 
1257
1276
  def _check_no_web_url(self, fn_name: str):
@@ -1535,6 +1554,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1535
1554
  )
1536
1555
  return FunctionStats(backlog=resp.backlog, num_total_runners=resp.num_total_tasks)
1537
1556
 
1557
+ @live_method
1558
+ async def _get_schema(self) -> api_pb2.FunctionSchema:
1559
+ """Returns recorded schema for function, internal use only for now"""
1560
+ assert self._metadata
1561
+ return self._metadata.function_schema
1562
+
1538
1563
  # A bit hacky - but the map-style functions need to not be synchronicity-wrapped
1539
1564
  # in order to not execute their input iterators on the synchronicity event loop.
1540
1565
  # We still need to wrap them using MethodWithAio to maintain a synchronicity-like
modal/_serialization.py CHANGED
@@ -12,7 +12,7 @@ from modal_proto import api_pb2
12
12
  from ._object import _Object
13
13
  from ._type_manager import parameter_serde_registry, schema_registry
14
14
  from ._vendor import cloudpickle
15
- from .config import logger
15
+ from .config import config, logger
16
16
  from .exception import DeserializationError, ExecutionError, InvalidError
17
17
  from .object import Object
18
18
 
@@ -526,3 +526,28 @@ def signature_to_parameter_specs(signature: inspect.Signature) -> list[api_pb2.C
526
526
  field_spec = _signature_parameter_to_spec(param, include_legacy_parameter_fields=True)
527
527
  modal_parameters.append(field_spec)
528
528
  return modal_parameters
529
+
530
+
531
+ def get_callable_schema(
532
+ callable: typing.Callable, *, is_web_endpoint: bool, ignore_first_argument: bool = False
533
+ ) -> typing.Optional[api_pb2.FunctionSchema]:
534
+ # ignore_first_argument can be used in case of unbound methods where we want to ignore the first (self) argument
535
+ if is_web_endpoint or not config.get("function_schemas"):
536
+ # we don't support schemas on web endpoints for now
537
+ return None
538
+
539
+ sig = inspect.signature(callable)
540
+ # TODO: treat no return value annotation as None return?
541
+ return_type_proto = schema_registry.get_proto_generic_type(sig.return_annotation)
542
+ arguments = []
543
+ for i, p in enumerate(sig.parameters.values()):
544
+ if i == 0 and ignore_first_argument:
545
+ continue
546
+
547
+ arguments.append(_signature_parameter_to_spec(p))
548
+
549
+ return api_pb2.FunctionSchema(
550
+ schema_type=api_pb2.FunctionSchema.FUNCTION_SCHEMA_V1,
551
+ arguments=arguments,
552
+ return_type=return_type_proto,
553
+ )
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.150",
34
+ version: str = "0.73.151",
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.150",
96
+ version: str = "0.73.151",
97
97
  ): ...
98
98
  def is_closed(self) -> bool: ...
99
99
  @property
modal/cls.py CHANGED
@@ -719,6 +719,28 @@ class _Cls(_Object, type_prefix="cs"):
719
719
  Cls = synchronize_api(_Cls)
720
720
 
721
721
 
722
+ @synchronize_api
723
+ async def _get_constructor_args(cls: _Cls) -> typing.Sequence[api_pb2.ClassParameterSpec]:
724
+ # for internal use only - defined separately to not clutter Cls namespace
725
+ await cls.hydrate()
726
+ service_function = cls._get_class_service_function()
727
+ metadata = service_function._metadata
728
+ assert metadata
729
+ if metadata.class_parameter_info.format != metadata.class_parameter_info.PARAM_SERIALIZATION_FORMAT_PROTO:
730
+ raise InvalidError("Can only get constructor args for strictly parameterized classes")
731
+ return metadata.class_parameter_info.schema
732
+
733
+
734
+ @synchronize_api
735
+ async def _get_method_schemas(cls: _Cls) -> dict[str, api_pb2.FunctionSchema]:
736
+ # for internal use only - defined separately to not clutter Cls namespace
737
+ await cls.hydrate()
738
+ assert cls._method_metadata
739
+ return {
740
+ method_name: method_metadata.function_schema for method_name, method_metadata in cls._method_metadata.items()
741
+ }
742
+
743
+
722
744
  class _NO_DEFAULT:
723
745
  def __repr__(self):
724
746
  return "modal.cls._NO_DEFAULT()"
modal/cls.pyi CHANGED
@@ -244,6 +244,18 @@ class Cls(modal.object.Object):
244
244
  def __getattr__(self, k): ...
245
245
  def _is_local(self) -> bool: ...
246
246
 
247
+ class ___get_constructor_args_spec(typing_extensions.Protocol):
248
+ def __call__(self, cls: Cls) -> typing.Sequence[modal_proto.api_pb2.ClassParameterSpec]: ...
249
+ async def aio(self, cls: Cls) -> typing.Sequence[modal_proto.api_pb2.ClassParameterSpec]: ...
250
+
251
+ _get_constructor_args: ___get_constructor_args_spec
252
+
253
+ class ___get_method_schemas_spec(typing_extensions.Protocol):
254
+ def __call__(self, cls: Cls) -> dict[str, modal_proto.api_pb2.FunctionSchema]: ...
255
+ async def aio(self, cls: Cls) -> dict[str, modal_proto.api_pb2.FunctionSchema]: ...
256
+
257
+ _get_method_schemas: ___get_method_schemas_spec
258
+
247
259
  class _NO_DEFAULT:
248
260
  def __repr__(self): ...
249
261
 
modal/config.py CHANGED
@@ -231,6 +231,7 @@ _SETTINGS = {
231
231
  "strict_parameters": _Setting(False, transform=_to_boolean), # For internal/experimental use
232
232
  "snapshot_debug": _Setting(False, transform=_to_boolean),
233
233
  "cuda_checkpoint_path": _Setting("/__modal/.bin/cuda-checkpoint"), # Used for snapshotting GPU memory.
234
+ "function_schemas": _Setting(False, transform=_to_boolean),
234
235
  }
235
236
 
236
237
 
modal/functions.pyi CHANGED
@@ -52,6 +52,7 @@ class Function(
52
52
  _use_method_name: str
53
53
  _class_parameter_info: typing.Optional[modal_proto.api_pb2.ClassParameterInfo]
54
54
  _method_handle_metadata: typing.Optional[dict[str, modal_proto.api_pb2.FunctionHandleMetadata]]
55
+ _metadata: typing.Optional[modal_proto.api_pb2.FunctionHandleMetadata]
55
56
 
56
57
  def __init__(self, *args, **kwargs): ...
57
58
  @staticmethod
@@ -199,11 +200,11 @@ class Function(
199
200
 
200
201
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
201
202
 
202
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
203
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
203
204
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
204
205
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
205
206
 
206
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
207
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
207
208
 
208
209
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
209
210
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -218,19 +219,19 @@ class Function(
218
219
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
219
220
  ) -> modal._functions.OriginalReturnType: ...
220
221
 
221
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
222
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
222
223
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
223
224
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
224
225
 
225
226
  _experimental_spawn: ___experimental_spawn_spec[
226
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
227
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
227
228
  ]
228
229
 
229
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
230
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
230
231
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
231
232
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
232
233
 
233
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
234
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
234
235
 
235
236
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
236
237
 
@@ -240,6 +241,12 @@ class Function(
240
241
 
241
242
  get_current_stats: __get_current_stats_spec[typing_extensions.Self]
242
243
 
244
+ class ___get_schema_spec(typing_extensions.Protocol[SUPERSELF]):
245
+ def __call__(self) -> modal_proto.api_pb2.FunctionSchema: ...
246
+ async def aio(self) -> modal_proto.api_pb2.FunctionSchema: ...
247
+
248
+ _get_schema: ___get_schema_spec[typing_extensions.Self]
249
+
243
250
  class __map_spec(typing_extensions.Protocol[SUPERSELF]):
244
251
  def __call__(
245
252
  self, *input_iterators, kwargs={}, order_outputs: bool = True, return_exceptions: bool = False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: modal
3
- Version: 0.73.150
3
+ Version: 0.73.151
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=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=XyqJPvzX0YMqviIIz-9bsD6HMrPsboU4A1yfgTloTSA,29302
6
- modal/_functions.py,sha256=nUyiCOYcuY_jXJhY5-haHFIUQleCmjh8z6GgXgo5MRY,73556
6
+ modal/_functions.py,sha256=QKH7L7CHS_DN21bkayeQm-XkYFBs92El26RgKNTwqGA,74760
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
@@ -13,7 +13,7 @@ modal/_proxy_tunnel.py,sha256=gnKyCfmVB7x2d1A6c-JDysNIP3kEFxmXzhcXhPrzPn0,1906
13
13
  modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
14
14
  modal/_resolver.py,sha256=RtoXoYzSllPlFu0D1vel_FWiEmDO7RyToiC2bxeN8ZY,6917
15
15
  modal/_resources.py,sha256=5qmcirXUI8dSH926nwkUaeX9H25mqYu9mXD_KuT79-o,1733
16
- modal/_serialization.py,sha256=SQMKtmjvjOLM6ErxTboeJiW970LySqjxDWk0humBR1U,21939
16
+ modal/_serialization.py,sha256=kkLmQ6jnPlbLT3FfuyigocHKG7H1HDJ0i24IxYFbgs8,22927
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
@@ -23,12 +23,12 @@ modal/app.py,sha256=w00bV9cjABAsS2ExE7zb1jY6Q_snXYmdKa3xRFg8iXA,47428
23
23
  modal/app.pyi,sha256=pUEqciyGZ446sc_QoG8XcQ_oc6oU-U4dqjkxjhgOX98,26968
24
24
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
25
25
  modal/client.py,sha256=j9D3hNis1lfhnz9lVFGgJgowbH3PaGUzNKgHPWYG778,15372
26
- modal/client.pyi,sha256=7uZv9uWQf4FIvAK5rTuUNBrYYa2l_S-nGgvxH6ttlVI,7661
26
+ modal/client.pyi,sha256=TXB2eB0HqifVWkvHpWRDccAH40BN4qUq6ozXtYN9uSw,7661
27
27
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
28
28
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
29
- modal/cls.py,sha256=6MZYzhOcsCG7uWKk_zv_Q7fDcn5dkmK0M4QVRrpfF3Q,31769
30
- modal/cls.pyi,sha256=ZJUwtRaQBGlM6tphvnv49FHBVDSgttMdD_LnYyRSKJM,10302
31
- modal/config.py,sha256=Zx7YsllgIJzMRKeIkaGSLLtMFV4kTUvGxpptnmqlP1U,11623
29
+ modal/cls.py,sha256=OE6lPrKmaZDvyctfmZ__nCIw-b7AWxSmoOHMqlrrI7A,32723
30
+ modal/cls.pyi,sha256=pTYO9JsRENmsa5pDgzfoRJGm_NpCvEjEx--vs-jJkj8,10902
31
+ modal/config.py,sha256=FlqVyh6LVukMahhmEGQVTwWtwtfoPfHqEo3GDn13EOA,11687
32
32
  modal/container_process.py,sha256=vvyK3DVPUMsuqvkKdUiQ49cDLF9JawGrxpglLk5vfgI,6208
33
33
  modal/container_process.pyi,sha256=bXs2KHe7nxVuLAm6RRBqXCvDKelANGX9gFY8qIuZYDs,2898
34
34
  modal/dict.py,sha256=3Pb45IkfqcDGXu3VVStJVbC_QYk6RTRXrMbZxtByAAk,13354
@@ -40,7 +40,7 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
40
40
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
41
41
  modal/file_pattern_matcher.py,sha256=trosX-Bp7dOubudN1bLLhRAoidWy1TcoaR4Pv8CedWw,6497
42
42
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
43
- modal/functions.pyi,sha256=0Au1n37DimTZVvxCIR7HWALuNGxfJ_fcNR-or37eo5k,14438
43
+ modal/functions.pyi,sha256=m1PL2pwO-lnGV0uZDVCmzZ_v7Mu8ISRtxmxS15aEIAQ,14785
44
44
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
45
45
  modal/image.py,sha256=HtkKomhX4inozqSRi7lf5Vt9IEqCnVHn5bEo59hD64A,92835
46
46
  modal/image.pyi,sha256=iWclz2rxaP-LSsYMgU0X3ZcN5mEFvpyKzIPKJbohmsg,25591
@@ -153,10 +153,10 @@ modal_docs/mdmd/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,2
153
153
  modal_docs/mdmd/mdmd.py,sha256=Irx49MCCTlBOP4FBdLR--JrpA3-WhsVeriq0LGgsRic,6232
154
154
  modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
155
155
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
156
- modal_proto/api.proto,sha256=KLgOS8GclVSbeNOJcxC2Vyzbns2BHt9AdvQrXBEltvA,90668
156
+ modal_proto/api.proto,sha256=PWLx_gHuGjruhb-x03G619KXkIaoq4973uQvIe6fpcQ,91186
157
157
  modal_proto/api_grpc.py,sha256=9Rs0JyHcz_DSjVKhdtMbDuNt6qDkrE2718KsyA3QL4c,110702
158
- modal_proto/api_pb2.py,sha256=rl4rGn-Q_AS-Kn_F_T3df0_Lx2rvJMajdcpTkewJ0Ag,320170
159
- modal_proto/api_pb2.pyi,sha256=QLmFaTak-GwdKUhGQGk-DudI3cV7PdluTWSnvxlgobo,434662
158
+ modal_proto/api_pb2.py,sha256=UHDLT-LkMVEyTR-uHxMMenpGhtuVVRwPLYnAj9lXMy0,321651
159
+ modal_proto/api_pb2.pyi,sha256=ufI-SQmXNkrjw_jDNv6un28ihwZzBnhoctmEmRCGHKo,438025
160
160
  modal_proto/api_pb2_grpc.py,sha256=olXvs6OQvy7pqvHP9bkSWC_DdIv0iO38xRlmkLo-ai8,239213
161
161
  modal_proto/api_pb2_grpc.pyi,sha256=ybhcN2nwFBIPd4Z4kkMOv-M8Ejidz93Bl4zScLpYcK0,55706
162
162
  modal_proto/modal_api_grpc.py,sha256=43ujbC_a8YAjuhtEvS-O-5lNpkG5d0K0ZIlryJ4weT4,14766
@@ -170,10 +170,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
170
170
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
171
  modal_version/__init__.py,sha256=wiJQ53c-OMs0Xf1UeXOxQ7FwlV1VzIjnX6o-pRYZ_Pk,470
172
172
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
173
- modal_version/_version_generated.py,sha256=b_9tYBKQ8OVORw51ouAMn3uT9_gfkq2Vrg3B7PU_BQw,150
174
- modal-0.73.150.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
175
- modal-0.73.150.dist-info/METADATA,sha256=ePf8YfB9Bp8xAIz5Mjv9GwuZpwsQnBC_wnNqL3u-AY8,2453
176
- modal-0.73.150.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
177
- modal-0.73.150.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
- modal-0.73.150.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
- modal-0.73.150.dist-info/RECORD,,
173
+ modal_version/_version_generated.py,sha256=KZXRsCy2OlLht4bWbBOqRjtFexrC-QH_9Lv8oc7DDgk,150
174
+ modal-0.73.151.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
175
+ modal-0.73.151.dist-info/METADATA,sha256=bzJWJmO2ve_UUdSaJsHNlIvML36c8NQ1PQ2mZFvvlz0,2453
176
+ modal-0.73.151.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
177
+ modal-0.73.151.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
+ modal-0.73.151.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
+ modal-0.73.151.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -1308,7 +1308,7 @@ message Function {
1308
1308
  bool _experimental_enable_gpu_snapshot = 78; // Experimental support for GPU snapshotting
1309
1309
 
1310
1310
  AutoscalerSettings autoscaler_settings = 79; // Bundle of parameters related to autoscaling
1311
-
1311
+ FunctionSchema function_schema = 80;
1312
1312
  }
1313
1313
 
1314
1314
  message FunctionAsyncInvokeRequest {
@@ -1457,7 +1457,7 @@ message FunctionData {
1457
1457
  bool runtime_perf_record = 29; // For internal debugging use only.
1458
1458
 
1459
1459
  AutoscalerSettings autoscaler_settings = 31; // Bundle of parameters related to autoscaling
1460
-
1460
+ FunctionSchema function_schema = 32;
1461
1461
  }
1462
1462
 
1463
1463
  message FunctionExtended {
@@ -1591,6 +1591,7 @@ message FunctionHandleMetadata {
1591
1591
  ClassParameterInfo class_parameter_info = 43;
1592
1592
  // Mapping of method names to their metadata, only non-empty for class service functions
1593
1593
  map<string, FunctionHandleMetadata> method_handle_metadata = 44;
1594
+ FunctionSchema function_schema = 45;
1594
1595
  }
1595
1596
 
1596
1597
  message FunctionInput {
@@ -1647,6 +1648,7 @@ message FunctionPrecreateRequest {
1647
1648
  string use_method_name = 7; // for class methods - this method name needs to be included in the FunctionInput
1648
1649
  // Mapping of method names to method definitions, only non-empty for class service functions
1649
1650
  map<string, MethodDefinition> method_definitions = 8;
1651
+ FunctionSchema function_schema = 9;
1650
1652
  }
1651
1653
 
1652
1654
  message FunctionPrecreateResponse {
@@ -1712,6 +1714,16 @@ message FunctionRetryPolicy {
1712
1714
  uint32 retries = 18;
1713
1715
  }
1714
1716
 
1717
+ message FunctionSchema {
1718
+ enum FunctionSchemaType {
1719
+ FUNCTION_SCHEMA_UNSPECIFIED = 0;
1720
+ FUNCTION_SCHEMA_V1 = 1;
1721
+ }
1722
+ FunctionSchemaType schema_type = 1; // allows easy disambiguation between empty schema and no schema collection etc.
1723
+ repeated ClassParameterSpec arguments = 2;
1724
+ GenericPayloadType return_type = 3;
1725
+ }
1726
+
1715
1727
  message FunctionStats {
1716
1728
  uint32 backlog = 1;
1717
1729
  uint32 num_total_tasks = 3;
@@ -1891,6 +1903,7 @@ message MethodDefinition {
1891
1903
  string web_url = 4;
1892
1904
  WebUrlInfo web_url_info = 5;
1893
1905
  repeated CustomDomainInfo custom_domain_info = 6;
1906
+ FunctionSchema function_schema = 7;
1894
1907
  }
1895
1908
 
1896
1909
  message MountFile {