modAL 1.5.4.dev16__py3-none-any.whl → 1.5.4.dev17__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/cli/container.py CHANGED
@@ -1,4 +1,6 @@
1
1
  # Copyright Modal Labs 2022
2
+ import asyncio
3
+ import dataclasses
2
4
  import warnings
3
5
  from datetime import datetime, timezone
4
6
 
@@ -24,14 +26,16 @@ from modal.cli.utils import (
24
26
  yes_option,
25
27
  )
26
28
  from modal.client import _Client
27
- from modal.exception import InvalidError
28
- from modal.sandbox import _container_exec
29
+ from modal.exception import ConflictError, InvalidError
30
+ from modal.sandbox import SandboxVersion, _container_exec, _get_sandbox_version, _Sandbox
29
31
  from modal_proto import api_pb2
30
32
 
31
33
  from ._help import ModalGroup
32
34
 
33
35
  container_cli = ModalGroup(name="container", help="Manage and connect to running containers.")
34
36
 
37
+ _SANDBOX_TASK_ID_WAIT_SECS = 55.0
38
+
35
39
 
36
40
  @container_cli.command("list")
37
41
  @click.option("--app-id", default="", help="List containers running for a specific App.")
@@ -149,6 +153,13 @@ async def logs(
149
153
  else:
150
154
  raise InvalidError(f"Invalid container ID: {container_id}")
151
155
 
156
+ is_v2_sandbox = sandbox_id is not None and _get_sandbox_version(sandbox_id) == SandboxVersion.V2
157
+
158
+ if follow and is_v2_sandbox:
159
+ raise UsageError(
160
+ "Following logs (-f/--follow) is not supported for this Sandbox. Re-run without -f to fetch its logs."
161
+ )
162
+
152
163
  if follow and (since or until or tail):
153
164
  raise UsageError("--follow cannot be combined with --since, --until, or --tail.")
154
165
 
@@ -190,32 +201,52 @@ async def logs(
190
201
  # Resolve the app_id for the container.
191
202
  client = await _Client.from_env()
192
203
 
193
- if sandbox_id:
194
- sb_resp = await client.stub.SandboxGetTaskId(api_pb2.SandboxGetTaskIdRequest(sandbox_id=sandbox_id))
195
- task_id = sb_resp.task_id
204
+ enqueued_dt: datetime | None = None
205
+ finished_dt: datetime | None = None
206
+
207
+ if is_v2_sandbox:
208
+ assert sandbox_id is not None
209
+ sandbox = await _Sandbox.from_id(sandbox_id, client)
210
+ app_id = sandbox._app_id or ""
211
+ try:
212
+ task_id = await asyncio.wait_for(
213
+ sandbox._get_task_id(raise_if_task_complete=True),
214
+ timeout=_SANDBOX_TASK_ID_WAIT_SECS,
215
+ )
216
+ except (asyncio.TimeoutError, ConflictError):
217
+ # No container ran (still queued, or finished before starting), so there are no
218
+ # logs. Returning empty is consistent with other no-logs-yet cases (e.g. logs not
219
+ # yet flushed to ClickHouse), so we don't warn.
220
+ return
221
+ log_filters = dataclasses.replace(log_filters, sandbox_id="", task_id=task_id)
222
+ else:
223
+ if sandbox_id:
224
+ sb_resp = await client.stub.SandboxGetTaskId(api_pb2.SandboxGetTaskIdRequest(sandbox_id=sandbox_id))
225
+ task_id = sb_resp.task_id
196
226
 
197
- assert task_id
198
- task_info_resp = await client.stub.TaskGetInfo(api_pb2.TaskGetInfoRequest(task_id=task_id))
199
- app_id = task_info_resp.app_id
227
+ assert task_id
228
+ task_info_resp = await client.stub.TaskGetInfo(api_pb2.TaskGetInfoRequest(task_id=task_id))
229
+ app_id = task_info_resp.app_id
200
230
 
201
- if not task_info_resp.info.enqueued_at:
202
- return
231
+ if not task_info_resp.info.enqueued_at:
232
+ return
203
233
 
204
- container_enqueued_dt = datetime.fromtimestamp(task_info_resp.info.enqueued_at, timezone.utc)
234
+ enqueued_dt = datetime.fromtimestamp(task_info_resp.info.enqueued_at, timezone.utc)
235
+ if task_info_resp.info.finished_at:
236
+ finished_dt = datetime.fromtimestamp(task_info_resp.info.finished_at, timezone.utc)
205
237
 
206
238
  now = datetime.now(timezone.utc)
239
+ # V2 Sandboxes don't expose task enqueue/finish times to the client, so fall back to the
240
+ # widest single-query window. This can miss logs older than _MAX_FETCH_RANGE for workspaces
241
+ # whose custom log retention window exceeds it.
242
+ default_since_dt = enqueued_dt or (now - _MAX_FETCH_RANGE)
243
+ default_until_dt = finished_dt or now
244
+
207
245
  if all_logs:
208
- since_dt = container_enqueued_dt
209
- if task_info_resp.info.finished_at:
210
- until_dt = datetime.fromtimestamp(task_info_resp.info.finished_at, timezone.utc)
211
- else:
212
- until_dt = now
246
+ since_dt = default_since_dt
247
+ until_dt = default_until_dt
213
248
  else:
214
- since_dt = _parse_time_arg(since, default=container_enqueued_dt)
215
- if task_info_resp.info.finished_at:
216
- default_until_dt = datetime.fromtimestamp(task_info_resp.info.finished_at, timezone.utc)
217
- else:
218
- default_until_dt = now
249
+ since_dt = _parse_time_arg(since, default=default_since_dt)
219
250
  until_dt = _parse_time_arg(until, default=default_until_dt)
220
251
 
221
252
  if since is not None and until is not None and since_dt >= until_dt:
modal/cli/run.py CHANGED
@@ -539,6 +539,13 @@ def run(
539
539
  help="Deployment strategy",
540
540
  type=click.Choice(get_args(DEPLOYMENT_STRATEGY_TYPE)),
541
541
  )
542
+ @click.option(
543
+ "--staged",
544
+ "staged",
545
+ is_flag=True,
546
+ default=False,
547
+ hidden=True,
548
+ )
542
549
  def deploy(
543
550
  app_ref: str,
544
551
  name: str = "",
@@ -548,6 +555,7 @@ def deploy(
548
555
  use_module_mode: bool = False,
549
556
  timestamps: bool = False,
550
557
  strategy: str = "rolling",
558
+ staged: bool = False,
551
559
  ):
552
560
  """Deploy a Modal application.
553
561
 
@@ -578,7 +586,14 @@ def deploy(
578
586
  "modal deploy ... --name=some-name"
579
587
  )
580
588
 
581
- res = deploy_app(app, name=name, environment_name=env or "", tag=tag, deployment_strategy=strategy)
589
+ res = deploy_app(
590
+ app,
591
+ name=name,
592
+ environment_name=env or "",
593
+ tag=tag,
594
+ deployment_strategy=strategy,
595
+ staged=staged,
596
+ )
582
597
 
583
598
  if stream_logs:
584
599
  # stream_app_logs is defined in cli/utils.py, which does not get type stubs
modal/cli/workspace.py CHANGED
@@ -3,6 +3,8 @@ import json as json_mod
3
3
 
4
4
  import click
5
5
  import rich
6
+ import rich.box
7
+ import rich.table
6
8
 
7
9
  from modal._utils.time_utils import timestamp_to_localized_str
8
10
  from modal.cli.utils import confirm_or_suggest_yes, display_table, yes_option
@@ -46,15 +48,26 @@ def members_list(json: bool = False):
46
48
 
47
49
  PROXY_TOKENS_HELP_TEXT = """Manage the proxy tokens of the current Workspace.
48
50
 
49
- Proxy tokens provide authentication to HTTP interfaces on Modal Servers and Web Functions.
50
- They are passed as request headers (`Modal-Key` and `Modal-Secret`). On Modal Servers and
51
- Endpoints they can also be joined into a single `Authorization: Bearer
52
- wk-<id>.ws-<secret>` header, which OpenAI-compatible clients accept as an API key. See
53
- https://modal.com/docs/guide/webhook-proxy-auth for more information.
51
+ Proxy tokens provide authentication to Modal Endpoints, Servers, and Web Functions.
54
52
 
55
53
  Proxy tokens and secrets have `wk-` and `ws-` prefixes, respectively. They cannot be
56
54
  interchanged with API tokens (which use `ak-` and `as-` prefixes).
57
55
 
56
+ Proxy tokens are passed as request headers, either as a key / secret pair:
57
+
58
+ ```
59
+ Modal-Key: wk-123
60
+ Modal-Secret: ws-456
61
+ ```
62
+
63
+ Or as a single Bearer token:
64
+
65
+ ```
66
+ Authorization: Bearer wk-123.ws-456
67
+ ```
68
+
69
+ See https://modal.com/docs/guide/webhook-proxy-auth for more information.
70
+
58
71
  On workspaces with RBAC enabled, tokens are scoped to specific environments;
59
72
  use the `allow` and `revoke` commands to manage environment associations.
60
73
  """
@@ -85,13 +98,10 @@ def proxy_tokens_create(*, json: bool = False):
85
98
  )
86
99
  )
87
100
  else:
88
- output_manager.print(
89
- f"Modal-Key: {token.token_id}\n"
90
- f"Modal-Secret: {token.token_secret}\n"
91
- "\n"
92
- "Or as a single header (Endpoints and Servers only):\n"
93
- f"Authorization: {bearer}"
94
- )
101
+ table = rich.table.Table(show_header=False, box=rich.box.HORIZONTALS, show_lines=True)
102
+ table.add_row(f"Modal-Key: {token.token_id}\nModal-Secret: {token.token_secret}")
103
+ table.add_row(f"Authorization: {bearer}")
104
+ output_manager.print(table)
95
105
 
96
106
 
97
107
  @proxy_tokens_cli.command("list", help="List the proxy tokens of the current Workspace.")
@@ -138,8 +148,7 @@ def proxy_tokens_revoke(token_id: str, environment_name: str):
138
148
  def proxy_tokens_delete(token_id: str, yes: bool = False):
139
149
  if not yes:
140
150
  message = (
141
- f"Are you sure you want to delete proxy token {token_id!r}? "
142
- "Any web endpoints relying on it will no longer accept it."
151
+ f"Are you sure you want to delete proxy token {token_id!r}? Requests using this token will be rejected."
143
152
  )
144
153
  confirm_or_suggest_yes(message)
145
154
  Workspace.from_context().proxy_tokens.delete(token_id)
modal/client.pyi CHANGED
@@ -37,7 +37,7 @@ class _Client:
37
37
  server_url: str,
38
38
  client_type: int,
39
39
  credentials: typing.Optional[tuple[str, str]],
40
- version: str = "1.5.4.dev16",
40
+ version: str = "1.5.4.dev17",
41
41
  ):
42
42
  """mdmd:hidden
43
43
  The Modal client object is not intended to be instantiated directly by users.
@@ -207,7 +207,7 @@ class Client:
207
207
  server_url: str,
208
208
  client_type: int,
209
209
  credentials: typing.Optional[tuple[str, str]],
210
- version: str = "1.5.4.dev16",
210
+ version: str = "1.5.4.dev17",
211
211
  ):
212
212
  """mdmd:hidden
213
213
  The Modal client object is not intended to be instantiated directly by users.
modal/functions.pyi CHANGED
@@ -546,7 +546,7 @@ class Function(
546
546
 
547
547
  _call_generator: ___call_generator_spec
548
548
 
549
- class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
549
+ class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
550
550
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
551
551
  """Calls the function remotely, executing it with the given arguments and returning the execution's result.
552
552
 
@@ -571,7 +571,7 @@ class Function(
571
571
  """
572
572
  ...
573
573
 
574
- remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
574
+ remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
575
575
 
576
576
  class __remote_gen_spec(typing_extensions.Protocol):
577
577
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -621,7 +621,7 @@ class Function(
621
621
  """
622
622
  ...
623
623
 
624
- class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
624
+ class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
625
625
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
626
626
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
627
627
 
@@ -654,7 +654,7 @@ class Function(
654
654
  """
655
655
  ...
656
656
 
657
- _experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
657
+ _experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
658
658
 
659
659
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
660
660
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
@@ -662,7 +662,7 @@ class Function(
662
662
 
663
663
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
664
664
 
665
- class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
665
+ class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
666
666
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
667
667
  """Calls the function with the given arguments, without waiting for the results.
668
668
 
@@ -695,7 +695,7 @@ class Function(
695
695
  """
696
696
  ...
697
697
 
698
- spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
698
+ spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
699
699
 
700
700
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
701
701
  """Return the inner Python object wrapped by this Modal Function.
modal/runner.py CHANGED
@@ -280,10 +280,14 @@ async def _publish_app(
280
280
  commit_info: api_pb2.CommitInfo | None = None, # Git commit information
281
281
  deployment_strategy: str = "rolling",
282
282
  environment_name: str | None = None,
283
+ staged: bool = False,
283
284
  ) -> tuple[str, list[api_pb2.Warning], float]:
284
285
  """Wrapper for AppPublish RPC."""
285
286
  deployment_strategy = _validate_deployment_strategy(deployment_strategy)
286
287
 
288
+ if staged and deployment_strategy == "recreate":
289
+ raise InvalidError("Cannot use `recreate` deployment strategy with a staged deployment")
290
+
287
291
  functions = app_local_state.functions
288
292
  definition_ids = {obj.object_id: obj._get_metadata().definition_id for obj in functions.values()} # type: ignore
289
293
 
@@ -297,6 +301,7 @@ async def _publish_app(
297
301
  function_ids=running_app.function_ids,
298
302
  class_ids=running_app.class_ids,
299
303
  definition_ids=definition_ids,
304
+ staged=staged,
300
305
  )
301
306
  response = await client.stub.AppPublish(request)
302
307
  print_server_warnings(response.server_warnings)
@@ -590,6 +595,7 @@ async def _deploy_app(
590
595
  tag: str = "",
591
596
  deployment_strategy: str = "rolling",
592
597
  client: _Client | None = None,
598
+ staged: bool = False,
593
599
  ) -> DeployResult:
594
600
  """Internal function for deploying an App.
595
601
 
@@ -665,6 +671,7 @@ async def _deploy_app(
665
671
  commit_info=commit_info,
666
672
  environment_name=root_load_context.environment_name,
667
673
  deployment_strategy=deployment_strategy,
674
+ staged=staged,
668
675
  )
669
676
  except Exception as e:
670
677
  # Note that AppClientDisconnect only stops the app if it's still initializing, and is a no-op otherwise.
modal/runner.pyi CHANGED
@@ -53,6 +53,7 @@ async def _publish_app(
53
53
  commit_info: typing.Optional[modal_proto.api_pb2.CommitInfo] = None,
54
54
  deployment_strategy: str = "rolling",
55
55
  environment_name: typing.Optional[str] = None,
56
+ staged: bool = False,
56
57
  ) -> tuple[str, list[modal_proto.api_pb2.Warning], float]:
57
58
  """Wrapper for AppPublish RPC."""
58
59
  ...
@@ -131,6 +132,7 @@ async def _deploy_app(
131
132
  tag: str = "",
132
133
  deployment_strategy: str = "rolling",
133
134
  client: typing.Optional[modal.client._Client] = None,
135
+ staged: bool = False,
134
136
  ) -> DeployResult:
135
137
  """Internal function for deploying an App.
136
138
 
@@ -238,6 +240,7 @@ class __deploy_app_spec(typing_extensions.Protocol):
238
240
  tag: str = "",
239
241
  deployment_strategy: str = "rolling",
240
242
  client: typing.Optional[modal.client.Client] = None,
243
+ staged: bool = False,
241
244
  ) -> DeployResult:
242
245
  """Internal function for deploying an App.
243
246
 
@@ -255,6 +258,7 @@ class __deploy_app_spec(typing_extensions.Protocol):
255
258
  tag: str = "",
256
259
  deployment_strategy: str = "rolling",
257
260
  client: typing.Optional[modal.client.Client] = None,
261
+ staged: bool = False,
258
262
  ) -> DeployResult:
259
263
  """Internal function for deploying an App.
260
264
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.4.dev16
3
+ Version: 1.5.4.dev17
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -34,7 +34,7 @@ modal/billing.py,sha256=E1-P_P8bJFLp-bTaggYd4BaaViImPB5UdtXiY8VeAZQ,390
34
34
  modal/billing.pyi,sha256=4m7VLYNS8IiJ2I3CJx0awvrOM6BILWRVLfdeqtAYr8M,7189
35
35
  modal/call_graph.py,sha256=XGALIDn1bLchWo_goyX23bcPjzCZcfqKUo8INIfDapo,1775
36
36
  modal/client.py,sha256=NjpAL0fIKabEaN0uXJPEoI1OTjFtXSp4tSck-M-WF3k,16360
37
- modal/client.pyi,sha256=-tK0qPkfuQyIorH6sJ18SstAHZXSgFS2VF1ShX5c46k,17999
37
+ modal/client.pyi,sha256=cO6UirQ2TAexM6Oai7KQtlq8tIgp_5Udt_bf-CsZnd8,17999
38
38
  modal/cloud_bucket_mount.py,sha256=NrdNV9r9aL3QFrlt-Dhtd7_K3f8v1igrHf2FRwgJ1CI,6827
39
39
  modal/cloud_bucket_mount.pyi,sha256=0E8d53pMh2KsFa-rMh_i6LxlzW4cMV8drVmmkPHSqZk,8149
40
40
  modal/cls.py,sha256=TxRxHdY4L6AZ6I16DNPgDryAkGtlFadD-Mm0ovtfN58,41206
@@ -51,7 +51,7 @@ modal/file_io.py,sha256=GYTa67mrmbTTTBsYQnb51VmwGIo0YY-1qQ3YBhagkmA,21795
51
51
  modal/file_io.pyi,sha256=3181-DS07flFWLf2BKjqCOiWIjieEOolf33wx6fBp5c,15377
52
52
  modal/file_pattern_matcher.py,sha256=CpaNNj7oBlOSewX-AAUZCF8KDxH0_DmgwzfpVGbPYJ4,8138
53
53
  modal/functions.py,sha256=EZRcHFfnoYbvawUJnAHF5nIvoo9GX2Djy7mUmOCXmXc,258
54
- modal/functions.pyi,sha256=d_Qsid1-LZQhNmhuDGFT1xqnadxuG95gb-IFmURPh50,50868
54
+ modal/functions.pyi,sha256=t-J2aYsREGFc2MJIckiEOK3S_n4rYJ_Vh1H6qSGUoOQ,50868
55
55
  modal/image.py,sha256=c0lUSAoU-Ip3g5DGZ0uhdCzoWSQWh1g0i-7Rxo-Sz-I,160
56
56
  modal/image.pyi,sha256=R5rdY4P30IEm-F7A2S9CdXa6QYNk-pQwsEun9BKTyLw,61094
57
57
  modal/io_streams.py,sha256=3fhhb7SDJ69pVUu9J3PiMLBePD9bpiIxPN05SCzf8FE,29118
@@ -73,8 +73,8 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
73
  modal/queue.py,sha256=UenmKInphpR8ySg80ZLgaEoV8phfDhaPgihXeao2zgM,30086
74
74
  modal/queue.pyi,sha256=Qoy2Bcd1iB7CtR_L4_7tRjJEV7rG_x_-72Sf2Nng4ro,51497
75
75
  modal/retries.py,sha256=tSGB5bGM5xZZUDXMkuelIEoQJY0vOukOssZhwc6tXAo,5014
76
- modal/runner.py,sha256=oqKyahvUEDpbGcNkxoCtKqFUShKWhoYEPecn7pk-fc4,31090
77
- modal/runner.pyi,sha256=HjkJBkv3GPIe9occmuQUBRgVuw82vrTL0urM8zV4TaY,9760
76
+ modal/runner.py,sha256=v99crUwFi3YsWfgeDElG6OIBtgRofqSfPXJRUewQsQ8,31347
77
+ modal/runner.pyi,sha256=ZMt4kNfsmOkVvyYNvy7Lgxezo7uw8IXFAIGxTzQaOIE,9872
78
78
  modal/running_app.py,sha256=xSR1VVlhxEFytmjx2x697_0GpD25Vc9crhp6r117_QY,1145
79
79
  modal/sandbox.py,sha256=tWCDtjJ3jw7Lh1AhULcDzzvIWvaKbxSy_Mer7l1J5go,126900
80
80
  modal/sandbox.pyi,sha256=Xg97tZ0hZlDQlw9Jox8RFhUZBlxVVbUPn2SD29BXmfk,150392
@@ -167,7 +167,7 @@ modal/cli/bootstrap.py,sha256=0P7GMEuDdZ-sUm_-lml_8F2YYdmzhAItoDnN4s8T9zo,5269
167
167
  modal/cli/changelog.py,sha256=l1litymo-ZH8KWVELnhcXkSYMzcsDCe40yIIUJCVgis,5799
168
168
  modal/cli/cluster.py,sha256=7u68L1PVlh4NqPoUHn7TrcekqhlpdUVjoVBnqE50-o8,4356
169
169
  modal/cli/config.py,sha256=4F67a07bS3h0sR1vMR7N21vE6tI7X5W0TQDwm_kXXdo,1899
170
- modal/cli/container.py,sha256=xQ6QYqCDJEXi9E5ABnrfFMnM-a34miVlC04XqMdME7o,10872
170
+ modal/cli/container.py,sha256=u58JzpPoPRlDUmO40ID7XR5_cFrZy1WGkOGrTygVNuE,12379
171
171
  modal/cli/curl.py,sha256=e0YOuBlWYkVdH125H1v5r1mRy0oLKGRU4qgPOHOrHLA,4523
172
172
  modal/cli/dashboard.py,sha256=v3ME8R77JksAW-mlJnn8PAi1Q6_dIoTxJTJQDsYWy8c,916
173
173
  modal/cli/dict.py,sha256=20KQa1kZu5THlneed-F_2sxcZriY0vYxcfe12XYIkLk,5152
@@ -181,7 +181,7 @@ modal/cli/logo.py,sha256=plv82syvPb8j3qrR1A_nojZwp823t3VEXaDlrx1jkt0,3221
181
181
  modal/cli/network_file_system.py,sha256=WA54LgcF3ZJv3kQgdTm9tkbwKCxA2XXGCdC3nUPdTLY,7680
182
182
  modal/cli/profile.py,sha256=b7AYNrKsSvBecaUotnRqqVxvdWMynY-Ynj69fT-kL6U,3684
183
183
  modal/cli/queues.py,sha256=eSeAUC_itVMFPQKcZJozipzUTvDaHzYJinao1_H7eXA,6620
184
- modal/cli/run.py,sha256=zyAKhPSiY1S7pcAeuwhFB2xQm55JBf5w-o6cgcVt1WM,23090
184
+ modal/cli/run.py,sha256=RL5q260KrH9XqNk17yHjoqtH-cQtQ58QEvAdMnMTaLw,23287
185
185
  modal/cli/secret.py,sha256=fg_g-iA_FkF7_0_24P_0Y3k_dCfcFbOzFo7vzIiHaLQ,8253
186
186
  modal/cli/selector.py,sha256=OJr9Ua3K_l-qu3N3-I8z8oVq8lBakws2-XgfheR5p-c,4741
187
187
  modal/cli/shell.py,sha256=K1vj3rIrAvgQVG6Osjx6dmQC3_R2ayHq79UwMMhmpMY,16867
@@ -189,7 +189,7 @@ modal/cli/skills.py,sha256=oniDafrmu_ARYTlButnlXbKE9XlEU1-EFz-eO4tdnFY,11954
189
189
  modal/cli/token.py,sha256=yvCBs6L0yjATZIRc5vo-ZCWA01cnkk3yaMm2hBceUFI,4309
190
190
  modal/cli/utils.py,sha256=Mn_R7TvlihmNS9YMAWNNyRfR70xZ34Iymeli21cKfdo,6972
191
191
  modal/cli/volume.py,sha256=DnT3Cs29mdUESM5lWqHqyBQ048HlFVDKz-ycobTnnrE,11638
192
- modal/cli/workspace.py,sha256=_qj1oVG4p89P6JGyfKtg-f9Y13hHcCbR8-nLc7N1dNM,7521
192
+ modal/cli/workspace.py,sha256=cIHHjFOgOXzfWpsnUZn-bdmzMJa0bGHY8Mh_OkI_AZM,7485
193
193
  modal/cli/programs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
194
194
  modal/cli/programs/run_jupyter.py,sha256=IJw8nds8Cjl9j4dxBqMGxhz-bIyVX0kle7jbt8HFOhM,2688
195
195
  modal/cli/programs/vscode.py,sha256=E1aJPU7b8RWWj-JX71DifsCoLYsCAnre7lATiBJjUms,3386
@@ -198,7 +198,7 @@ modal/experimental/flash.py,sha256=GAJ1c-EGL8M3_loAkqr5gdUfySMHY3U_oc6RywfZ8-0,3
198
198
  modal/experimental/flash.pyi,sha256=lpTqJFZRMGWscw0xpYZVdBMnAYjj16asXE4_64A6itQ,17774
199
199
  modal/experimental/ipython.py,sha256=kJ6o9wkAY_MiSb7paewI7f1MJAeqdi8TX5pBdhr_mUI,2925
200
200
  modal/skills/modal/SKILL.md,sha256=WzLjYJ1utjc_ZOf6qZTPwB6wxxwRYB5PibdvIf_FLy0,5316
201
- modal-1.5.4.dev16.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
201
+ modal-1.5.4.dev17.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
202
202
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
203
203
  modal_docs/gen_cli_docs.py,sha256=9-b8vl2EsLWD9zJqpCK8IUi5h44Bjn3i3rSdedZV4bA,6415
204
204
  modal_docs/gen_cli_docs_main.py,sha256=UPGr7O1DYTIRLwfINe2rbdh89J3cPVTU1OWL-SjxnOQ,198
@@ -211,8 +211,8 @@ modal_docs/mdmd/signatures.py,sha256=OASroKle763Kfumn4Ek4PABJXEGP56JMCTug44QoBx4
211
211
  modal_docs/mdmd/types.py,sha256=tv7fvziPr-MeDzOp4e2pK5h3d1DXTUOO74rPqDoBn6g,736
212
212
  modal_proto/__init__.py,sha256=Hkou4lcD5tArEkW_9v9KZhLY7fl0fA9-O28beKU55pg,396
213
213
  modal_proto/api_grpc.py,sha256=lvTskOBdLYX3Yx4e1Jk0lBaVWYu2y5mnlnsjNibhYZY,184122
214
- modal_proto/api_pb2.py,sha256=wqJawDdWUzvfXN51IoHTkpuN8LllpSld1JMe_LEvN6s,502812
215
- modal_proto/api_pb2.pyi,sha256=DF9iIc0vbOnpDmxnN50a-WYS4wPpVN2oKkYX4Y3W9B4,695309
214
+ modal_proto/api_pb2.py,sha256=AMPjtlQsTgbEJfvEUp_B6fsG6nqolMTLF_ddKc4mYpE,503017
215
+ modal_proto/api_pb2.pyi,sha256=CYi_4gQruV_QnGZHQmggC28z4MXOUD23kO0AFSd1TPM,696577
216
216
  modal_proto/api_pb2_grpc.py,sha256=4aS6cYkxKo7aUv33Smrf5xgKrgtht0SoN1PzABThS0g,395149
217
217
  modal_proto/api_pb2_grpc.pyi,sha256=jdaQTqjHhRGw-twSqPv6A97PEzmmblYkSuEWg3jdDo0,92665
218
218
  modal_proto/modal_api_grpc.py,sha256=t0y6IZq8ec9zzIhFpnKNPgYBPrxD0uD-VANzx5EtDgM,29045
@@ -222,10 +222,10 @@ modal_proto/task_command_router_pb2.py,sha256=4cyDT_uPGi54blsO663bnSzUe7aBFqi9F4
222
222
  modal_proto/task_command_router_pb2.pyi,sha256=5xfhnwtTDTmJo1Nv0tPBJrYzb0aeilY2Lm92wWT_6yw,46211
223
223
  modal_proto/task_command_router_pb2_grpc.py,sha256=zuFkJgKcswB2ftjnyEgs70dp61VMA7gK0h0uzR3gYFw,42563
224
224
  modal_proto/task_command_router_pb2_grpc.pyi,sha256=UjAJFqz9DpOFXP04fVm5lB2eAyTtjOg3oKjfWei8yLU,14262
225
- modal_version/__init__.py,sha256=PMubULAc9RsJXD2OLFx25k27r8fIO_7lDPzSzmC_LiA,121
225
+ modal_version/__init__.py,sha256=8N1BZO1FEHjeAjxwfHhTTyzsw6XyXmVP_PzkavBaZhk,121
226
226
  modal_version/__main__.py,sha256=nLUbubxKx7GXNzJIkTB7M7_u8080LyLM0IS0rzFkC_c,119
227
- modal-1.5.4.dev16.dist-info/METADATA,sha256=tjYNLLJb41XAl9qtI0f-3Xmh1V9Aof1HqMyenfoar7o,2513
228
- modal-1.5.4.dev16.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
229
- modal-1.5.4.dev16.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
230
- modal-1.5.4.dev16.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
231
- modal-1.5.4.dev16.dist-info/RECORD,,
227
+ modal-1.5.4.dev17.dist-info/METADATA,sha256=4M26dn3GuguyAwhi5WYZZNuPQF6BPH_dcaVoYibbnXM,2513
228
+ modal-1.5.4.dev17.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
229
+ modal-1.5.4.dev17.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
230
+ modal-1.5.4.dev17.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
231
+ modal-1.5.4.dev17.dist-info/RECORD,,