modal 0.67.42__py3-none-any.whl → 0.67.44__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.
@@ -415,6 +415,9 @@ def main(container_args: api_pb2.ContainerArguments, client: Client):
415
415
 
416
416
  _client: _Client = synchronizer._translate_in(client) # TODO(erikbern): ugly
417
417
 
418
+ # Call ContainerHello - currently a noop but might be used later for things
419
+ container_io_manager.hello()
420
+
418
421
  with container_io_manager.heartbeats(is_snapshotting_function), UserCodeEventLoop() as event_loop:
419
422
  # If this is a serialized function, fetch the definition from the server
420
423
  if function_def.definition_type == api_pb2.Function.DEFINITION_TYPE_SERIALIZED:
@@ -335,6 +335,9 @@ class _ContainerIOManager:
335
335
  """Only used for tests."""
336
336
  cls._singleton = None
337
337
 
338
+ async def hello(self):
339
+ await self._client.stub.ContainerHello(Empty())
340
+
338
341
  async def _run_heartbeat_loop(self):
339
342
  while 1:
340
343
  t0 = time.monotonic()
modal/cli/container.py CHANGED
@@ -1,5 +1,4 @@
1
1
  # Copyright Modal Labs 2022
2
-
3
2
  from typing import Optional, Union
4
3
 
5
4
  import typer
@@ -8,12 +7,13 @@ from rich.text import Text
8
7
  from modal._pty import get_pty_info
9
8
  from modal._utils.async_utils import synchronizer
10
9
  from modal._utils.grpc_utils import retry_transient_errors
11
- from modal.cli.utils import ENV_OPTION, display_table, stream_app_logs, timestamp_to_local
10
+ from modal.cli.utils import ENV_OPTION, display_table, is_tty, stream_app_logs, timestamp_to_local
12
11
  from modal.client import _Client
13
12
  from modal.config import config
14
13
  from modal.container_process import _ContainerProcess
15
14
  from modal.environments import ensure_env
16
15
  from modal.object import _get_environment_name
16
+ from modal.stream_type import StreamType
17
17
  from modal_proto import api_pb2
18
18
 
19
19
  container_cli = typer.Typer(name="container", help="Manage and connect to running containers.", no_args_is_help=True)
@@ -55,12 +55,19 @@ def logs(container_id: str = typer.Argument(help="Container ID")):
55
55
  @container_cli.command("exec")
56
56
  @synchronizer.create_blocking
57
57
  async def exec(
58
+ pty: Optional[bool] = typer.Option(default=None, help="Run the command using a PTY."),
58
59
  container_id: str = typer.Argument(help="Container ID"),
59
- command: list[str] = typer.Argument(help="A command to run inside the container."),
60
- pty: bool = typer.Option(default=True, help="Run the command using a PTY."),
60
+ command: list[str] = typer.Argument(
61
+ help="A command to run inside the container.\n\n"
62
+ "To pass command-line flags or options, add `--` before the start of your commands. "
63
+ "For example: `modal container exec <id> -- /bin/bash -c 'echo hi'`"
64
+ ),
61
65
  ):
62
66
  """Execute a command in a container."""
63
67
 
68
+ if pty is None:
69
+ pty = is_tty()
70
+
64
71
  client = await _Client.from_env()
65
72
 
