modAL 1.3.2__py3-none-any.whl → 1.3.2.dev0__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/_object.py CHANGED
@@ -39,41 +39,6 @@ def _get_environment_name(
39
39
  return config.get("environment")
40
40
 
41
41
 
42
- def live_method(method):
43
- @wraps(method)
44
- async def wrapped(self, *args, **kwargs):
45
- await self.hydrate()
46
- return await method(self, *args, **kwargs)
47
-
48
- return wrapped
49
-
50
-
51
- def live_method_gen(method):
52
- @wraps(method)
53
- async def wrapped(self, *args, **kwargs):
54
- await self.hydrate()
55
- async with aclosing(method(self, *args, **kwargs)) as stream:
56
- async for item in stream:
57
- yield item
58
-
59
- return wrapped
60
-
61
-
62
- def live_method_contextmanager(method):
63
- # make sure a wrapped function returning an async context manager
64
- # will not require both an `await func.aio()` and `async with`
65
- # which would have been the case if it was wrapped in live_method
66
-
67
- @wraps(method)
68
- @contextlib.asynccontextmanager
69
- async def wrapped(self, *args, **kwargs):
70
- await self.hydrate()
71
- async with method(self, *args, **kwargs) as ctx:
72
- yield ctx
73
-
74
- return wrapped
75
-
76
-
77
42
  class _Object:
78
43
  _type_prefix: ClassVar[Optional[str]] = None
79
44
  _prefix_to_type: ClassVar[dict[str, type]] = {}
@@ -310,11 +275,6 @@ class _Object:
310
275
  raise AttributeError(f"Attempting to get object_id of unhydrated {self}")
311
276
  return self._object_id
312
277
 
313
- @live_method
314
- async def get_dashboard_url(self) -> str:
315
- """mdmd:hidden"""
316
- return f"https://modal.com/id/{self.object_id}"
317
-
318
278
  @property
319
279
  def client(self) -> _Client:
320
280
  """mdmd:hidden"""
@@ -376,3 +336,38 @@ class _Object:
376
336
  with suppress_tb_frame(): # skip this frame by default
377
337
  await resolver.load(self, root_load_context)
378
338
  return self
339
+
340
+
341
+ def live_method(method):
342
+ @wraps(method)
343
+ async def wrapped(self, *args, **kwargs):
344
+ await self.hydrate()
345
+ return await method(self, *args, **kwargs)
346
+
347
+ return wrapped
348
+
349
+
350
+ def live_method_gen(method):
351
+ @wraps(method)
352
+ async def wrapped(self, *args, **kwargs):
353
+ await self.hydrate()
354
+ async with aclosing(method(self, *args, **kwargs)) as stream:
355
+ async for item in stream:
356
+ yield item
357
+
358
+ return wrapped
359
+
360
+
361
+ def live_method_contextmanager(method):
362
+ # make sure a wrapped function returning an async context manager
363
+ # will not require both an `await func.aio()` and `async with`
364
+ # which would have been the case if it was wrapped in live_method
365
+
366
+ @wraps(method)
367
+ @contextlib.asynccontextmanager
368
+ async def wrapped(self, *args, **kwargs):
369
+ await self.hydrate()
370
+ async with method(self, *args, **kwargs) as ctx:
371
+ yield ctx
372
+
373
+ return wrapped
modal/_output.py CHANGED
@@ -545,7 +545,7 @@ async def get_app_logs_loop(
545
545
  output_mgr: OutputManager,
546
546
  app_id: str | None = None,
547
547
  task_id: str | None = None,
548
- sandbox_id: str | None = None,
548
+ app_logs_url: str | None = None,
549
549
  ):
550
550
  last_log_batch_entry_id = ""
551
551
 
@@ -600,7 +600,6 @@ async def get_app_logs_loop(
600
600
  request = api_pb2.AppGetLogsRequest(
601
601
  app_id=app_id or "",
602
602
  task_id=task_id or "",
603
- sandbox_id=sandbox_id or "",
604
603
  timeout=55,
605
604
  last_entry_id=last_log_batch_entry_id,
606
605
  )
modal/cli/app.py CHANGED
@@ -10,9 +10,7 @@ from rich.text import Text
10
10
  from typer import Argument
11
11
 
12
12
  from modal._object import _get_environment_name
13
- from modal._output import make_console
14
13
  from modal._utils.async_utils import synchronizer
15
- from modal._utils.browser_utils import open_url_and_display
16
14
  from modal.client import _Client
17
15
  from modal.environments import ensure_env
18
16
  from modal_proto import api_pb2
@@ -250,35 +248,3 @@ async def history(
250
248
 
251
249
  if deployments_with_dirty_commit and not json:
252
250
  rich.print("* - repo had uncommitted changes")
253
-
254
-
255
- @app_cli.command("dashboard", no_args_is_help=True)
256
- @synchronizer.create_blocking
257
- async def dashboard(
258
- app_identifier: str = APP_IDENTIFIER,
259
- *,
260
- env: Optional[str] = ENV_OPTION,
261
- ):
262
- """Open an App's dashboard page in your web browser.
263
-
264
- **Examples:**
265
-
266
- Open dashboard for an app by name:
267
-
268
- ```
269
- modal app dashboard my-app
270
- ```
271
-
272
- Use a specified environment:
273
-
274
- ```
275
- modal app dashboard my-app --env dev
276
- ```
277
- """
278
- client = await _Client.from_env()
279
- app_id = await get_app_id.aio(app_identifier, env, client)
280
-
281
- console = make_console()
282
- url = f"https://modal.com/id/{app_id}"
283
-
284
- open_url_and_display(url, "App dashboard", console)
modal/cli/container.py CHANGED
@@ -13,7 +13,6 @@ from modal.client import _Client
13
13
  from modal.config import config
14
14
  from modal.container_process import _ContainerProcess
15
15
  from modal.environments import ensure_env
16
- from modal.exception import InvalidError
17
16
  from modal.stream_type import StreamType
18
17
  from modal_proto import api_pb2
19
18
 
@@ -53,14 +52,7 @@ def logs(
53
52
  timestamps: bool = typer.Option(False, "--timestamps", help="Show timestamps for each log line"),
54
53
  ):
55
54
  """Show logs for a specific container, streaming while active."""
56
- task_id, sandbox_id = None, None
57
- if container_id.startswith("sb-"):
58
- sandbox_id = container_id
59
- elif container_id.startswith("ta-"):
60
- task_id = container_id
61
- else:
62
- raise InvalidError(f"Invalid container ID: {container_id}")
63
- stream_app_logs(task_id=task_id, sandbox_id=sandbox_id, show_timestamps=timestamps)
55
+ stream_app_logs(task_id=container_id, show_timestamps=timestamps)
64
56
 
65
57
 
66
58
  @container_cli.command("exec")
modal/cli/entry_point.py CHANGED
@@ -13,7 +13,6 @@ from .app import app_cli
13
13
  from .cluster import cluster_cli
14
14
  from .config import config_cli
15
15
  from .container import container_cli
16
- from .dashboard import dashboard
17
16
  from .dict import dict_cli
18
17
  from .environment import environment_cli
19
18
  from .launch import launch_cli
@@ -119,7 +118,6 @@ async def setup(profile: Optional[str] = None):
119
118
  entrypoint_cli_typer.command("deploy", no_args_is_help=True)(run.deploy)
120
119
  entrypoint_cli_typer.command("serve", no_args_is_help=True)(run.serve)
121
120
  entrypoint_cli_typer.command("shell")(shell_module.shell)
122
- entrypoint_cli_typer.command("dashboard")(dashboard)
123
121
  entrypoint_cli_typer.add_typer(launch_cli)
124
122
 
125
123
  # Deployments
modal/cli/utils.py CHANGED
@@ -21,16 +21,14 @@ from ..exception import NotFoundError
21
21
  async def stream_app_logs(
22
22
  app_id: Optional[str] = None,
23
23
  task_id: Optional[str] = None,
24
- sandbox_id: Optional[str] = None,
25
24
  app_logs_url: Optional[str] = None,
26
25
  show_timestamps: bool = False,
27
26
  ):
28
27
  client = await _Client.from_env()
29
- display_id = app_id or task_id or sandbox_id
30
- output_mgr = OutputManager(status_spinner_text=f"Tailing logs for {display_id}", show_timestamps=show_timestamps)
28
+ output_mgr = OutputManager(status_spinner_text=f"Tailing logs for {app_id}", show_timestamps=show_timestamps)
31
29
  try:
32
30
  with output_mgr.show_status_spinner():
33
- await get_app_logs_loop(client, output_mgr, app_id=app_id, task_id=task_id, sandbox_id=sandbox_id)
31
+ await get_app_logs_loop(client, output_mgr, app_id=app_id, task_id=task_id, app_logs_url=app_logs_url)
34
32
  except asyncio.CancelledError:
35
33
  pass
36
34
  except KeyboardInterrupt:
modal/cli/volume.py CHANGED
@@ -12,7 +12,6 @@ from typer import Argument, Option, Typer
12
12
  import modal
13
13
  from modal._output import OutputManager, ProgressHandler, make_console
14
14
  from modal._utils.async_utils import synchronizer
15
- from modal._utils.browser_utils import open_url_and_display
16
15
  from modal._utils.time_utils import timestamp_to_localized_str
17
16
  from modal.cli._download import _volume_download
18
17
  from modal.cli.utils import ENV_OPTION, YES_OPTION, display_table
@@ -311,30 +310,3 @@ async def rename(
311
310
  )
312
311
 
313
312
  await _Volume.rename(old_name, new_name, environment_name=env)
314
-
315
-
316
- @volume_cli.command(
317
- name="dashboard",
318
- help="Open the Volume's dashboard page in your web browser.",
319
- rich_help_panel="Management",
320
- )
321
- @synchronizer.create_blocking
322
- async def dashboard(
323
- volume_name: str = Argument(help="Name of the Volume to view in the dashboard."),
324
- env: Optional[str] = ENV_OPTION,
325
- ):
326
- """Open a Volume's dashboard page in your web browser.
327
-
328
- **Example:**
329
-
330
- ```
331
- modal volume dashboard my-volume
332
- ```
333
- """
334
- env = ensure_env(env)
335
- volume = await _Volume.from_name(volume_name, environment_name=env).hydrate()
336
-
337
- console = make_console()
338
- url = f"https://modal.com/id/{volume.object_id}"
339
-
340
- open_url_and_display(url, "Volume dashboard", console)
modal/client.pyi CHANGED
@@ -31,7 +31,11 @@ class _Client:
31
31
  client_type: int
32
32
 
33
33
  def __init__(
34
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "1.3.2"
34
+ self,
35
+ server_url: str,
36
+ client_type: int,
37
+ credentials: typing.Optional[tuple[str, str]],
38
+ version: str = "1.3.2.dev0",
35
39
  ):
36
40
  """mdmd:hidden
37
41
  The Modal client object is not intended to be instantiated directly by users.
@@ -163,7 +167,11 @@ class Client:
163
167
  client_type: int
164
168
 
165
169
  def __init__(
166
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "1.3.2"
170
+ self,
171
+ server_url: str,
172
+ client_type: int,
173
+ credentials: typing.Optional[tuple[str, str]],
174
+ version: str = "1.3.2.dev0",
167
175
  ):
168
176
  """mdmd:hidden
169
177
  The Modal client object is not intended to be instantiated directly by users.
modal/functions.pyi CHANGED
@@ -408,7 +408,7 @@ class Function(
408
408
 
409
409
  _call_generator: ___call_generator_spec
410
410
 
411
- class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
411
+ class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
412
412
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
413
413
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
414
414
  ...
@@ -417,7 +417,7 @@ class Function(
417
417
  """Calls the function remotely, executing it with the given arguments and returning the execution's result."""
418
418
  ...
419
419
 
420
- remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
420
+ remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
421
421
 
422
422
  class __remote_gen_spec(typing_extensions.Protocol):
423
423
  def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
@@ -444,7 +444,7 @@ class Function(
444
444
  """
445
445
  ...
446
446
 
447
- class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
447
+ class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
448
448
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
449
449
  """[Experimental] Calls the function with the given arguments, without waiting for the results.
450
450
 
@@ -467,7 +467,7 @@ class Function(
467
467
  """
468
468
  ...
469
469
 
470
- _experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
470
+ _experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
471
471
 
472
472
  class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
473
473
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
@@ -475,7 +475,7 @@ class Function(
475
475
 
476
476
  _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
477
477
 
478
- class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
478
+ class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
479
479
  def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
480
480
  """Calls the function with the given arguments, without waiting for the results.
481
481
 
@@ -496,7 +496,7 @@ class Function(
496
496
  """
497
497
  ...
498
498
 
499
- spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
499
+ spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
500
500
 
501
501
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
502
502
  """Return the inner Python object wrapped by this Modal Function."""
modal/object.pyi CHANGED
@@ -231,17 +231,6 @@ class Object:
231
231
  """mdmd:hidden"""
232
232
  ...
233
233
 
234
- class __get_dashboard_url_spec(typing_extensions.Protocol):
235
- def __call__(self, /) -> str:
236
- """mdmd:hidden"""
237
- ...
238
-
239
- async def aio(self, /) -> str:
240
- """mdmd:hidden"""
241
- ...
242
-
243
- get_dashboard_url: __get_dashboard_url_spec
244
-
245
234
  @property
246
235
  def client(self) -> modal.client.Client:
247
236
  """mdmd:hidden"""
modal/runner.py CHANGED
@@ -340,7 +340,11 @@ async def _run_app(
340
340
 
341
341
  # Start logs loop
342
342
 
343
- logs_loop = tc.create_task(get_app_logs_loop(load_context.client, output_mgr, app_id=running_app.app_id))
343
+ logs_loop = tc.create_task(
344
+ get_app_logs_loop(
345
+ load_context.client, output_mgr, app_id=running_app.app_id, app_logs_url=running_app.app_logs_url
346
+ )
347
+ )
344
348
 
345
349
  try:
346
350
  # Create all members
modal/token_flow.py CHANGED
@@ -1,6 +1,7 @@
1
1
  # Copyright Modal Labs 2023
2
2
  import itertools
3
3
  import os
4
+ import webbrowser
4
5
  from collections.abc import AsyncGenerator
5
6
  from typing import Optional
6
7
 
@@ -11,7 +12,6 @@ from modal_proto import api_pb2
11
12
 
12
13
  from ._output import make_console
13
14
  from ._utils.async_utils import synchronize_api
14
- from ._utils.browser_utils import open_url
15
15
  from ._utils.http_utils import run_temporary_http_server
16
16
  from .client import _Client
17
17
  from .config import DEFAULT_SERVER_URL, _lookup_workspace, _store_user_config, config, config_profiles, user_config_path
@@ -85,7 +85,7 @@ async def _new_token(
85
85
  async with token_flow.start(source, next_url) as (_, web_url, code):
86
86
  with console.status("Waiting for authentication in the web browser", spinner="dots"):
87
87
  # Open the web url in the browser
88
- if open_url(web_url):
88
+ if _open_url(web_url):
89
89
  console.print(
90
90
  "The web browser should have opened for you to authenticate and get an API token.\n"
91
91
  "If it didn't, please copy this URL into your web browser manually:\n"
@@ -176,3 +176,18 @@ async def _set_token(
176
176
  f"Warning: The {env_vars_str} environment variable{s} {verb} set; this will override your new credentials.",
177
177
  style="yellow",
178
178
  )
179
+
180
+
181
+ def _open_url(url: str) -> bool:
182
+ """Opens url in web browser, making sure we use a modern one (not Lynx etc)"""
183
+ if "PYTEST_CURRENT_TEST" in os.environ:
184
+ return False
185
+ try:
186
+ browser = webbrowser.get()
187
+ # zpresto defines `BROWSER=open` by default on macOS, which causes `webbrowser` to return `GenericBrowser`.
188
+ if isinstance(browser, webbrowser.GenericBrowser) and browser.name != "open":
189
+ return False
190
+ else:
191
+ return browser.open_new_tab(url)
192
+ except webbrowser.Error:
193
+ return False
modal/token_flow.pyi CHANGED
@@ -71,3 +71,6 @@ async def _set_token(
71
71
  verify: bool = True,
72
72
  server_url: typing.Optional[str] = None,
73
73
  ): ...
74
+ def _open_url(url: str) -> bool:
75
+ """Opens url in web browser, making sure we use a modern one (not Lynx etc)"""
76
+ ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.3.2
3
+ Version: 1.3.2.dev0
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -9,8 +9,8 @@ modal/_grpc_client.py,sha256=G8gWQXChtsuRgyXK9kcPiPNYXOYbl_m9Bz2AVBJb-zs,6924
9
9
  modal/_ipython.py,sha256=Bu9fc3hm3xt2O47qLe_d-Mu2jS81LwMsmXNJ1sawBA0,575
10
10
  modal/_load_context.py,sha256=DvfOWNTevEmHqdlu0-AeO_03JChrmAjoupgppPVW2Pc,4867
11
11
  modal/_location.py,sha256=joiX-0ZeutEUDTrrqLF1GHXCdVLF-rHzstocbMcd_-k,366
12
- modal/_object.py,sha256=144YrNnTG77vK_PAHRU9GFxHBOlt2PWFgTUXpgX4BQk,14315
13
- modal/_output.py,sha256=WZ5wJ_Zty9353KSUviPlE8cbEVE8BMmiWN34X8b_PD4,26933
12
+ modal/_object.py,sha256=eMkfvGiVtdYxIuqhOStsmzCgKqt9nKO1paiSR97TlL0,14169
13
+ modal/_output.py,sha256=z7cLrcf0Cu7c697SVTxl4uPsg9yVK2Q4zsIfV9NkcYY,26894
14
14
  modal/_partial_function.py,sha256=6HsV3xqwzmaTgytZ-CL5sNKIttxNjVQv_QgUF-sR20E,37489
15
15
  modal/_pty.py,sha256=E58MQ8d5-wkbMatRKpQR-G9FdbCRcZGiZxOpGy__VuY,1481
16
16
  modal/_resolver.py,sha256=r8MuiDIVcMekZUZHMtNZQbR4tQCxf-riyeaEvl9IZDk,7566
@@ -27,7 +27,7 @@ modal/app.pyi,sha256=DY4kQP_hcy1JdYCn13xJwT-LxPqy_XRzMOgIFYvmjgM,56025
27
27
  modal/billing.py,sha256=zmQ3bcCJlwa4KD1IA_QgdWpm1pn13c-7qfy79iEauYI,195
28
28
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
29
29
  modal/client.py,sha256=-IxazxLhdkNFAHS2AP2FpyTVpCDVR58RF6ecSVV59r0,14862
30
- modal/client.pyi,sha256=ARvxSHaYTF303OAGSMOLhZGrV_F-d2qnCW9x0PCyO2c,14854
30
+ modal/client.pyi,sha256=6GizOUY3ExH_VqTUB1Npt7ZcIbsi5n3mu5kbQFZkYCQ,14930
31
31
  modal/cloud_bucket_mount.py,sha256=cvVj5Rt4nDHoQbTneoJPTaAcnl_Ab_mrsjnnzd0v9OI,6013
32
32
  modal/cloud_bucket_mount.pyi,sha256=vXusGMOUk9HjCs4lhxteuCK4xLQclPfugGWKo7LECEA,7539
33
33
  modal/cls.py,sha256=ozx5ZVGyG6w5SQ1ouj9Y6M3yPtnpL9PfblnmqFzf694,42338
@@ -44,7 +44,7 @@ modal/file_io.py,sha256=dx90C5L8cQv2Z7pVVPaQmE0R3pUOGv2h-wn1qNNXbGQ,19818
44
44
  modal/file_io.pyi,sha256=up9OhV2Y54n-X7nlfV6j_eBwJ8D2cNMEswZ1iddrEQw,15877
45
45
  modal/file_pattern_matcher.py,sha256=A_Kdkej6q7YQyhM_2-BvpFmPqJ0oHb54B6yf9VqvPVE,8116
46
46
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
47
- modal/functions.pyi,sha256=jnC5QZvfs_yPPwXmEoHO16xUXzX448aP6eWawVmeGko,36498
47
+ modal/functions.pyi,sha256=mwwTcswVuCRQeVJhqiBHCbVqKieOKH3z_cIca1NIQBk,36498
48
48
  modal/gpu.py,sha256=Fe5ORvVPDIstSq1xjmM6OoNgLYFWvogP9r5BgmD3hYg,6769
49
49
  modal/image.py,sha256=JccGnn1Aog2Kk09XpQ__22f4LjoAZRXLXK6-B27s3Hg,109233
50
50
  modal/image.pyi,sha256=x8a6gohK9XD35z8MejOmKHauOnI7JwbQcZhp3bVfB5I,78383
@@ -55,7 +55,7 @@ modal/mount.pyi,sha256=HVNPL8po23Hulaj7Kdl5goakZbirN0ADv2nkLc8Hpn4,15748
55
55
  modal/network_file_system.py,sha256=23GUYz2DZ5kCzlUrdWBq1siBse6fP_CeGt2Lo9xHkR8,13598
56
56
  modal/network_file_system.pyi,sha256=oRQzPxSF3ZmY8BDtBFU3CCyGwPLl5jkobtN6ekexLog,16161
57
57
  modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
58
- modal/object.pyi,sha256=vfWPMie8HyL_Lb6Npb6XNXVJdc9_utzfumV5Zm8UHok,10372
58
+ modal/object.pyi,sha256=IiWqkhIVNryH9mbpOpZiG21W9UWW5T7l8gf98J3fVIk,10088
59
59
  modal/output.py,sha256=ga4glXYUbUKdlj_R3Ra2AlxqCEJjhYORR90spJrrqTs,2032
60
60
  modal/parallel_map.py,sha256=VAfhkgCKFXtpba01Dvq7kc-xg5nlP-AdvmJW0LoyfD8,68670
61
61
  modal/parallel_map.pyi,sha256=CPX8c8sxCGjrMGFYdm6u8x28b9T2UnW96O2dRbiqWPI,15426
@@ -67,7 +67,7 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
67
  modal/queue.py,sha256=Ec8Mk2TVXSiHWLYNWyvZ-y8VAZdYqCxnJZNjwdwmKvo,25954
68
68
  modal/queue.pyi,sha256=D8LSNrjI75ztWlg4x4Qy2DfsKF0U9d040ZMjJuGLMzE,38627
69
69
  modal/retries.py,sha256=IvNLDM0f_GLUDD5VgEDoN09C88yoxSrCquinAuxT1Sc,5205
70
- modal/runner.py,sha256=gNy0UtUiMc7QdOJtCM_menHNtOGdHJV3GLWcZswrnxg,26715
70
+ modal/runner.py,sha256=9U_2QtnkqJ95jk5v73vorULRDWyb0zIePAY9a1-NF4Q,26822
71
71
  modal/runner.pyi,sha256=kQRO3oWA_Icjdm87sgeUV6Fa6rVPWfCYi99POj_2i4Q,8860
72
72
  modal/running_app.py,sha256=v61mapYNV1-O-Uaho5EfJlryMLvIT9We0amUOSvSGx8,1188
73
73
  modal/sandbox.py,sha256=EsNapk12bXXnM5hFtkYaqBo4mcxWSBLxwpkwXLNiYPk,51228
@@ -83,8 +83,8 @@ modal/serving.pyi,sha256=eNqF_bhO_JQ0EDpqvSjSUdNs48vv7AcPXinp7GEs5wI,1966
83
83
  modal/snapshot.py,sha256=vIKxA1XRRsH8cFcpSUqC9M8NccKIaYaDpmiEC2clNks,2297
84
84
  modal/snapshot.pyi,sha256=vMYDx1s9Ds4qtH-PXgB_9RzVuS5wsTchVcclR5Q-mmM,2014
85
85
  modal/stream_type.py,sha256=A6320qoAAWhEfwOCZfGtymQTu5AfLfJXXgARqooTPvY,417
86
- modal/token_flow.py,sha256=J8Mx1ys6IRzAw7aQfbmrG_cNZuFBfETYWLMl-iRJHMo,7087
87
- modal/token_flow.pyi,sha256=5zdXJ5SLLHM4j6xSPuEvnpSeEJBbzE6NkSX-MSyE5wM,2282
86
+ modal/token_flow.py,sha256=tLvBE9OT50p8AnYYh4b5MvBMQc1vV1-6C0GsmyFDfxw,7626
87
+ modal/token_flow.pyi,sha256=xxMmxKU2_Z8aLhQazqhnBng8PVPKaPgZXKnUuS5WykI,2406
88
88
  modal/volume.py,sha256=vej3tMfs0ayarcp2Y3wsDnStJdnQ6u2U8VKYQi7YTn8,52733
89
89
  modal/volume.pyi,sha256=I0-tL9d87MsS0MarB07IqYnX4X2bNpBfmp0yvJKFKA8,53915
90
90
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
@@ -102,7 +102,6 @@ modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
102
102
  modal/_utils/async_utils.py,sha256=TO0t6JxI9nVEewwBlpksH-IAbUGyCAGoO5gkXXk_e9E,44919
103
103
  modal/_utils/auth_token_manager.py,sha256=QsDokl1c1dN9m6Z9N-Se-8cY3laphByjJtNdRXUTieI,5151
104
104
  modal/_utils/blob_utils.py,sha256=LIWNN7w0ma5IG1rP3gaOrn6YKcGTXMbI1_rSpJay8pY,23147
105
- modal/_utils/browser_utils.py,sha256=kxPf3rvx1bgS3HiGoDeFO0szBidbhqZijqlL31TTh1Q,1069
106
105
  modal/_utils/bytes_io_segment_payload.py,sha256=vaXPq8b52-x6G2hwE7SrjS58pg_aRm7gV3bn3yjmTzQ,4261
107
106
  modal/_utils/deprecation.py,sha256=-Bgg7jZdcJU8lROy18YyVnQYbM8hue-hVmwJqlWAGH0,5504
108
107
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
@@ -137,13 +136,12 @@ modal/builder/base-images.json,sha256=9zgY2-a2U_iEBBe60VNLQvErJQosRhQuXXRqcG6mHG
137
136
  modal/cli/__init__.py,sha256=6FRleWQxBDT19y7OayO4lBOzuL6Bs9r0rLINYYYbHwQ,769
138
137
  modal/cli/_download.py,sha256=_Q_CG1Qb4cjVSAwHGGPOPoNTsmK9gHvF-HNWCNdFjaY,4900
139
138
  modal/cli/_traceback.py,sha256=EqsLTVtnrAgo9b7vVDr5TV_bAGP30VTLfcoDOAcrNLI,7363
140
- modal/cli/app.py,sha256=xsoztDQSQE7RuMvy0_60Zdt1EglibvW31OX2Ti7WWdQ,8620
139
+ modal/cli/app.py,sha256=rbuAG92my-1eZN0olk6p2eD4oBnyBliUsrCOUW-U-9k,7832
141
140
  modal/cli/cluster.py,sha256=BLcKDpwpDmlqE2UC4V0qNpJKiQ-ZXfI9g_SE7u6vnIU,3347
142
141
  modal/cli/config.py,sha256=7xgglsSf5pKfE7ZLz-uZf9S11NBuNbUkUbcZ5nFk8Y0,1721
143
- modal/cli/container.py,sha256=ikjmiqMK7aRh5aeAH6pyuKJvCZzG6qKrfFDASaIhuvQ,4142
144
- modal/cli/dashboard.py,sha256=RIlv-Q6K8a49h1MK-XOrJmPT_1A1SDhHjtAohQ6c8wY,940
142
+ modal/cli/container.py,sha256=nIz8GS39lU2F2e3tt2rZfQmMxHObjT8-78kzzGjpO88,3823
145
143
  modal/cli/dict.py,sha256=Cp4sovXCsdJWWik_irhc7fG-H5_ZMjYYYCObiyyMueE,4760
146
- modal/cli/entry_point.py,sha256=Htl0zxd1WjgTqK2k8jvxCajRhfPfRnFAo9zURVx67Sc,5902
144
+ modal/cli/entry_point.py,sha256=aaofRsA9c4s68CVbXehzmLilJWLBUL2DXLh--lTVYRQ,5816
147
145
  modal/cli/environment.py,sha256=AKgtjzFkTxAOlWAZC6uHsZro_y2jfeugL0r8bXHw4Ic,3904
148
146
  modal/cli/import_refs.py,sha256=w5jYnqqVcJB_5FPgh6zAO6w77uDefoqFmhoQz3m1fNY,14029
149
147
  modal/cli/launch.py,sha256=1inePjuiqV3HHwk0H-Lk-UAxhkoodCwFoRswD_dat2U,3840
@@ -154,8 +152,8 @@ modal/cli/run.py,sha256=RMQnTGL42CrpTn8YPK5wXRUrngDImNLt4BT7jqTI9gY,21340
154
152
  modal/cli/secret.py,sha256=zkCztov8c4x8CI8G0EoyieUfv9XLQQtVXV8xeMLK-Os,8044
155
153
  modal/cli/shell.py,sha256=L5Dw8yeuu9-f6vNlBGbUT4oh9AVSK4GuB5J6m6vYLBk,12613
156
154
  modal/cli/token.py,sha256=BC-bHqhv39tsO8azlHzGu4Iu4glC8fPdYTrAN-NQHeI,4104
157
- modal/cli/utils.py,sha256=L1098G6QWlVFzzeU5M0Y7GaHl-FQgxDJbSqNiCvOynU,2966
158
- modal/cli/volume.py,sha256=wvv3WolrwoJuDgHzqC9OiI-M_6aCqqCkk5STFQPmpLE,11286
155
+ modal/cli/utils.py,sha256=d7J4j29b6bsj2GqYe3QdqgHpO-QkxcjtF9YnRCYxVIg,2879
156
+ modal/cli/volume.py,sha256=8_wjfaFmtcPrIYx46__CbCefaSLPJ14nlm6iCLz_HOA,10512
159
157
  modal/cli/programs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
160
158
  modal/cli/programs/run_jupyter.py,sha256=IJw8nds8Cjl9j4dxBqMGxhz-bIyVX0kle7jbt8HFOhM,2688
161
159
  modal/cli/programs/vscode.py,sha256=E1aJPU7b8RWWj-JX71DifsCoLYsCAnre7lATiBJjUms,3386
@@ -163,7 +161,7 @@ modal/experimental/__init__.py,sha256=VqLPIyuwasUMab3t2T5jEcONz_p_iUIqXzHRAjxmOv
163
161
  modal/experimental/flash.py,sha256=cP7gnWo7460GG-WS3p_N5L6-dD7HABLTfuyn_w-Aa7g,33109
164
162
  modal/experimental/flash.pyi,sha256=xSxFesFVuhIOX2Cz2h1wD4NVk_PsrlZ7SsVU-SKfPsY,16960
165
163
  modal/experimental/ipython.py,sha256=TrCfmol9LGsRZMeDoeMPx3Hv3BFqQhYnmD_iH0pqdhk,2904
166
- modal-1.3.2.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
164
+ modal-1.3.2.dev0.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
167
165
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
168
166
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
169
167
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -171,13 +169,13 @@ modal_docs/mdmd/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,2
171
169
  modal_docs/mdmd/mdmd.py,sha256=tUTImNd4UMFk1opkaw8J672gX8AkBO5gbY2S_NMxsxs,7140
172
170
  modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
173
171
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
174
- modal_proto/api.proto,sha256=ULD5PMs_dXnAp02dQ1EbV632iZdtb5e1jEVAhaK2FB4,112863
175
- modal_proto/api_grpc.py,sha256=9OBPRHwXObCImeu4lyADWY6N1huZvatErjxuq8Isd6I,136048
176
- modal_proto/api_pb2.py,sha256=SAjQ6NXCX7fk3E7h7ec1A64FXqxeafAyRnugcEX2VlU,390660
177
- modal_proto/api_pb2.pyi,sha256=sbyiDGU73ynzYVFJoSm57mh642yyPIh_UAPCkOvZ56E,552115
178
- modal_proto/api_pb2_grpc.py,sha256=f-D7P3ccYCOb7znGj0sJQ4e_b97VKY3lPUPnxkQznfw,293118
179
- modal_proto/api_pb2_grpc.pyi,sha256=avhkF4okJVvkWAxx48fS4KvotH_mGLYLPNPn_QgbKKc,68566
180
- modal_proto/modal_api_grpc.py,sha256=XwBL09RMGODaz7xsG6rWVi0WFmP0n7rU5RbMlQt8mWM,21543
172
+ modal_proto/api.proto,sha256=NADWZjZZT35ZmBuU6IcknPr8vDYY3TANYrK5c08xINY,112626
173
+ modal_proto/api_grpc.py,sha256=ozNudkNLbPLp2bFm0bJtb0FHK9ACvJXXnGy771noCKc,135188
174
+ modal_proto/api_pb2.py,sha256=3_sz9e3HKvYeB-DUlMgU0-ilQx2CKzUQKmiv5VvXyn8,389234
175
+ modal_proto/api_pb2.pyi,sha256=9myEquz8BuFIa34WoSiPut3LZO1ztvuN2_vrZ5TJimA,551169
176
+ modal_proto/api_pb2_grpc.py,sha256=hHdfvfbS6HELZXTmHNfxlgPxFRDSc2B81G8YRtLwuHM,291347
177
+ modal_proto/api_pb2_grpc.pyi,sha256=cqpXpAVrLoMQMCCyzyW5oXSFKmUPC9Y2wkTOpwNeAGM,68141
178
+ modal_proto/modal_api_grpc.py,sha256=ls_o6oVYm8iup0nbKGPqs-CcJZJrry0eIY51mQFJRUc,21407
181
179
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
182
180
  modal_proto/task_command_router.proto,sha256=oyHT02Ck7jrBe55s4ge5f2ko58-2sg3gZ-xEvvn5bXU,5620
183
181
  modal_proto/task_command_router_grpc.py,sha256=_K9lOLOB_pyT8-XvGnicgAIW1aLVFTqQISmP7Q1x4e8,6962
@@ -185,10 +183,10 @@ modal_proto/task_command_router_pb2.py,sha256=2Y8wRvnq4_7RiQ-5ZAPIgXaxrHv_MXzgS5
185
183
  modal_proto/task_command_router_pb2.pyi,sha256=yI4tFteErLlonFA2HyaWtONfhY_VGSe7KCWFIspvmkE,16323
186
184
  modal_proto/task_command_router_pb2_grpc.py,sha256=q2VWfK2-4uDcPaPLhAqPZkgxhuQRYnWmwUcnEbPbGuk,13895
187
185
  modal_proto/task_command_router_pb2_grpc.pyi,sha256=e1MM10VGUgDkm041v53QeTglGQPzTpA0FUsFtezjp74,4536
188
- modal_version/__init__.py,sha256=B-iUoQRH5-b6pyxr9QXBOolBt9NJOdZRU6FNewiIJTA,115
186
+ modal_version/__init__.py,sha256=7ZN0cUZWX2rCUQGzQhgw_T5UtCM5BZh0B8hGd6dnvtI,120
189
187
  modal_version/__main__.py,sha256=nLUbubxKx7GXNzJIkTB7M7_u8080LyLM0IS0rzFkC_c,119
190
- modal-1.3.2.dist-info/METADATA,sha256=kcMhN3ey3jU66Sk9PvC0y6zy6pknkCkLtCjsh2M6np4,2576
191
- modal-1.3.2.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
192
- modal-1.3.2.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
193
- modal-1.3.2.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
194
- modal-1.3.2.dist-info/RECORD,,
188
+ modal-1.3.2.dev0.dist-info/METADATA,sha256=vtxp8JUyAFrZhNP4SKAdLCs6HIeIIFTM_KA5iVIZRhU,2581
189
+ modal-1.3.2.dev0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
190
+ modal-1.3.2.dev0.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
191
+ modal-1.3.2.dev0.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
192
+ modal-1.3.2.dev0.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -3690,15 +3690,6 @@ message WorkspaceBillingReportRequest {
3690
3690
  repeated string tag_names = 4;
3691
3691
  }
3692
3692
 
3693
- message WorkspaceDashboardUrlRequest {
3694
- string environment_name = 1;
3695
- }
3696
-
3697
- message WorkspaceDashboardUrlResponse {
3698
- string url = 1;
3699
- }
3700
-
3701
-
3702
3693
  message WorkspaceNameLookupResponse {
3703
3694
  string workspace_name = 1 [deprecated=true];
3704
3695
  string username = 2;
@@ -3933,6 +3924,5 @@ service ModalClient {
3933
3924
 
3934
3925
  // Workspaces
3935
3926
  rpc WorkspaceBillingReport(WorkspaceBillingReportRequest) returns (stream WorkspaceBillingReportItem);
3936
- rpc WorkspaceDashboardUrlGet(WorkspaceDashboardUrlRequest) returns (WorkspaceDashboardUrlResponse);
3937
3927
  rpc WorkspaceNameLookup(google.protobuf.Empty) returns (WorkspaceNameLookupResponse);
3938
3928
  }
modal_proto/api_grpc.py CHANGED
@@ -715,10 +715,6 @@ class ModalClientBase(abc.ABC):
715
715
  async def WorkspaceBillingReport(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.WorkspaceBillingReportRequest, modal_proto.api_pb2.WorkspaceBillingReportItem]') -> None:
716
716
  pass
717
717
 
718
- @abc.abstractmethod
719
- async def WorkspaceDashboardUrlGet(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.WorkspaceDashboardUrlRequest, modal_proto.api_pb2.WorkspaceDashboardUrlResponse]') -> None:
720
- pass
721
-
722
718
  @abc.abstractmethod
723
719
  async def WorkspaceNameLookup(self, stream: 'grpclib.server.Stream[google.protobuf.empty_pb2.Empty, modal_proto.api_pb2.WorkspaceNameLookupResponse]') -> None:
724
720
  pass
@@ -1769,12 +1765,6 @@ class ModalClientBase(abc.ABC):
1769
1765
  modal_proto.api_pb2.WorkspaceBillingReportRequest,
1770
1766
  modal_proto.api_pb2.WorkspaceBillingReportItem,
1771
1767
  ),
1772
- '/modal.client.ModalClient/WorkspaceDashboardUrlGet': grpclib.const.Handler(
1773
- self.WorkspaceDashboardUrlGet,
1774
- grpclib.const.Cardinality.UNARY_UNARY,
1775
- modal_proto.api_pb2.WorkspaceDashboardUrlRequest,
1776
- modal_proto.api_pb2.WorkspaceDashboardUrlResponse,
1777
- ),
1778
1768
  '/modal.client.ModalClient/WorkspaceNameLookup': grpclib.const.Handler(
1779
1769
  self.WorkspaceNameLookup,
1780
1770
  grpclib.const.Cardinality.UNARY_UNARY,
@@ -2831,12 +2821,6 @@ class ModalClientStub:
2831
2821
  modal_proto.api_pb2.WorkspaceBillingReportRequest,
2832
2822
  modal_proto.api_pb2.WorkspaceBillingReportItem,
2833
2823
  )
2834
- self.WorkspaceDashboardUrlGet = grpclib.client.UnaryUnaryMethod(
2835
- channel,
2836
- '/modal.client.ModalClient/WorkspaceDashboardUrlGet',
2837
- modal_proto.api_pb2.WorkspaceDashboardUrlRequest,
2838
- modal_proto.api_pb2.WorkspaceDashboardUrlResponse,
2839
- )
2840
2824
  self.WorkspaceNameLookup = grpclib.client.UnaryUnaryMethod(
2841
2825
  channel,
2842
2826
  '/modal.client.ModalClient/WorkspaceNameLookup',