modal 0.74.55__py3-none-any.whl → 0.74.57__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
@@ -477,6 +477,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
477
477
  i6pn_enabled: bool = False,
478
478
  # Experimental: Clustered functions
479
479
  cluster_size: Optional[int] = None,
480
+ rdma: Optional[bool] = None,
480
481
  max_inputs: Optional[int] = None,
481
482
  ephemeral_disk: Optional[int] = None,
482
483
  # current default: first-party, future default: main-package
@@ -899,7 +900,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
899
900
 
900
901
  function_definition_copy.resources.CopyFrom(
901
902
  convert_fn_config_to_resources_config(
902
- cpu=cpu, memory=memory, gpu=_gpu, ephemeral_disk=ephemeral_disk
903
+ cpu=cpu, memory=memory, gpu=_gpu, ephemeral_disk=ephemeral_disk, rdma=rdma
903
904
  ),
904
905
  )
905
906
  ranked_function = api_pb2.FunctionData.RankedFunction(
@@ -914,7 +915,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
914
915
  # assert isinstance(gpu, GPU_T) # includes the case where gpu==None case
915
916
  function_definition.resources.CopyFrom(
916
917
  convert_fn_config_to_resources_config(
917
- cpu=cpu, memory=memory, gpu=gpu, ephemeral_disk=ephemeral_disk
918
+ cpu=cpu, memory=memory, gpu=gpu, ephemeral_disk=ephemeral_disk, rdma=rdma
918
919
  ),
919
920
  )
920
921
 
@@ -77,6 +77,7 @@ class _PartialFunctionParams:
77
77
  max_concurrent_inputs: Optional[int] = None
78
78
  target_concurrent_inputs: Optional[int] = None
79
79
  build_timeout: Optional[int] = None
80
+ rdma: Optional[bool] = None
80
81
 
81
82
  def update(self, other: "_PartialFunctionParams") -> None:
82
83
  """Update self with params set in other."""
@@ -900,7 +901,7 @@ def _concurrent(
900
901
 
901
902
 
902
903
  # NOTE: clustered is currently exposed through modal.experimental, not the top-level namespace
903
- def _clustered(size: int, broadcast: bool = True):
904
+ def _clustered(size: int, broadcast: bool = True, rdma: bool = False):
904
905
  """Provision clusters of colocated and networked containers for the Function.
905
906
 
906
907
  Parameters:
@@ -918,7 +919,7 @@ def _clustered(size: int, broadcast: bool = True):
918
919
  raise ValueError("cluster size must be greater than 0")
919
920
 
920
921
  flags = _PartialFunctionFlags.CLUSTERED
921
- params = _PartialFunctionParams(cluster_size=size)
922
+ params = _PartialFunctionParams(cluster_size=size, rdma=rdma)
922
923
 
923
924
  def wrapper(
924
925
  obj: Union[_PartialFunction[P, ReturnType, ReturnType], Callable[P, ReturnType]],
modal/_resources.py CHANGED
@@ -13,6 +13,7 @@ def convert_fn_config_to_resources_config(
13
13
  memory: Optional[Union[int, tuple[int, int]]],
14
14
  gpu: GPU_T,
15
15
  ephemeral_disk: Optional[int],
16
+ rdma: Optional[bool] = None,
16
17
  ) -> api_pb2.Resources:
17
18
  gpu_config = parse_gpu_config(gpu)
18
19
  if cpu and isinstance(cpu, tuple):
@@ -48,4 +49,5 @@ def convert_fn_config_to_resources_config(
48
49
  memory_mb=memory_mb,
49
50
  memory_mb_max=memory_mb_max,
50
51
  ephemeral_disk_mb=ephemeral_disk,
52
+ rdma=rdma or False,
51
53
  )
modal/app.py CHANGED
@@ -747,6 +747,7 @@ class _App:
747
747
  )
748
748
  i6pn_enabled = i6pn or (f.flags & _PartialFunctionFlags.CLUSTERED)
749
749
  cluster_size = f.params.cluster_size # Experimental: Clustered functions
750
+ rdma = f.params.rdma
750
751
 
751
752
  info = FunctionInfo(f.raw_f, serialized=serialized, name_override=name)
752
753
  raw_f = f.raw_f
@@ -799,6 +800,7 @@ class _App:
799
800
  target_concurrent_inputs = None
800
801
 
801
802
  cluster_size = None # Experimental: Clustered functions
803
+ rdma = None
802
804
  i6pn_enabled = i6pn
803
805
 
804
806
  if info.function_name.endswith(".app"):
@@ -850,6 +852,7 @@ class _App:
850
852
  scheduler_placement=scheduler_placement,
851
853
  i6pn_enabled=i6pn_enabled,
852
854
  cluster_size=cluster_size, # Experimental: Clustered functions
855
+ rdma=rdma,
853
856
  include_source=include_source if include_source is not None else self._include_source_default,
854
857
  experimental_options={k: str(v) for k, v in (experimental_options or {}).items()},
855
858
  _experimental_proxy_ip=_experimental_proxy_ip,
modal/cli/cluster.py ADDED
@@ -0,0 +1,82 @@
1
+ # Copyright Modal Labs 2022
2
+ from typing import Optional, Union
3
+
4
+ import typer
5
+ from rich.console import Console
6
+ from rich.text import Text
7
+
8
+ from modal._object import _get_environment_name
9
+ from modal._pty import get_pty_info
10
+ from modal._utils.async_utils import synchronizer
11
+ from modal.cli.utils import ENV_OPTION, display_table, is_tty, timestamp_to_local
12
+ from modal.client import _Client
13
+ from modal.config import config
14
+ from modal.container_process import _ContainerProcess
15
+ from modal.environments import ensure_env
16
+ from modal.stream_type import StreamType
17
+ from modal_proto import api_pb2
18
+
19
+ cluster_cli = typer.Typer(
20
+ name="cluster", help="Manage and connect to running multi-node clusters.", no_args_is_help=True
21
+ )
22
+
23
+
24
+ @cluster_cli.command("list")
25
+ @synchronizer.create_blocking
26
+ async def list_(env: Optional[str] = ENV_OPTION, json: bool = False):
27
+ """List all clusters that are currently running."""
28
+ env = ensure_env(env)
29
+ client = await _Client.from_env()
30
+ environment_name = _get_environment_name(env)
31
+ res: api_pb2.ClusterListResponse = await client.stub.ClusterList(
32
+ api_pb2.ClusterListRequest(environment_name=environment_name)
33
+ )
34
+
35
+ column_names = ["Cluster ID", "App ID", "Start Time", "Nodes"]
36
+ rows: list[list[Union[Text, str]]] = []
37
+ res.clusters.sort(key=lambda c: c.started_at, reverse=True)
38
+
39
+ for c in res.clusters:
40
+ rows.append(
41
+ [
42
+ c.cluster_id,
43
+ c.app_id,
44
+ timestamp_to_local(c.started_at, json) if c.started_at else "Pending",
45
+ str(len(c.task_ids)),
46
+ ]
47
+ )
48
+
49
+ display_table(column_names, rows, json=json, title=f"Active Multi-node Clusters in environment: {environment_name}")
50
+
51
+
52
+ @cluster_cli.command("shell")
53
+ @synchronizer.create_blocking
54
+ async def shell(
55
+ cluster_id: str = typer.Argument(help="Cluster ID"),
56
+ rank: int = typer.Option(default=0, help="Rank of the node to shell into"),
57
+ ):
58
+ """Open a shell to a multi-node cluster node."""
59
+ client = await _Client.from_env()
60
+ res: api_pb2.ClusterGetResponse = await client.stub.ClusterGet(api_pb2.ClusterGetRequest(cluster_id=cluster_id))
61
+ if len(res.cluster.task_ids) <= rank:
62
+ raise typer.Abort(f"No node with rank {rank} in cluster {cluster_id}")
63
+ task_id = res.cluster.task_ids[rank]
64
+ console = Console()
65
+ is_main = "(main)" if rank == 0 else ""
66
+ console.print(
67
+ f"Opening shell to node {rank} {is_main} of cluster {cluster_id} (container {task_id})", style="green"
68
+ )
69
+
70
+ pty = is_tty()
71
+ req = api_pb2.ContainerExecRequest(
72
+ task_id=task_id,
73
+ command=["/bin/bash"],
74
+ pty_info=get_pty_info(shell=True) if pty else None,
75
+ runtime_debug=config.get("function_runtime_debug"),
76
+ )
77
+ exec_res: api_pb2.ContainerExecResponse = await client.stub.ContainerExec(req)
78
+ if pty:
79
+ await _ContainerProcess(exec_res.exec_id, client).attach()
80
+ else:
81
+ # TODO: redirect stderr to its own stream?
82
+ await _ContainerProcess(exec_res.exec_id, client, stdout=StreamType.STDOUT, stderr=StreamType.STDOUT).wait()
modal/cli/entry_point.py CHANGED
@@ -10,6 +10,7 @@ from modal._utils.async_utils import synchronizer
10
10
 
11
11
  from . import run
12
12
  from .app import app_cli
13
+ from .cluster import cluster_cli
13
14
  from .config import config_cli
14
15
  from .container import container_cli
15
16
  from .dict import dict_cli
@@ -92,6 +93,8 @@ entrypoint_cli_typer.add_typer(launch_cli)
92
93
  # Deployments
93
94
  entrypoint_cli_typer.add_typer(app_cli, rich_help_panel="Deployments")
94
95
  entrypoint_cli_typer.add_typer(container_cli, rich_help_panel="Deployments")
96
+ # TODO: cluster is hidden while multi-node is in beta/experimental
97
+ entrypoint_cli_typer.add_typer(cluster_cli, rich_help_panel="Deployments", hidden=True)
95
98
 
96
99
  # Storage
97
100
  entrypoint_cli_typer.add_typer(dict_cli, rich_help_panel="Storage")
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.74.55"
30
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.57"
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.74.55"
89
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.57"
90
90
  ): ...
91
91
  def is_closed(self) -> bool: ...
92
92
  @property
modal/functions.pyi CHANGED
@@ -94,6 +94,7 @@ class Function(
94
94
  restrict_modal_access: bool = False,
95
95
  i6pn_enabled: bool = False,
96
96
  cluster_size: typing.Optional[int] = None,
97
+ rdma: typing.Optional[bool] = None,
97
98
  max_inputs: typing.Optional[int] = None,
98
99
  ephemeral_disk: typing.Optional[int] = None,
99
100
  include_source: typing.Optional[bool] = None,
@@ -222,11 +223,11 @@ class Function(
222
223
 
223
224
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
224
225
 
225
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
226
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
226
227
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
227
228
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
228
229
 
229
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
230
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
230
231
 
231
232
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
232
233
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -241,12 +242,12 @@ class Function(
241
242
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
242
243
  ) -> modal._functions.OriginalReturnType: ...
243
244
 
244
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
245
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
245
246
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
246
247
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
247
248
 
248
249
  _experimental_spawn: ___experimental_spawn_spec[
249
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
250
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
250
251
  ]
251
252
 
252
253
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
@@ -255,11 +256,11 @@ class Function(
255
256
 
256
257
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
257
258
 
258
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
259
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
259
260
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
260
261
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
261
262
 
262
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
263
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
263
264
 
264
265
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
265
266
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 0.74.55
3
+ Version: 0.74.57
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -3,26 +3,26 @@ 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=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
5
5
  modal/_container_entrypoint.py,sha256=2Zx9O_EMJg0H77EdnC2vGKs6uFMWwbP1NLFf-qYmWmU,28962
6
- modal/_functions.py,sha256=XouGO1IvJA3qSmjwZYt6i-dZxH-FJkfhwVJp4o_0j1s,77679
6
+ modal/_functions.py,sha256=9vDIyDiAqW3TTpcda0mMDP62BgMd8kUjth16xSd4Nwc,77738
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
10
10
  modal/_output.py,sha256=Z0nngPh2mKHMQc4MQ92YjVPc3ewOLa3I4dFBlL9nvQY,25656
11
- modal/_partial_function.py,sha256=pdMPMjZYBiOm037U1W-97Omw7NZ3nNyRUHAXpdTK7M4,39704
11
+ modal/_partial_function.py,sha256=TWqbBERQR0Xyl0UWAmhD2Q7EXyGPYJr8kIU2pY5i3TM,39767
12
12
  modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
13
13
  modal/_resolver.py,sha256=-nolqj_p_mx5czVYj1Mazh2IQWpSMrTOGughVJqYfo8,7579
14
- modal/_resources.py,sha256=5qmcirXUI8dSH926nwkUaeX9H25mqYu9mXD_KuT79-o,1733
14
+ modal/_resources.py,sha256=NMAp0GCLutiZI4GuKSIVnRHVlstoD3hNGUabjTUtzf4,1794
15
15
  modal/_serialization.py,sha256=wAgaALThfr-DBV9LMhM4qY_PCH7SRhA9xgoHL2bapBk,22963
16
16
  modal/_traceback.py,sha256=IZQzB3fVlUfMHOSyKUgw0H6qv4yHnpyq-XVCNZKfUdA,5023
17
17
  modal/_tunnel.py,sha256=zTBxBiuH1O22tS1OliAJdIsSmaZS8PlnifS_6S5z-mk,6320
18
18
  modal/_tunnel.pyi,sha256=JmmDYAy9F1FpgJ_hWx0xkom2nTOFQjn4mTPYlU3PFo4,1245
19
19
  modal/_type_manager.py,sha256=DWjgmjYJuOagw2erin506UUbG2H5UzZCFEekS-7hmfA,9087
20
20
  modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
21
- modal/app.py,sha256=r-9vVU1lrR1CWtJEo60fuaianvxY_oOXZyv1Qx1DEkI,51231
21
+ modal/app.py,sha256=xojuGZv4LaQwZU5ntj7WbmMjeNuB9Gll8Mzqe2LyiEs,51323
22
22
  modal/app.pyi,sha256=0QNtnUpAFbOPcbwCt119ge7OmoBqMFw5SajLgdE5eOw,28600
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=9fUzrcuA2uqCuRxHuIZxhsTR-lopTQuKxs_VvusFdLY,8343
25
+ modal/client.pyi,sha256=_KIrJFw7x6MSUXAh5wFfVriJU-z0CH8NWtGkqEU__i8,8343
26
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
27
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
28
28
  modal/cls.py,sha256=aHoMEWMZUN7bOezs3tRPxzS1FP3gTxZBORVjbPmtxyg,35338
@@ -39,7 +39,7 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
39
39
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
40
40
  modal/file_pattern_matcher.py,sha256=trosX-Bp7dOubudN1bLLhRAoidWy1TcoaR4Pv8CedWw,6497
41
41
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
42
- modal/functions.pyi,sha256=RB5J_KCZknSsZ5TW4Yi-16w-FqlHWuE3w-5DOiiSO3c,16360
42
+ modal/functions.pyi,sha256=rZarGph8_sA_Zo0LUrMOgqbXzFmxrPznWwr_UJWLY7Q,16404
43
43
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
44
44
  modal/image.py,sha256=ZCghS6l1O7pezXcdMHk6RoJpW3qWszfWGJTW38lNXaU,92797
45
45
  modal/image.pyi,sha256=ddbegF532pDLiVANOJdtJiYoDbbF3mAFrsCiyvIu7jU,25632
@@ -118,10 +118,11 @@ modal/cli/__init__.py,sha256=6FRleWQxBDT19y7OayO4lBOzuL6Bs9r0rLINYYYbHwQ,769
118
118
  modal/cli/_download.py,sha256=t6BXZwjTd9MgznDvbsV8rp0FZWggdzC-lUAGZU4xx1g,3984
119
119
  modal/cli/_traceback.py,sha256=4ywtmFcmPnY3tqb4-3fA061N2tRiM01xs8fSagtkwhE,7293
120
120
  modal/cli/app.py,sha256=87LWg3bTQQIHFOqs8iiJYD_X03omXBZ6lFYR0rMJV-I,8433
121
+ modal/cli/cluster.py,sha256=EBDhkzfOtPSbwknYdYPBGYvRAwl4Gm7OJkD6_zxrcus,3106
121
122
  modal/cli/config.py,sha256=QvFsqO4eUOtI7d_pQAOAyfq_ZitjhPtav3C6GIDQcZM,1680
122
123
  modal/cli/container.py,sha256=FYwEgjf93j4NMorAjGbSV98i1wpebqdAeNU1wfrFp1k,3668
123
124
  modal/cli/dict.py,sha256=8Wq3w-UDaywk8EVNdj-ECCNV9TYHqh4kzhUqhhulatM,4593
124
- modal/cli/entry_point.py,sha256=dOosuCwhfznwTCB4oMljUFhihq5aLUVoAz7RhcBEDnc,4189
125
+ modal/cli/entry_point.py,sha256=Ytpsy0MTLQC1RSClI0wNhCbiy6ecPO8555PMmsrxoSc,4377
125
126
  modal/cli/environment.py,sha256=Ayddkiq9jdj3XYDJ8ZmUqFpPPH8xajYlbexRkzGtUcg,4334
126
127
  modal/cli/import_refs.py,sha256=pmzY0hpexx6DtvobNmCOvRqEdS9IriEP4BpMw1TIy2w,13911
127
128
  modal/cli/launch.py,sha256=0_sBu6bv2xJEPWi-rbGS6Ri9ggnkWQvrGlgpYSUBMyY,3097
@@ -145,7 +146,7 @@ modal/requirements/2024.10.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddR
145
146
  modal/requirements/PREVIEW.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddRo,296
146
147
  modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
147
148
  modal/requirements/base-images.json,sha256=57vMSqzMbLBxw5tFWSaMiIkkVEps4JfX5PAtXGnkS4U,740
148
- modal-0.74.55.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
149
+ modal-0.74.57.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
149
150
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
150
151
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
151
152
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -170,9 +171,9 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
170
171
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
172
  modal_version/__init__.py,sha256=m94xZNWIjH8oUtJk4l9xfovzDJede2o7X-q0MHVECtM,470
172
173
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
173
- modal_version/_version_generated.py,sha256=OZ_XmoTkO3MCoksyO8lR_vFkMH1zV93AgoruWFvLPis,149
174
- modal-0.74.55.dist-info/METADATA,sha256=oCE7_7EOAb5XgRznncfj2CpEJmlHutoa2JPOv9cDg_I,2451
175
- modal-0.74.55.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
176
- modal-0.74.55.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
177
- modal-0.74.55.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
178
- modal-0.74.55.dist-info/RECORD,,
174
+ modal_version/_version_generated.py,sha256=jDPOt0hc526e_geJkc67dSyGFBVRc-ypApzbMcc47yA,149
175
+ modal-0.74.57.dist-info/METADATA,sha256=Kl0L5wgpuBfV2mQpPJJB8rKFKFeKRHGOAkcKEYsKijs,2451
176
+ modal-0.74.57.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
177
+ modal-0.74.57.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
+ modal-0.74.57.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
+ modal-0.74.57.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 = 55 # git: aa1b399
4
+ build_number = 57 # git: 747bcf5