66
73
  req = api_pb2.ContainerExecRequest(
@@ -71,7 +78,11 @@ async def exec(
71
78
  )
72
79
  res: api_pb2.ContainerExecResponse = await client.stub.ContainerExec(req)
73
80
 
74
- await _ContainerProcess(res.exec_id, client).attach(pty=pty)
81
+ if pty:
82
+ await _ContainerProcess(res.exec_id, client).attach()
83
+ else:
84
+ # TODO: redirect stderr to its own stream?
85
+ await _ContainerProcess(res.exec_id, client, stdout=StreamType.STDOUT, stderr=StreamType.STDOUT).wait()
75
86
 
76
87
 
77
88
  @container_cli.command("stop")
modal/cli/run.py CHANGED
@@ -29,7 +29,7 @@ from ..runner import deploy_app, interactive_shell, run_app
29
29
  from ..serving import serve_app
30
30
  from ..volume import Volume
31
31
  from .import_refs import import_app, import_function
32
- from .utils import ENV_OPTION, ENV_OPTION_HELP, stream_app_logs
32
+ from .utils import ENV_OPTION, ENV_OPTION_HELP, is_tty, stream_app_logs
33
33
 
34
34
 
35
35
  class ParameterMetadata(TypedDict):
@@ -392,40 +392,47 @@ def shell(
392
392
  "Can be a single region or a comma-separated list to choose from (if not using REF)."
393
393
  ),
394
394
  ),
395
+ pty: Optional[bool] = typer.Option(default=None, help="Run the command using a PTY."),
395
396
  ):
396
- """Run an interactive shell inside a Modal container.
397
+ """Run a command or interactive shell inside a Modal container.
397
398
 
398
- **Examples:**
399
+ \b**Examples:**
399
400
 
400
- Start a shell inside the default Debian-based image:
401
+ \bStart an interactive shell inside the default Debian-based image:
401
402
 
402
- ```
403
+ \b```
403
404
  modal shell
404
405
  ```
405
406
 
406
- Start a bash shell using the spec for `my_function` in your App:
407
+ \bStart an interactive shell with the spec for `my_function` in your App
408
+ (uses the same image, volumes, mounts, etc.):
407
409
 
408
- ```
410
+ \b```
409
411
  modal shell hello_world.py::my_function
410
412
  ```
411
413
 
412
- Or, if you're using a [modal.Cls](/docs/reference/modal.Cls), you can refer to a `@modal.method` directly:
414
+ \bOr, if you're using a [modal.Cls](/docs/reference/modal.Cls), you can refer to a `@modal.method` directly:
413
415
 
414
- ```
416
+ \b```
415
417
  modal shell hello_world.py::MyClass.my_method
416
418
  ```
417
419
 
418
420
  Start a `python` shell:
419
421
 
420
- ```
422
+ \b```
421
423
  modal shell hello_world.py --cmd=python
422
424
  ```
