modal 0.73.113__py3-none-any.whl → 0.73.115__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
@@ -245,8 +245,7 @@ class _Invocation:
245
245
  or not ctx.retry_policy
246
246
  or ctx.retry_policy.retries == 0
247
247
  or ctx.function_call_invocation_type != api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC
248
- # TODO: Eventually we want to honor this flag. For now, we ignore it.
249
- # or not ctx.sync_client_retries_enabled
248
+ or not ctx.sync_client_retries_enabled
250
249
  ):
251
250
  return await self._get_single_output()
252
251
 
@@ -1311,16 +1310,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1311
1310
  yield item
1312
1311
 
1313
1312
  async def _call_function(self, args, kwargs) -> ReturnType:
1314
- if config.get("client_retries"):
1315
- function_call_invocation_type = api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC
1316
- else:
1317
- function_call_invocation_type = api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC_LEGACY
1318
1313
  invocation = await _Invocation.create(
1319
1314
  self,
1320
1315
  args,
1321
1316
  kwargs,
1322
1317
  client=self.client,
1323
- function_call_invocation_type=function_call_invocation_type,
1318
+ function_call_invocation_type=api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC,
1324
1319
  )
1325
1320
 
1326
1321
  return await invocation.run_function()
modal/_serialization.py CHANGED
@@ -389,6 +389,12 @@ def check_valid_cls_constructor_arg(key, obj):
389
389
  )
390
390
 
391
391
 
392
+ def assert_bytes(obj: Any):
393
+ if not isinstance(obj, bytes):
394
+ raise TypeError(f"Expected bytes, got {type(obj)}")
395
+ return obj
396
+
397
+
392
398
  @dataclass
393
399
  class ParamTypeInfo:
394
400
  default_field: str
@@ -396,16 +402,27 @@ class ParamTypeInfo:
396
402
  converter: typing.Callable[[str], typing.Any]
397
403
 
398
404
 
