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 +3 -2
- modal/_partial_function.py +3 -2
- modal/_resources.py +2 -0
- modal/app.py +3 -0
- modal/cli/cluster.py +82 -0
- modal/cli/entry_point.py +3 -0
- modal/client.pyi +2 -2
- modal/functions.pyi +7 -6
- {modal-0.74.55.dist-info → modal-0.74.57.dist-info}/METADATA +1 -1
- {modal-0.74.55.dist-info → modal-0.74.57.dist-info}/RECORD +15 -14
- modal_version/_version_generated.py +1 -1
- {modal-0.74.55.dist-info → modal-0.74.57.dist-info}/WHEEL +0 -0
- {modal-0.74.55.dist-info → modal-0.74.57.dist-info}/entry_points.txt +0 -0
- {modal-0.74.55.dist-info → modal-0.74.57.dist-info}/licenses/LICENSE +0 -0
- {modal-0.74.55.dist-info → modal-0.74.57.dist-info}/top_level.txt +0 -0
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
|
|
modal/_partial_function.py
CHANGED
@@ -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.
|
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.
|
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[
|
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.
|
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[
|
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.
|
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[
|
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.
|
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
|
|
@@ -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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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.
|
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=
|
174
|
-
modal-0.74.
|
175
|
-
modal-0.74.
|
176
|
-
modal-0.74.
|
177
|
-
modal-0.74.
|
178
|
-
modal-0.74.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|