425
+
426
+ \bRun a command with your function's spec and pipe the output to a file:
427
+
428
+ \b```
429
+ modal shell hello_world.py -c 'uv pip list' > env.txt
430
+ ```
423
431
  """
424
432
  env = ensure_env(env)
425
433
 
426
- console = Console()
427
- if not console.is_terminal:
428
- raise click.UsageError("`modal shell` can only be run from a terminal.")
434
+ if pty is None:
435
+ pty = is_tty()
429
436
 
430
437
  if platform.system() == "Windows":
431
438
  raise InvalidError("`modal shell` is currently not supported on Windows")
@@ -441,7 +448,7 @@ def shell(
441
448
  ):
442
449
  from .container import exec
443
450
 
444
- exec(container_id=container_or_function, command=shlex.split(cmd), pty=True)
451
+ exec(container_id=container_or_function, command=shlex.split(cmd))
445
452
  return
446
453
 
447
454
  function = import_function(
@@ -461,6 +468,7 @@ def shell(
461
468
  memory=function_spec.memory,
462
469
  volumes=function_spec.volumes,
463
470
  region=function_spec.scheduler_placement.proto.regions if function_spec.scheduler_placement else None,
471
+ pty=pty,
464
472
  )
465
473
  else:
466
474
  modal_image = Image.from_registry(image, add_python=add_python) if image else None
@@ -474,6 +482,7 @@ def shell(
474
482
  cloud=cloud,
475
483
  volumes=volumes,
476
484
  region=region.split(",") if region else [],
485
+ pty=pty,
477
486
  )
478
487
 
479
488
  # NB: invoking under bash makes --cmd a lot more flexible.
modal/cli/utils.py CHANGED
@@ -77,6 +77,10 @@ def _plain(text: Union[Text, str]) -> str:
77
77
  return text.plain if isinstance(text, Text) else text
78
78
 
79
79
 
80
+ def is_tty() -> bool:
81
+ return Console().is_terminal
82
+
83
+
80
84
  def display_table(
81
85
  columns: Sequence[Union[Column, str]],
82
86
  rows: Sequence[Sequence[Union[Text, str]]],
modal/client.pyi CHANGED
@@ -26,7 +26,7 @@ class _Client:
26
26
  _stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
27
27
 
28
28
  def __init__(
29
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.42"
29
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.44"
30
30
  ): ...
31
31
  def is_closed(self) -> bool: ...
32
32
  @property
@@ -81,7 +81,7 @@ class Client:
81
81
  _stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
82
82
 
83
83
  def __init__(
84
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.42"
84
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.44"
85
85
  ): ...
86
86
  def is_closed(self) -> bool: ...
87
87
  @property
@@ -9,7 +9,7 @@ from ._utils.async_utils import TaskContext, synchronize_api
9
9
  from ._utils.grpc_utils import retry_transient_errors
10
10
  from ._utils.shell_utils import stream_from_stdin, write_to_fd
11
11
  from .client import _Client
12
- from .exception import InteractiveTimeoutError, InvalidError
12
+ from .exception import InteractiveTimeoutError, InvalidError, deprecation_error
13
13
  from .io_streams import _StreamReader, _StreamWriter
14
14
  from .stream_type import StreamType
15
15
 
@@ -114,11 +114,18 @@ class _ContainerProcess(Generic[T]):
114
114
  self._returncode = resp.exit_code
115
115
  return self._returncode
116
116
 
117
- async def attach(self, *, pty: bool):
117
+ async def attach(self, *, pty: Optional[bool] = None):
118
118
  if platform.system() == "Windows":
119
119
  print("interactive exec is not currently supported on Windows.")
120
120
  return
121
121
 
122
+ if pty is not None:
123
+ deprecation_error(
124
+ (2024, 12, 9),
125
+ "The `pty` argument to `modal.container_process.attach(pty=...)` is deprecated, "
126
+ "as only PTY mode is supported. Please remove the argument.",
127
+ )
128
+
122
129
  from rich.console import Console
123
130
 
124
131
  console = Console()
@@ -151,7 +158,7 @@ class _ContainerProcess(Generic[T]):
151
158
  # time out if we can't connect to the server fast enough
152
159
  await asyncio.wait_for(on_connect.wait(), timeout=60)
153
160
 
154
- async with stream_from_stdin(_handle_input, use_raw_terminal=pty):
161
+ async with stream_from_stdin(_handle_input, use_raw_terminal=True):
155
162
  await stdout_task
156
163
  await stderr_task
157
164
 
@@ -34,7 +34,7 @@ class _ContainerProcess(typing.Generic[T]):
34
34
  def returncode(self) -> int: ...
35
35
  async def poll(self) -> typing.Optional[int]: ...
36
36
  async def wait(self) -> int: ...
37
- async def attach(self, *, pty: bool): ...
37
+ async def attach(self, *, pty: typing.Optional[bool] = None): ...
38
38
 
39
39
  class ContainerProcess(typing.Generic[T]):
40
40
  _process_id: typing.Optional[str]
@@ -76,7 +76,7 @@ class ContainerProcess(typing.Generic[T]):
76
76
  wait: __wait_spec
77
77
 
78
78
  class __attach_spec(typing_extensions.Protocol):
79
- def __call__(self, *, pty: bool): ...
80
- async def aio(self, *, pty: bool): ...
79
+ def __call__(self, *, pty: typing.Optional[bool] = None): ...
80
+ async def aio(self, *, pty: typing.Optional[bool] = None): ...
81
81
 
82
82
  attach: __attach_spec
modal/functions.pyi CHANGED
@@ -455,11 +455,11 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
455
455
 
456
456
  _call_generator_nowait: ___call_generator_nowait_spec
457
457
 
458
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
458
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
459
459
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
460
460
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
461
461
 
462
- remote: __remote_spec[ReturnType, P]
462
+ remote: __remote_spec[P, ReturnType]
463
463
 
464
464
  class __remote_gen_spec(typing_extensions.Protocol):
465
465
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -471,17 +471,17 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
471
471
  def _get_obj(self) -> typing.Optional[modal.cls.Obj]: ...
472
472
  def local(self, *args: P.args, **kwargs: P.kwargs) -> OriginalReturnType: ...
473
473
 
474
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
474
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
475
475
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
476
476
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
477
477
 
478
- _experimental_spawn: ___experimental_spawn_spec[ReturnType, P]
478
+ _experimental_spawn: ___experimental_spawn_spec[P, ReturnType]
479
479
 
480
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
480
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
481
481
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
482
482
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
483
483
 
484
- spawn: __spawn_spec[ReturnType, P]
484
+ spawn: __spawn_spec[P, ReturnType]
485
485
 
486
486
  def get_raw_f(self) -> typing.Callable[..., typing.Any]: ...
487
487
 
modal/runner.py CHANGED
@@ -38,6 +38,7 @@ from .output import _get_output_manager, enable_output
38
38
  from .running_app import RunningApp
39
39
  from .sandbox import _Sandbox
40
40
  from .secret import _Secret
41
+ from .stream_type import StreamType
41
42
 
42
43
  if TYPE_CHECKING:
43
44
  from .app import _App
@@ -557,7 +558,9 @@ async def _deploy_app(
557
558
  )
558
559
 
559
560
 
560
- async def _interactive_shell(_app: _App, cmds: list[str], environment_name: str = "", **kwargs: Any) -> None:
561
+ async def _interactive_shell(
562
+ _app: _App, cmds: list[str], environment_name: str = "", pty: bool = True, **kwargs: Any
563
+ ) -> None:
561
564
  """Run an interactive shell (like `bash`) within the image for this app.