399
- PARAM_TYPE_MAPPING = {
405
+ PYTHON_TO_PROTO_TYPE: dict[type, "api_pb2.ParameterType.ValueType"] = {
406
+ # python type -> protobuf type enum
407
+ str: api_pb2.PARAM_TYPE_STRING,
408
+ int: api_pb2.PARAM_TYPE_INT,
409
+ bytes: api_pb2.PARAM_TYPE_BYTES,
410
+ }
411
+
412
+ PROTO_TYPE_INFO = {
413
+ # Protobuf type enum -> encode/decode helper metadata
400
414
  api_pb2.PARAM_TYPE_STRING: ParamTypeInfo(default_field="string_default", proto_field="string_value", converter=str),
401
415
  api_pb2.PARAM_TYPE_INT: ParamTypeInfo(default_field="int_default", proto_field="int_value", converter=int),
416
+ api_pb2.PARAM_TYPE_BYTES: ParamTypeInfo(
417
+ default_field="bytes_default", proto_field="bytes_value", converter=assert_bytes
418
+ ),
402
419
  }
403
420
 
404
421
 
405
422
  def serialize_proto_params(python_params: dict[str, Any], schema: typing.Sequence[api_pb2.ClassParameterSpec]) -> bytes:
406
423
  proto_params: list[api_pb2.ClassParameterValue] = []
407
424
  for schema_param in schema:
408
- type_info = PARAM_TYPE_MAPPING.get(schema_param.type)
425
+ type_info = PROTO_TYPE_INFO.get(schema_param.type)
409
426
  if not type_info:
410
427
  raise ValueError(f"Unsupported parameter type: {schema_param.type}")
411
428
  proto_param = api_pb2.ClassParameterValue(
@@ -429,6 +446,8 @@ def serialize_proto_params(python_params: dict[str, Any], schema: typing.Sequenc
429
446
 
430
447
 
431
448
  def deserialize_proto_params(serialized_params: bytes, schema: list[api_pb2.ClassParameterSpec]) -> dict[str, Any]:
449
+ # TODO: this currently requires the schema to decode a payload, but we should make the validation
450
+ # distinct from the deserialization
432
451
  proto_struct = api_pb2.ClassParameterSet()
433
452
  proto_struct.ParseFromString(serialized_params)
434
453
  value_by_name = {p.name: p for p in proto_struct.parameters}
@@ -449,6 +468,8 @@ def deserialize_proto_params(serialized_params: bytes, schema: list[api_pb2.Clas
449
468
  python_value = param_value.string_value
450
469
  elif schema_param.type == api_pb2.PARAM_TYPE_INT:
451
470
  python_value = param_value.int_value
471
+ elif schema_param.type == api_pb2.PARAM_TYPE_BYTES:
472
+ python_value = param_value.bytes_value
452
473
  else:
453
474
  # TODO(elias): based on `parameters` declared types, we could add support for
454
475
  # custom non proto types encoded as bytes in the proto, e.g. PARAM_TYPE_PYTHON_PICKLE
@@ -15,7 +15,7 @@ from synchronicity.exceptions import UserCodeException
15
15
  import modal_proto
16
16
  from modal_proto import api_pb2
17
17
 
18
- from .._serialization import deserialize, deserialize_data_format, serialize
18
+ from .._serialization import PROTO_TYPE_INFO, PYTHON_TO_PROTO_TYPE, deserialize, deserialize_data_format, serialize
19
19
  from .._traceback import append_modal_tb
20
20
  from ..config import config, logger
21
21
  from ..exception import (
@@ -38,13 +38,6 @@ class FunctionInfoType(Enum):
38
38
  NOTEBOOK = "notebook"
39
39
 
40
40
 
41
- # TODO(elias): Add support for quoted/str annotations
42
- CLASS_PARAM_TYPE_MAP: dict[type, tuple["api_pb2.ParameterType.ValueType", str]] = {
43
- str: (api_pb2.PARAM_TYPE_STRING, "string_default"),
44
- int: (api_pb2.PARAM_TYPE_INT, "int_default"),
45
- }
46
-
47
-
48
41
  class LocalFunctionError(InvalidError):
49
42
  """Raised if a function declared in a non-global scope is used in an impermissible way"""
50
43
 
@@ -284,7 +277,7 @@ class FunctionInfo:
284
277
  return api_pb2.ClassParameterInfo()
285
278
 
286
279
  # TODO(elias): Resolve circular dependencies... maybe we'll need some cls_utils module
287
- from modal.cls import _get_class_constructor_signature, _use_annotation_parameters
280
+ from modal.cls import _get_class_constructor_signature, _use_annotation_parameters, _validate_parameter_type
288
281
 
289
282
  if not _use_annotation_parameters(self.user_cls):
290
283
  return api_pb2.ClassParameterInfo(format=api_pb2.ClassParameterInfo.PARAM_SERIALIZATION_FORMAT_PICKLE)
@@ -296,12 +289,12 @@ class FunctionInfo:
296
289
  signature = _get_class_constructor_signature(self.user_cls)
297
290
  for param in signature.parameters.values():
298
291
  has_default = param.default is not param.empty
299
- if param.annotation not in CLASS_PARAM_TYPE_MAP:
300
- raise InvalidError("modal.parameter() currently only support str or int types")
301
- param_type, default_field = CLASS_PARAM_TYPE_MAP[param.annotation]
302
- class_param_spec = api_pb2.ClassParameterSpec(name=param.name, has_default=has_default, type=param_type)
292
+ _validate_parameter_type(self.user_cls.__name__, param.name, param.annotation)
293
+ proto_type = PYTHON_TO_PROTO_TYPE[param.annotation]
294
+ proto_type_info = PROTO_TYPE_INFO[proto_type]
295
+ class_param_spec = api_pb2.ClassParameterSpec(name=param.name, has_default=has_default, type=proto_type)
303
296
  if has_default:
304
- setattr(class_param_spec, default_field, param.default)
297
+ setattr(class_param_spec, proto_type_info.default_field, param.default)
305
298
  modal_parameters.append(class_param_spec)
306
299
 
307
300
  return api_pb2.ClassParameterInfo(
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.113",
34
+ version: str = "0.73.115",
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.113",
96
+ version: str = "0.73.115",
97
97
  ): ...
98
98
  def is_closed(self) -> bool: ...
99
99
  @property
modal/cls.py CHANGED
@@ -9,7 +9,6 @@ from typing import Any, Callable, Optional, TypeVar, Union
9
9
  from google.protobuf.message import Message
10
10
  from grpclib import GRPCError, Status
11
11
 
12
- from modal._utils.function_utils import CLASS_PARAM_TYPE_MAP, FunctionInfo
13
12
  from modal_proto import api_pb2
14
13
 
15
14
  from ._functions import _Function, _parse_retries
@@ -22,7 +21,7 @@ from ._partial_function import (
22
21
  )
23
22
  from ._resolver import Resolver
24
23
  from ._resources import convert_fn_config_to_resources_config
25
- from ._serialization import check_valid_cls_constructor_arg
24
+ from ._serialization import PYTHON_TO_PROTO_TYPE, check_valid_cls_constructor_arg
26
25
  from ._traceback import print_server_warnings
27
26
  from ._utils.async_utils import synchronize_api, synchronizer
28
27
  from ._utils.deprecation import deprecation_warning, renamed_parameter, warn_on_renamed_autoscaler_settings
@@ -133,6 +132,8 @@ def _bind_instance_method(cls: "_Cls", service_function: _Function, method_name:
133
132
 
134
133
  if cls._is_local():
135
134
  partial_function = cls._method_partials[method_name]
135
+ from modal._utils.function_utils import FunctionInfo
136
+
136
137
  fun._info = FunctionInfo(
137
138
  # ugly - needed for .local() TODO (elias): Clean up!
138
139
  partial_function.raw_f,
@@ -361,6 +362,15 @@ class _Obj:
361
362
  Obj = synchronize_api(_Obj)
362
363
 
363
364
 
365
+ def _validate_parameter_type(cls_name: str, parameter_name: str, parameter_type: type):
366
+ if parameter_type not in PYTHON_TO_PROTO_TYPE:
367
+ type_name = getattr(parameter_type, "__name__", repr(parameter_type))
368
+ supported = ", ".join(parameter_type.__name__ for parameter_type in PYTHON_TO_PROTO_TYPE.keys())
369
+ raise InvalidError(
370
+ f"{cls_name}.{parameter_name}: {type_name} is not a supported parameter type. Use one of: {supported}"
371
+ )
372
+
373
+
364
374
  class _Cls(_Object, type_prefix="cs"):
365
375
  """
366
376
  Cls adds method pooling and [lifecycle hook](/docs/guide/lifecycle-functions) behavior
@@ -461,12 +471,8 @@ class _Cls(_Object, type_prefix="cs"):
461
471
 
462
472
  annotated_params = {k: t for k, t in annotations.items() if k in params}
463
473
  for k, t in annotated_params.items():
464
- if t not in CLASS_PARAM_TYPE_MAP:
465
- t_name = getattr(t, "__name__", repr(t))
466
- supported = ", ".join(t.__name__ for t in CLASS_PARAM_TYPE_MAP.keys())
467
- raise InvalidError(
468
- f"{user_cls.__name__}.{k}: {t_name} is not a supported parameter type. Use one of: {supported}"
469
- )
474
+ if t not in PYTHON_TO_PROTO_TYPE:
475
+ _validate_parameter_type(user_cls.__name__, k, t)
470
476
 
471
477
  @staticmethod
472
478
  def from_local(user_cls, app: "modal.app._App", class_service_function: _Function) -> "_Cls":
modal/cls.pyi CHANGED
@@ -109,6 +109,8 @@ class Obj:
109
109
  async def _aenter(self): ...
110
110
  def __getattr__(self, k): ...
111
111
 
112
+ def _validate_parameter_type(cls_name: str, parameter_name: str, parameter_type: type): ...
113
+
112
114
  class _Cls(modal._object._Object):
113
115
  _class_service_function: typing.Optional[modal._functions._Function]
114
116
  _options: typing.Optional[_ServiceOptions]
modal/config.py CHANGED
@@ -230,7 +230,6 @@ _SETTINGS = {
230
230
  "image_builder_version": _Setting(),
231
231
  "strict_parameters": _Setting(False, transform=_to_boolean), # For internal/experimental use
232
232
  "snapshot_debug": _Setting(False, transform=_to_boolean),
233
- "client_retries": _Setting(False, transform=_to_boolean), # For internal testing.
234
233
  "cuda_checkpoint_path": _Setting("/__modal/.bin/cuda-checkpoint"), # Used for snapshotting GPU memory.
235
234
  }
236
235
 
modal/functions.pyi CHANGED
@@ -198,11 +198,11 @@ class Function(
198
198
 
199
199
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
200
200
 
201
- class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
201
+ class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
202
202
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
203
203
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
204
204
 
205
- 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]
206
206
 
207
207
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
208
208
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -217,19 +217,19 @@ class Function(
217
217
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
218
218
  ) -> modal._functions.OriginalReturnType: ...
219
219
 
220
- 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]):
221
221
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
222
222
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
223
223
 
224
224
  _experimental_spawn: ___experimental_spawn_spec[
225
- modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
225
+ modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
226
226
  ]
227
227
 
228
- class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
228
+ class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
229
229
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
230
230
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
231
231
 
232
- 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]
233
233
 
234
234
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
235
235
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: modal
3
- Version: 0.73.113
3
+ Version: 0.73.115
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=arhkIoF8nQNfa4iwYGSoqN3QMDg5M38QNAODXC8TlKc,29301
6
- modal/_functions.py,sha256=SrgTst7GCYcj1IVCaW126T6wfZLWeF_VJYyLVcgBaVc,73133
6
+ modal/_functions.py,sha256=B2pf6yN3MI07j9TdyJ-fSLUHXUjrLJzEby37I8WhKnc,72826
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=NYSjM9FnbLXULuzpboVvPcFFHRyh3hn_AcSFXQCGPYc,19741
16
+ modal/_serialization.py,sha256=xqBzCNvzDofh3DSmXFbK3nFvpz6gi4JDEnsLhcW21uI,20554
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
@@ -22,12 +22,12 @@ modal/app.py,sha256=ojhuLZuNZAQ1OsbDH0k6G4pm1W7bOIvZfXbaKlvQ-Ao,45622
22
22
  modal/app.pyi,sha256=tZFbcsu20SuvfB2puxCyuXLFNJ9bQulzag55rVpgZmc,26827
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=j9D3hNis1lfhnz9lVFGgJgowbH3PaGUzNKgHPWYG778,15372
25
- modal/client.pyi,sha256=kNMyWXSDP_ZYTG0DIjukvvlEOzqpAAcPw5eSS5yh0sQ,7661
25
+ modal/client.pyi,sha256=xE78ktMJldHGjMgAE6Sfpl6LiDrQvIFGcA1yYNgpqGY,7661
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=JhDbaZZHN52lqA_roY1BCbcN9BvbkUcdXiM2Kg9lIc0,31717
29
- modal/cls.pyi,sha256=ZJUwtRaQBGlM6tphvnv49FHBVDSgttMdD_LnYyRSKJM,10302
30
- modal/config.py,sha256=Boz1bPzaG-k5Grjq6y6fAELH1N_gTuYDnpB6FODzCPo,11710
28
+ modal/cls.py,sha256=jjhzmnGdmLaBTJzVfUM81B-DWU2Mm2Rdw-m2LCGYbE0,31955
29
+ modal/cls.pyi,sha256=odrnYkqtQRiVwrAc6Ly23_zMYojIDYPo2bwMeElz-Ms,10395
30
+ modal/config.py,sha256=Zx7YsllgIJzMRKeIkaGSLLtMFV4kTUvGxpptnmqlP1U,11623
31
31
  modal/container_process.py,sha256=WTqLn01dJPVkPpwR_0w_JH96ceN5mV4TGtiu1ZR2RRA,6108
32
32
  modal/container_process.pyi,sha256=Hf0J5JyDdCCXBJSKx6gvkPOo0XrztCm78xzxamtzUjQ,2828
33
33
  modal/dict.py,sha256=3Pb45IkfqcDGXu3VVStJVbC_QYk6RTRXrMbZxtByAAk,13354
@@ -41,7 +41,7 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
41
41
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
42
42
  modal/file_pattern_matcher.py,sha256=trosX-Bp7dOubudN1bLLhRAoidWy1TcoaR4Pv8CedWw,6497
43
43
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
44
- modal/functions.pyi,sha256=ujc6eIYyNmMn__4dpxEy85-vZmAniZv56D2A4uBgs6U,14377
44
+ modal/functions.pyi,sha256=D-PDJfSbwqMDXdq7Bxu2ErZRENo-tRgu_zPoB-jl0OU,14377
45
45
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
46
46
  modal/image.py,sha256=Q-zNKdDmn7HHRv8YW7cIVYD1lbsOiiRuWfTZqLjGu2U,92189
47
47
  modal/image.pyi,sha256=DQ4DLOCPr6_yV7z4LS0bTY0rOyvQP9-dQOrzaW7pPG8,25260
@@ -98,7 +98,7 @@ modal/_utils/blob_utils.py,sha256=RB1G6T7eC1Poe-O45qYLaxwCr2jkM-Q6Nexk1J3wk_w,14
98
98
  modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
99
99
  modal/_utils/deprecation.py,sha256=EXP1beU4pmEqEzWMLw6E3kUfNfpmNA_VOp6i0EHi93g,4856
100
100
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
101
- modal/_utils/function_utils.py,sha256=OqsmLKOqSenxkXiNSPUWpKqD5KotySa_Omw1tmt97K0,27380
101
+ modal/_utils/function_utils.py,sha256=Un9WXZCmLb0itbDDOn4q6hF6n1r5ayhxPDb6oMCkucE,27190
102
102
  modal/_utils/git_utils.py,sha256=qtUU6JAttF55ZxYq51y55OR58B0tDPZsZWK5dJe6W5g,3182
103
103
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
104
104
  modal/_utils/grpc_utils.py,sha256=wmMydVKN9YbugTwUXuOuzxbpzYvxkTDaFRxlBtIDE_0,8526
@@ -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=nCyRegt7czA8sl95JTLmjtQiNEdVuyQ2QYPjkUjvXgU,150
174
- modal-0.73.113.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
175
- modal-0.73.113.dist-info/METADATA,sha256=1T09sS1RCSYsnkDJC3yVvhZ1YtGdZJFyU9iVeYXAxw8,2453
176
- modal-0.73.113.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
177
- modal-0.73.113.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
- modal-0.73.113.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
- modal-0.73.113.dist-info/RECORD,,
173
+ modal_version/_version_generated.py,sha256=UYVu80OuzFCShlTl1bGkjkxEUmQ2WFqu_AaRJ9AXteA,150
174
+ modal-0.73.115.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
175
+ modal-0.73.115.dist-info/METADATA,sha256=lHov8_PXPDz7NNTAKDel9-Z-JhNiEwfson9zuw6NMt8,2453
176
+ modal-0.73.115.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
177
+ modal-0.73.115.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
+ modal-0.73.115.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
+ modal-0.73.115.dist-info/RECORD,,
@@ -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 = 113 # git: 456336d
4
+ build_number = 115 # git: c9326d9