562
565
 
563
566
  This is useful for online debugging and interactive exploration of the
@@ -599,9 +602,17 @@ async def _interactive_shell(_app: _App, cmds: list[str], environment_name: str
599
602
  **kwargs,
600
603
  )
601
604
 
602
- container_process = await sandbox.exec(*sandbox_cmds, pty_info=get_pty_info(shell=True))
603
605
  try:
604
- await container_process.attach(pty=True)
606
+ if pty:
607
+ container_process = await sandbox.exec(
608
+ *sandbox_cmds, pty_info=get_pty_info(shell=True) if pty else None
609
+ )
610
+ await container_process.attach()
611
+ else:
612
+ container_process = await sandbox.exec(
613
+ *sandbox_cmds, stdout=StreamType.STDOUT, stderr=StreamType.STDOUT
614
+ )
615
+ await container_process.wait()
605
616
  except InteractiveTimeoutError:
606
617
  # Check on status of Sandbox. It may have crashed, causing connection failure.
607
618
  req = api_pb2.SandboxWaitRequest(sandbox_id=sandbox._object_id, timeout=0)
modal/runner.pyi CHANGED
@@ -75,7 +75,9 @@ async def _deploy_app(
75
75
  environment_name: typing.Optional[str] = None,
76
76
  tag: str = "",
77
77
  ) -> DeployResult: ...
78
- async def _interactive_shell(_app: _App, cmds: list[str], environment_name: str = "", **kwargs: typing.Any) -> None: ...
78
+ async def _interactive_shell(
79
+ _app: _App, cmds: list[str], environment_name: str = "", pty: bool = True, **kwargs: typing.Any
80
+ ) -> None: ...
79
81
  def _run_stub(*args: typing.Any, **kwargs: typing.Any): ...
80
82
  def _deploy_stub(*args: typing.Any, **kwargs: typing.Any): ...
81
83
 
@@ -134,8 +136,12 @@ class __deploy_app_spec(typing_extensions.Protocol):
134
136
  deploy_app: __deploy_app_spec
135
137
 
136
138
  class __interactive_shell_spec(typing_extensions.Protocol):
137
- def __call__(self, _app: _App, cmds: list[str], environment_name: str = "", **kwargs: typing.Any) -> None: ...
138
- async def aio(self, _app: _App, cmds: list[str], environment_name: str = "", **kwargs: typing.Any) -> None: ...
139
+ def __call__(
140
+ self, _app: _App, cmds: list[str], environment_name: str = "", pty: bool = True, **kwargs: typing.Any
141
+ ) -> None: ...
142
+ async def aio(
143
+ self, _app: _App, cmds: list[str], environment_name: str = "", pty: bool = True, **kwargs: typing.Any
144
+ ) -> None: ...
139
145
 
140
146
  interactive_shell: __interactive_shell_spec
141
147
 
modal/sandbox.py CHANGED
@@ -21,7 +21,14 @@ from ._utils.mount_utils import validate_network_file_systems, validate_volumes
21
21
  from .client import _Client
22
22
  from .config import config
23
23
  from .container_process import _ContainerProcess
24
- from .exception import ExecutionError, InvalidError, SandboxTerminatedError, SandboxTimeoutError, deprecation_warning
24
+ from .exception import (
25
+ ExecutionError,
26
+ InvalidError,
27
+ SandboxTerminatedError,
28
+ SandboxTimeoutError,
29
+ deprecation_error,
30
+ deprecation_warning,
31
+ )
25
32
  from .gpu import GPU_T
26
33
  from .image import _Image
27
34
  from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
@@ -606,7 +613,7 @@ Sandbox = synchronize_api(_Sandbox)
606
613
 
607
614
  def __getattr__(name):
608
615
  if name == "LogsReader":
609
- deprecation_warning(
616
+ deprecation_error(
610
617
  (2024, 8, 12),
611
618
  "`modal.sandbox.LogsReader` is deprecated. Please import `modal.io_streams.StreamReader` instead.",
612
619
  )
@@ -614,7 +621,7 @@ def __getattr__(name):
614
621
 
615
622
  return StreamReader
616
623
  elif name == "StreamWriter":
617
- deprecation_warning(
624
+ deprecation_error(
618
625
  (2024, 8, 12),
619
626
  "`modal.sandbox.StreamWriter` is deprecated. Please import `modal.io_streams.StreamWriter` instead.",
620
627
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.67.42
3
+ Version: 0.67.44
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -2,7 +2,7 @@ modal/__init__.py,sha256=Yn8zS7Jxl5uZjPM331Pc4FdSmp9Rt6VdE7TiE4ZKRc8,2151
2
2
  modal/__main__.py,sha256=scYhGFqh8OJcVDo-VOxIT6CCwxOgzgflYWMnIZiMRqE,2871
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
5
- modal/_container_entrypoint.py,sha256=Tae8hAbgN62HM9Q_UFuCyyswfdh1rOey2zzXkbG4Cns,28795
5
+ modal/_container_entrypoint.py,sha256=DcaTfVnttlHaaStcYPwzFzojyVx6LvGVkV4t7ZOym2s,28909
6
6
  modal/_ipython.py,sha256=HF_DYy0e0qM9WnGDmTY30s1RxzGya9GeORCauCEpRaE,450
7
7
  modal/_location.py,sha256=S3lSxIU3h9HkWpkJ3Pwo0pqjIOSB1fjeSgUsY3x7eec,1202
8
8
  modal/_output.py,sha256=0fWX_KQwhER--U81ys16CL-pA5A-LN20C0EZjElKGJQ,25410
@@ -19,14 +19,14 @@ modal/app.py,sha256=EJ7FUN6rWnSwLJoYJh8nmKg_t-8hdN8_rt0OrkP7JvQ,46084
19
19
  modal/app.pyi,sha256=BE5SlR5tRECuc6-e2lUuOknDdov3zxgZ4N0AsLb5ZVQ,25270
20
20
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
21
21
  modal/client.py,sha256=cmylZhU35txmrx4nltNYuuqXRgeoMtm0ow1J9wJkEYQ,16400
22
- modal/client.pyi,sha256=-fnThLyTYwsvmI5wZIayIBBHAkeTQPwnbRT-GNGQe8g,7354
22
+ modal/client.pyi,sha256=TaiBPKqFJ0UHNiHC4LkhFAhk1OjtgvE3drbSEBGqwWQ,7354
23
23
  modal/cloud_bucket_mount.py,sha256=G7T7jWLD0QkmrfKR75mSTwdUZ2xNfj7pkVqb4ipmxmI,5735
24
24
  modal/cloud_bucket_mount.pyi,sha256=CEi7vrH3kDUF4LAy4qP6tfImy2UJuFRcRbsgRNM1wo8,1403
25
25
  modal/cls.py,sha256=OJqzj_V-n1g48BY_4Jg_BOTQdftEEl4kTWN0X4FOOdg,27378
26
26
  modal/cls.pyi,sha256=47jaIT06fz8PSUrs-MaNn6r03PHsAyUGsKuK5e9RMhQ,8140
27
27
  modal/config.py,sha256=1KhNJkjYsJkX1V8RPPdRYPlM2HE-ZZs0JVSxbiXjmrw,11010
28
- modal/container_process.py,sha256=YRCKjn56oqTtGjtLxpl_KSkOhYrcRitgF3LOI6o14Q4,5759
29
- modal/container_process.pyi,sha256=k2kClwaSzz11eci1pzFZgCm-ptXapHAyHTOENorlazA,2594
28
+ modal/container_process.py,sha256=zDxCLk6KfJT1G9FfNtjom6gekBQ46op3TWepT7-Hkbg,6077
29
+ modal/container_process.pyi,sha256=dqtqBmyRpXXpRrDooESL6WBVU_1Rh6OG-66P2Hk9E5U,2666
30
30
  modal/dict.py,sha256=RmJlEwFJOdSfAYcVa50hbbFccV8e7BvC5tc5g1HXF-c,12622
31
31
  modal/dict.pyi,sha256=2cYgOqBxYZih4BYgMV0c3rNPuxYR6-cB1GBXzFkHA5c,7265
32
32
  modal/environments.py,sha256=5cgA-zbm6ngKLsRA19zSOgtgo9-BarJK3FJK0BiF2Lo,6505
@@ -34,7 +34,7 @@ modal/environments.pyi,sha256=XalNpiPkAtHWAvOU2Cotq0ozmtl-Jv0FDsR8h9mr27Q,3521
34
34
  modal/exception.py,sha256=EBkdWVved2XEPsXaoPRu56xfxFFHL9iuqvUsdj42WDA,6392
35
35
  modal/experimental.py,sha256=jFuNbwrNHos47viMB9q-cHJSvf2RDxDdoEcss9plaZE,2302
36
36
  modal/functions.py,sha256=3GjjFbf40XciWAa4rTmh0erkZjPzRjKHqWxUu91mHOU,66685
37
- modal/functions.pyi,sha256=4k5CaJ9iTuEyHQ2rC5OysNHBLv1CZrD7zBMU1zXIU4w,24988
37
+ modal/functions.pyi,sha256=IyuM9TV79JfrtfTaJ4yq3EcWp3yHuxLavpxTOwSWEDw,24988
38
38
  modal/gpu.py,sha256=r4rL6uH3UJIQthzYvfWauXNyh01WqCPtKZCmmSX1fd4,6881
39
39
  modal/image.py,sha256=cQ6WP1xHXZT_nY8z3aEFiGwKzrTV0yxi3Ab8JzF91eo,79653
40
40
  modal/image.pyi,sha256=PIKH6JBA4L5TfdJrQu3pm2ykyIITmiP920TpP8cdyQA,24585
@@ -57,10 +57,10 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  modal/queue.py,sha256=fJYFfpdrlVj_doc3QxgvJvv7c8BGHjjja5q_9HCtSqs,18658
58
58
  modal/queue.pyi,sha256=di3ownBw4jc6d4X7ygXtbpjlUMOK69qyaD3lVsJbpoM,9900
59
59
  modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
60
- modal/runner.py,sha256=7obU-Gq1ocpBGCuR6pvn1T-D6ggg1T48qFo2TNUGWkU,24089
61
- modal/runner.pyi,sha256=RAtCvx_lXWjyFjIaZ3t9-X1c7rqpgAQlhl4Hww53OY8,5038
60
+ modal/runner.py,sha256=AiBGoc_BZxQenjA0T9yQ7hf515Va6G05ULYRGnTT5Y0,24453
61
+ modal/runner.pyi,sha256=Fa6HjaqH---CJhsefLm6Ce6DRLKZdz_Bng_gn9arJdw,5126
62
62
  modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
63
- modal/sandbox.py,sha256=ua2z6aV_fBE_7hSCv9vcRp4U9j6lRE9uOrcen4LEJks,26316
63
+ modal/sandbox.py,sha256=Yd__KipEINH2euDPOcm5MPBnagRv19Sa5z5tJCvGOQs,26360
64
64
  modal/sandbox.pyi,sha256=fRl32Pt5F6TbK7aYewjlcL4WQxxmp7m6Ybktmkd2VOk,18108
65
65
  modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
66
66
  modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
@@ -75,7 +75,7 @@ modal/volume.py,sha256=IISuMeXq9MoSkhXg8Q6JG0F-2n9NTkWk0xGuJB8l3d8,29159
75
75
  modal/volume.pyi,sha256=St0mDiaojfep6Bs4sBbkRJmeacYHF6lh6FKOWGmheHA,11182
76
76
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
77
77
  modal/_runtime/asgi.py,sha256=GvuxZqWnIHMIR-Bx5f7toCQlkERaJO8CHjTPNM9IFIw,21537
78
- modal/_runtime/container_io_manager.py,sha256=8NyX5uuwmHEJgxMwdoY9PpEO-IHA8LGdYdbdHLIafK8,44131
78
+ modal/_runtime/container_io_manager.py,sha256=ctgyNFiHjq1brCrabXmlurkAXjnrCeWPRvTVa735vRw,44215
79
79
  modal/_runtime/execution_context.py,sha256=E6ofm6j1POXGPxS841X3V7JU6NheVb8OkQc7JpLq4Kg,2712
80
80
  modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
81
81
  modal/_runtime/user_code_imports.py,sha256=q_3JOYqCPDcVFZWCHEjyEqj8yzdFsQ49HzeqYmFDLbk,14521
@@ -104,7 +104,7 @@ modal/cli/_download.py,sha256=t6BXZwjTd9MgznDvbsV8rp0FZWggdzC-lUAGZU4xx1g,3984
104
104
  modal/cli/_traceback.py,sha256=Tm0g4V_fr4XAlmuh_4MNgZKtjJly9wsWtnKKvOJFM7Q,7130
105
105
  modal/cli/app.py,sha256=KOU3tKdcw50612rmN2LmO-N8cT1M1-UgLs7tw68Kgds,7717
106
106
  modal/cli/config.py,sha256=pXPLmX0bIoV57rQNqIPK7V-yllj-GPRY4jiBO_EklGg,1667
107
- modal/cli/container.py,sha256=lRSrxnl7bTLLW9T6hzkqOxqFzzV9qHyXPOuOHY8zkc4,3194
107
+ modal/cli/container.py,sha256=nCySVD10VJPzmX3ghTsGmpxdYeVYYMW6ofjsyt2gQcM,3667
108
108
  modal/cli/dict.py,sha256=gwX4ZBsrr0dpWf_B5_5GN_ealcVzpcGyvY24dEY4y3Y,4455
109
109
  modal/cli/entry_point.py,sha256=aaNxFAqZcmtSjwzkYIA_Ba9CkL4cL4_i2gy5VjoXxkM,4228
110
110
  modal/cli/environment.py,sha256=Ayddkiq9jdj3XYDJ8ZmUqFpPPH8xajYlbexRkzGtUcg,4334
@@ -113,10 +113,10 @@ modal/cli/launch.py,sha256=uyI-ouGvYRjHLGxGQ2lYBZq32BiRT1i0L8ksz5iy7K8,2935
113
113
  modal/cli/network_file_system.py,sha256=3QbAxKEoRc6RCMsYE3OS-GcuiI4GMkz_wAKsIBbN1qg,8186
114
114
  modal/cli/profile.py,sha256=rLXfjJObfPNjaZvNfHGIKqs7y9bGYyGe-K7V0w-Ni0M,3110
115
115
  modal/cli/queues.py,sha256=MIh2OsliNE2QeL1erubfsRsNuG4fxqcqWA2vgIfQ4Mg,4494
116
- modal/cli/run.py,sha256=IPA5Hx7HqCE01NilPZDh1fFaslO4QZa-RKEpMPqjLqA,17066
116
+ modal/cli/run.py,sha256=MitoSFA_QaqkIVjBRi91w1ekz6UlCwL3htE3_RI3yjA,17353
117
117
  modal/cli/secret.py,sha256=uQpwYrMY98iMCWeZOQTcktOYhPTZ8IHnyealDc2CZqo,4206
118
118
  modal/cli/token.py,sha256=mxSgOWakXG6N71hQb1ko61XAR9ZGkTMZD-Txn7gmTac,1924
119
- modal/cli/utils.py,sha256=EK_6BIJ7gorQevp9sD_o5iW12foytpg8icBGO32hdeM,3660
119
+ modal/cli/utils.py,sha256=hZmjyzcPjDnQSkLvycZD2LhGdcsfdZshs_rOU78EpvI,3717
120
120
  modal/cli/volume.py,sha256=ngbnX4nhURMaCOqDGO4HmTvAbRBZBjRnPvk5TumnbVw,10004
121
121
  modal/cli/programs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
122
122
  modal/cli/programs/run_jupyter.py,sha256=RRr07CqZrStMbLdBM3PpzU6KM8t9FtLbdIPthg2-Mpw,2755
@@ -159,10 +159,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
159
159
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
160
  modal_version/__init__.py,sha256=3IY-AWLH55r35_mQXIaut0jrJvoPuf1NZJBQQfSbPuo,470
161
161
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
162
- modal_version/_version_generated.py,sha256=CPqvHkRI4G0suiPfCuDEKCeUgw_O5yILvh3KaNl3Np0,149
163
- modal-0.67.42.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
164
- modal-0.67.42.dist-info/METADATA,sha256=5HkkANTv2LGFzF5o8GlWJIgaUob1Vyk98nVmZienRxM,2329
165
- modal-0.67.42.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
166
- modal-0.67.42.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
167
- modal-0.67.42.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
168
- modal-0.67.42.dist-info/RECORD,,
162
+ modal_version/_version_generated.py,sha256=j9PfMkws1rfnUqEAN_lu0CiezuDi6eQfirAvf0CM_DM,149
163
+ modal-0.67.44.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
164
+ modal-0.67.44.dist-info/METADATA,sha256=miv8Op-4iBzWGjF7RXt7L2r4hCmKGi2FVESAn2OypNs,2329
165
+ modal-0.67.44.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
166
+ modal-0.67.44.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
167
+ modal-0.67.44.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
168
+ modal-0.67.44.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2024
2
2
 
3
3
  # Note: Reset this value to -1 whenever you make a minor `0.X` release of the client.
4
- build_number = 42 # git: a4dcffa
4
+ build_number = 44 # git: cb01050