modal 0.72.21__py3-none-any.whl → 0.72.23__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.
Files changed (48) hide show
  1. modal/_container_entrypoint.py +1 -1
  2. modal/_object.py +279 -0
  3. modal/_resolver.py +7 -5
  4. modal/_runtime/user_code_imports.py +7 -7
  5. modal/_serialization.py +4 -3
  6. modal/app.py +1 -1
  7. modal/app.pyi +4 -3
  8. modal/cli/app.py +1 -1
  9. modal/cli/container.py +1 -1
  10. modal/client.py +1 -0
  11. modal/client.pyi +4 -2
  12. modal/cls.py +1 -1
  13. modal/cls.pyi +2 -1
  14. modal/dict.py +1 -1
  15. modal/dict.pyi +2 -1
  16. modal/environments.py +1 -1
  17. modal/environments.pyi +2 -1
  18. modal/functions.py +18 -20
  19. modal/functions.pyi +13 -12
  20. modal/image.py +6 -6
  21. modal/image.pyi +2 -1
  22. modal/mount.py +1 -1
  23. modal/mount.pyi +2 -1
  24. modal/network_file_system.py +7 -7
  25. modal/network_file_system.pyi +2 -1
  26. modal/object.py +2 -265
  27. modal/object.pyi +30 -122
  28. modal/proxy.py +1 -1
  29. modal/proxy.pyi +2 -1
  30. modal/queue.py +1 -1
  31. modal/queue.pyi +2 -1
  32. modal/runner.py +2 -2
  33. modal/sandbox.py +1 -1
  34. modal/sandbox.pyi +2 -1
  35. modal/secret.py +1 -1
  36. modal/secret.pyi +2 -1
  37. modal/volume.py +1 -1
  38. modal/volume.pyi +2 -1
  39. {modal-0.72.21.dist-info → modal-0.72.23.dist-info}/METADATA +1 -1
  40. {modal-0.72.21.dist-info → modal-0.72.23.dist-info}/RECORD +48 -47
  41. modal_proto/api.proto +1 -1
  42. modal_proto/api_pb2.py +246 -246
  43. modal_proto/api_pb2.pyi +5 -2
  44. modal_version/_version_generated.py +1 -1
  45. {modal-0.72.21.dist-info → modal-0.72.23.dist-info}/LICENSE +0 -0
  46. {modal-0.72.21.dist-info → modal-0.72.23.dist-info}/WHEEL +0 -0
  47. {modal-0.72.21.dist-info → modal-0.72.23.dist-info}/entry_points.txt +0 -0
  48. {modal-0.72.21.dist-info → modal-0.72.23.dist-info}/top_level.txt +0 -0
modal/object.pyi CHANGED
@@ -5,117 +5,26 @@ import modal.client
5
5
  import typing
6
6
  import typing_extensions
7
7
 
8
- O = typing.TypeVar("O", bound="_Object")
9
-
10
- _BLOCKING_O = typing.TypeVar("_BLOCKING_O", bound="Object")
11
-
12
- def _get_environment_name(
13
- environment_name: typing.Optional[str] = None, resolver: typing.Optional[modal._resolver.Resolver] = None
14
- ) -> typing.Optional[str]: ...
15
-
16
- class _Object:
17
- _type_prefix: typing.ClassVar[typing.Optional[str]]
18
- _prefix_to_type: typing.ClassVar[dict[str, type]]
19
- _load: typing.Optional[
20
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
21
- ]
22
- _preload: typing.Optional[
23
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
24
- ]
25
- _rep: str
26
- _is_another_app: bool
27
- _hydrate_lazily: bool
28
- _deps: typing.Optional[typing.Callable[..., list[_Object]]]
29
- _deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]]
30
- _object_id: str
31
- _client: modal.client._Client
32
- _is_hydrated: bool
33
- _is_rehydrated: bool
34
-
35
- @classmethod
36
- def __init_subclass__(cls, type_prefix: typing.Optional[str] = None): ...
37
- def __init__(self, *args, **kwargs): ...
38
- def _init(
39
- self,
40
- rep: str,
41
- load: typing.Optional[
42
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
43
- ] = None,
44
- is_another_app: bool = False,
45
- preload: typing.Optional[
46
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
47
- ] = None,
48
- hydrate_lazily: bool = False,
49
- deps: typing.Optional[typing.Callable[..., list[_Object]]] = None,
50
- deduplication_key: typing.Optional[
51
- typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
52
- ] = None,
53
- ): ...
54
- def _unhydrate(self): ...
55
- def _initialize_from_empty(self): ...
56
- def _initialize_from_other(self, other): ...
57
- def _hydrate(
58
- self, object_id: str, client: modal.client._Client, metadata: typing.Optional[google.protobuf.message.Message]
59
- ): ...
60
- def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
61
- def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
62
- def _validate_is_hydrated(self: O): ...
63
- def clone(self: O) -> O: ...
64
- @classmethod
65
- def _from_loader(
66
- cls,
67
- load: typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]],
68
- rep: str,
69
- is_another_app: bool = False,
70
- preload: typing.Optional[
71
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
72
- ] = None,
73
- hydrate_lazily: bool = False,
74
- deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[_Object]]] = None,
75
- deduplication_key: typing.Optional[
76
- typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
77
- ] = None,
78
- ): ...
79
- @classmethod
80
- def _get_type_from_id(cls: type[O], object_id: str) -> type[O]: ...
81
- @classmethod
82
- def _is_id_type(cls: type[O], object_id) -> bool: ...
83
- @classmethod
84
- def _new_hydrated(
85
- cls: type[O],
86
- object_id: str,
87
- client: modal.client._Client,
88
- handle_metadata: typing.Optional[google.protobuf.message.Message],
89
- is_another_app: bool = False,
90
- ) -> O: ...
91
- def _hydrate_from_other(self, other: O): ...
92
- def __repr__(self): ...
93
- @property
94
- def local_uuid(self): ...
95
- @property
96
- def object_id(self) -> str: ...
97
- @property
98
- def is_hydrated(self) -> bool: ...
99
- @property
100
- def deps(self) -> typing.Callable[..., list[_Object]]: ...
101
- async def resolve(self, client: typing.Optional[modal.client._Client] = None): ...
102
-
103
8
  class Object:
104
9
  _type_prefix: typing.ClassVar[typing.Optional[str]]
105
10
  _prefix_to_type: typing.ClassVar[dict[str, type]]
106
11
  _load: typing.Optional[
107
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
12
+ typing.Callable[
13
+ [typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
14
+ ]
108
15
  ]
109
16
  _preload: typing.Optional[
110
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
17
+ typing.Callable[
18
+ [typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
19
+ ]
111
20
  ]
112
21
  _rep: str
113
22
  _is_another_app: bool
114
23
  _hydrate_lazily: bool
115
- _deps: typing.Optional[typing.Callable[..., list[Object]]]
24
+ _deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[Object]]]
116
25
  _deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]]
117
- _object_id: str
118
- _client: modal.client.Client
26
+ _object_id: typing.Optional[str]
27
+ _client: typing.Optional[modal.client.Client]
119
28
  _is_hydrated: bool
120
29
  _is_rehydrated: bool
121
30
 
@@ -128,14 +37,14 @@ class Object:
128
37
  self,
129
38
  rep: str,
130
39
  load: typing.Optional[
131
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
40
+ typing.Callable[[typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], None]
132
41
  ] = None,
133
42
  is_another_app: bool = False,
134
43
  preload: typing.Optional[
135
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
44
+ typing.Callable[[typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], None]
136
45
  ] = None,
137
46
  hydrate_lazily: bool = False,
138
- deps: typing.Optional[typing.Callable[..., list[Object]]] = None,
47
+ deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[Object]]] = None,
139
48
  deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Hashable]] = None,
140
49
  ): ...
141
50
  def aio(
@@ -143,17 +52,19 @@ class Object:
143
52
  rep: str,
144
53
  load: typing.Optional[
145
54
  typing.Callable[
146
- [_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
55
+ [typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]],
56
+ collections.abc.Awaitable[None],
147
57
  ]
148
58
  ] = None,
149
59
  is_another_app: bool = False,
150
60
  preload: typing.Optional[
151
61
  typing.Callable[
152
- [_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
62
+ [typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]],
63
+ collections.abc.Awaitable[None],
153
64
  ]
154
65
  ] = None,
155
66
  hydrate_lazily: bool = False,
156
- deps: typing.Optional[typing.Callable[..., list[Object]]] = None,
67
+ deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[Object]]] = None,
157
68
  deduplication_key: typing.Optional[
158
69
  typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
159
70
  ] = None,
@@ -169,51 +80,48 @@ class Object:
169
80
  ): ...
170
81
  def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
171
82
  def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
172
- def _validate_is_hydrated(self: _BLOCKING_O): ...
173
- def clone(self: _BLOCKING_O) -> _BLOCKING_O: ...
83
+ def _validate_is_hydrated(self): ...
84
+ def clone(self) -> typing_extensions.Self: ...
174
85
  @classmethod
175
86
  def _from_loader(
176
87
  cls,
177
- load: typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None],
88
+ load: typing.Callable[[typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], None],
178
89
  rep: str,
179
90
  is_another_app: bool = False,
180
91
  preload: typing.Optional[
181
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
92
+ typing.Callable[[typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], None]
182
93
  ] = None,
183
94
  hydrate_lazily: bool = False,
184
95
  deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[Object]]] = None,
185
96
  deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Hashable]] = None,
186
97
  ): ...
98
+ @staticmethod
99
+ def _get_type_from_id(object_id: str) -> type[Object]: ...
187
100
  @classmethod
188
- def _get_type_from_id(cls: type[_BLOCKING_O], object_id: str) -> type[_BLOCKING_O]: ...
189
- @classmethod
190
- def _is_id_type(cls: type[_BLOCKING_O], object_id) -> bool: ...
101
+ def _is_id_type(cls, object_id) -> bool: ...
191
102
  @classmethod
192
103
  def _new_hydrated(
193
- cls: type[_BLOCKING_O],
104
+ cls,
194
105
  object_id: str,
195
106
  client: modal.client.Client,
196
107
  handle_metadata: typing.Optional[google.protobuf.message.Message],
197
108
  is_another_app: bool = False,
198
- ) -> _BLOCKING_O: ...
199
- def _hydrate_from_other(self, other: _BLOCKING_O): ...
109
+ ) -> typing_extensions.Self: ...
110
+ def _hydrate_from_other(self, other: typing_extensions.Self): ...
200
111
  def __repr__(self): ...
201
112
  @property
202
113
  def local_uuid(self): ...
203
114
  @property
204
115
  def object_id(self) -> str: ...
205
116
  @property
117
+ def client(self) -> modal.client.Client: ...
118
+ @property
206
119
  def is_hydrated(self) -> bool: ...
207
120
  @property
208
- def deps(self) -> typing.Callable[..., list[Object]]: ...
121
+ def deps(self) -> typing.Callable[..., collections.abc.Sequence[Object]]: ...
209
122
 
210
123
  class __resolve_spec(typing_extensions.Protocol):
211
124
  def __call__(self, client: typing.Optional[modal.client.Client] = None): ...
212
125
  async def aio(self, client: typing.Optional[modal.client.Client] = None): ...
213
126
 
214
127
  resolve: __resolve_spec
215
-
216
- def live_method(method): ...
217
- def live_method_gen(method): ...
218
-
219
- EPHEMERAL_OBJECT_HEARTBEAT_SLEEP: int
modal/proxy.py CHANGED
@@ -3,9 +3,9 @@ from typing import Optional
3
3
 
4
4
  from modal_proto import api_pb2
5
5
 
6
+ from ._object import _get_environment_name, _Object
6
7
  from ._resolver import Resolver
7
8
  from ._utils.async_utils import synchronize_api
8
- from .object import _get_environment_name, _Object
9
9
 
10
10
 
11
11
  class _Proxy(_Object, type_prefix="pr"):
modal/proxy.pyi CHANGED
@@ -1,7 +1,8 @@
1
+ import modal._object
1
2
  import modal.object
2
3
  import typing
3
4
 
4
- class _Proxy(modal.object._Object):
5
+ class _Proxy(modal._object._Object):
5
6
  @staticmethod
6
7
  def from_name(name: str, environment_name: typing.Optional[str] = None) -> _Proxy: ...
7
8
 
modal/queue.py CHANGED
@@ -10,6 +10,7 @@ from synchronicity.async_wrap import asynccontextmanager
10
10
 
11
11
  from modal_proto import api_pb2
12
12
 
13
+ from ._object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
13
14
  from ._resolver import Resolver
14
15
  from ._serialization import deserialize, serialize
15
16
  from ._utils.async_utils import TaskContext, synchronize_api, warn_if_generator_is_not_consumed
@@ -18,7 +19,6 @@ from ._utils.grpc_utils import retry_transient_errors
18
19
  from ._utils.name_utils import check_object_name
19
20
  from .client import _Client
20
21
  from .exception import InvalidError, RequestSizeError
21
- from .object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
22
22
 
23
23
 
24
24
  class _Queue(_Object, type_prefix="qu"):
modal/queue.pyi CHANGED
@@ -1,11 +1,12 @@
1
1
  import collections.abc
2
+ import modal._object
2
3
  import modal.client
3
4
  import modal.object
4
5
  import synchronicity.combined_types
5
6
  import typing
6
7
  import typing_extensions
7
8
 
8
- class _Queue(modal.object._Object):
9
+ class _Queue(modal._object._Object):
9
10
  def __init__(self): ...
10
11
  @staticmethod
11
12
  def validate_partition_key(partition: typing.Optional[str]) -> bytes: ...
modal/runner.py CHANGED
@@ -14,6 +14,7 @@ from synchronicity.async_wrap import asynccontextmanager
14
14
  import modal_proto.api_pb2
15
15
  from modal_proto import api_pb2
16
16
 
17
+ from ._object import _get_environment_name, _Object
17
18
  from ._pty import get_pty_info
18
19
  from ._resolver import Resolver
19
20
  from ._runtime.execution_context import is_local
@@ -28,7 +29,6 @@ from .config import config, logger
28
29
  from .environments import _get_environment_cached
29
30
  from .exception import InteractiveTimeoutError, InvalidError, RemoteError, _CliUserExecutionError
30
31
  from .functions import _Function
31
- from .object import _get_environment_name, _Object
32
32
  from .output import _get_output_manager, enable_output
33
33
  from .running_app import RunningApp, running_app_from_layout
34
34
  from .sandbox import _Sandbox
@@ -155,7 +155,7 @@ async def _create_all_objects(
155
155
  # this is to ensure that directly referenced functions from the global scope has
156
156
  # ids associated with them when they are serialized into other functions
157
157
  await resolver.preload(obj, existing_object_id)
158
- if obj.object_id is not None:
158
+ if obj.is_hydrated:
159
159
  tag_to_object_id[tag] = obj.object_id
160
160
 
161
161
  await TaskContext.gather(*(_preload(tag, obj) for tag, obj in indexed_objects.items()))
modal/sandbox.py CHANGED
@@ -16,6 +16,7 @@ from modal.volume import _Volume
16
16
  from modal_proto import api_pb2
17
17
 
18
18
  from ._location import parse_cloud_provider
19
+ from ._object import _get_environment_name, _Object
19
20
  from ._resolver import Resolver
20
21
  from ._resources import convert_fn_config_to_resources_config
21
22
  from ._utils.async_utils import synchronize_api
@@ -32,7 +33,6 @@ from .image import _Image
32
33
  from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
33
34
  from .mount import _Mount
34
35
  from .network_file_system import _NetworkFileSystem, network_file_system_mount_protos
35
- from .object import _get_environment_name, _Object
36
36
  from .proxy import _Proxy
37
37
  from .scheduler_placement import SchedulerPlacement
38
38
  from .secret import _Secret
modal/sandbox.pyi CHANGED
@@ -1,6 +1,7 @@
1
1
  import _typeshed
2
2
  import collections.abc
3
3
  import google.protobuf.message
4
+ import modal._object
4
5
  import modal._tunnel
5
6
  import modal.app
6
7
  import modal.client
@@ -23,7 +24,7 @@ import os
23
24
  import typing
24
25
  import typing_extensions
25
26
 
26
- class _Sandbox(modal.object._Object):
27
+ class _Sandbox(modal._object._Object):
27
28
  _result: typing.Optional[modal_proto.api_pb2.GenericResult]
28
29
  _stdout: modal.io_streams._StreamReader[str]
29
30
  _stderr: modal.io_streams._StreamReader[str]
modal/secret.py CHANGED
@@ -6,6 +6,7 @@ from grpclib import GRPCError, Status
6
6
 
7
7
  from modal_proto import api_pb2
8
8
 
9
+ from ._object import _get_environment_name, _Object
9
10
  from ._resolver import Resolver
10
11
  from ._runtime.execution_context import is_local
11
12
  from ._utils.async_utils import synchronize_api
@@ -14,7 +15,6 @@ from ._utils.grpc_utils import retry_transient_errors
14
15
  from ._utils.name_utils import check_object_name
15
16
  from .client import _Client
16
17
  from .exception import InvalidError, NotFoundError
17
- from .object import _get_environment_name, _Object
18
18
 
19
19
  ENV_DICT_WRONG_TYPE_ERR = "the env_dict argument to Secret has to be a dict[str, Union[str, None]]"
20
20
 
modal/secret.pyi CHANGED
@@ -1,9 +1,10 @@
1
+ import modal._object
1
2
  import modal.client
2
3
  import modal.object
3
4
  import typing
4
5
  import typing_extensions
5
6
 
6
- class _Secret(modal.object._Object):
7
+ class _Secret(modal._object._Object):
7
8
  @staticmethod
8
9
  def from_dict(env_dict: dict[str, typing.Optional[str]] = {}): ...
9
10
  @staticmethod
modal/volume.py CHANGED
@@ -27,6 +27,7 @@ import modal_proto.api_pb2
27
27
  from modal.exception import VolumeUploadTimeoutError
28
28
  from modal_proto import api_pb2
29
29
 
30
+ from ._object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
30
31
  from ._resolver import Resolver
31
32
  from ._utils.async_utils import TaskContext, aclosing, async_map, asyncnullcontext, synchronize_api
32
33
  from ._utils.blob_utils import (
@@ -41,7 +42,6 @@ from ._utils.grpc_utils import retry_transient_errors
41
42
  from ._utils.name_utils import check_object_name
42
43
  from .client import _Client
43
44
  from .config import logger
44
- from .object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
45
45
 
46
46
  # Max duration for uploading to volumes files
47
47
  # As a guide, files >40GiB will take >10 minutes to upload.
modal/volume.pyi CHANGED
@@ -1,6 +1,7 @@
1
1
  import asyncio.locks
2
2
  import collections.abc
3
3
  import enum
4
+ import modal._object
4
5
  import modal._utils.blob_utils
5
6
  import modal.client
6
7
  import modal.object
@@ -33,7 +34,7 @@ class FileEntry:
33
34
  def __delattr__(self, name): ...
34
35
  def __hash__(self): ...
35
36
 
36
- class _Volume(modal.object._Object):
37
+ class _Volume(modal._object._Object):
37
38
  _lock: typing.Optional[asyncio.locks.Lock]
38
39
 
39
40
  async def _get_lock(self): ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.72.21
3
+ Version: 0.72.23
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -2,86 +2,87 @@ modal/__init__.py,sha256=3NJLLHb0TRc2tc68kf8NHzORx38GbtbZvPEWDWrQ6N4,2234
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=xvz2kZAI0y02BZVSlpyrdgKHk2WCYEqI_iu1FBRDCOM,29553
5
+ modal/_container_entrypoint.py,sha256=iHSNqLCTK4uXzcmhF5ou5AqOYovk4hMfV3BZYYDrFKc,29554
6
6
  modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
7
7
  modal/_location.py,sha256=S3lSxIU3h9HkWpkJ3Pwo0pqjIOSB1fjeSgUsY3x7eec,1202
8
+ modal/_object.py,sha256=zSqNoIQM9mDmcaJVHXZwbCw8dDEVVoL2iNxN-hk9KGs,10361
8
9
  modal/_output.py,sha256=0fWX_KQwhER--U81ys16CL-pA5A-LN20C0EZjElKGJQ,25410
9
10
  modal/_proxy_tunnel.py,sha256=gnKyCfmVB7x2d1A6c-JDysNIP3kEFxmXzhcXhPrzPn0,1906
10
11
  modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
11
- modal/_resolver.py,sha256=TtowKu2LdZ7NpiYkSXs058BZ4ivY8KVYdchqLfREkiA,6775
12
+ modal/_resolver.py,sha256=D9IAdZKNqRPwgPDaB-XMKGtO8G0GwtBzG6xdgiXKdCk,6945
12
13
  modal/_resources.py,sha256=5qmcirXUI8dSH926nwkUaeX9H25mqYu9mXD_KuT79-o,1733
13
- modal/_serialization.py,sha256=qPLH6OUEBas1CT-a6i5pOP1hPGt5AfKr9q7RMUTFOMc,18722
14
+ modal/_serialization.py,sha256=x0uArKNXg89SfmKMUaLup_moHodax9weZItkChKeQ64,18745
14
15
  modal/_traceback.py,sha256=IZQzB3fVlUfMHOSyKUgw0H6qv4yHnpyq-XVCNZKfUdA,5023
15
16
  modal/_tunnel.py,sha256=zTBxBiuH1O22tS1OliAJdIsSmaZS8PlnifS_6S5z-mk,6320
16
17
  modal/_tunnel.pyi,sha256=JmmDYAy9F1FpgJ_hWx0xkom2nTOFQjn4mTPYlU3PFo4,1245
17
18
  modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
18
- modal/app.py,sha256=t-INVjEAhSXppcu8m_rhaa1r5tzZmEPCS3lhAZg7xkc,45611
19
- modal/app.pyi,sha256=279Tf7Jmwq_SvAm_BKRnollAqefYI22g7wQqP94Er1Y,25453
19
+ modal/app.py,sha256=kUw4y1PtXHdQPemnl30EhUuP91tZxCXJju0tCTFsqRo,45612
20
+ modal/app.pyi,sha256=5D3LkPP6qvTIl2_YgiyhNQ9X4VsOVuxd69a23UmohDg,25477
20
21
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
21
- modal/client.py,sha256=JAnd4-GCN093BwkvOFAK5a6iy5ycxofjpUncMxlrIMw,15253
22
- modal/client.pyi,sha256=aGTbWWyktsgcmwlTAXb6k2clqWvb5s6RkL2NLyutDTU,7280
22
+ modal/client.py,sha256=8SQawr7P1PNUCq1UmJMUQXG2jIo4Nmdcs311XqrNLRE,15276
23
+ modal/client.pyi,sha256=RyHOBACbzE5dtGcHAnmBLILrI6DiFQ5VovSYE_49P8w,7326
23
24
  modal/cloud_bucket_mount.py,sha256=G7T7jWLD0QkmrfKR75mSTwdUZ2xNfj7pkVqb4ipmxmI,5735
24
25
  modal/cloud_bucket_mount.pyi,sha256=CEi7vrH3kDUF4LAy4qP6tfImy2UJuFRcRbsgRNM1wo8,1403
25
- modal/cls.py,sha256=jbGYPMM1AhS3Uj8Wh2lk0YARDCul_imUDiJmbyrfSSc,32158
26
- modal/cls.pyi,sha256=P-BAQZsx8fM7Vchd8xy3Mp0RZkwkCONSZzVyn2lNNtc,8834
26
+ modal/cls.py,sha256=xHgZZAmymplw0I2YZGAA8raBboixdNKKTrnsxQZI7G8,32159
27
+ modal/cls.pyi,sha256=ImhmNPUD2zVjk7zOmEhFbdU0JQiC90B4Y9yV11bmRJs,8856
27
28
  modal/config.py,sha256=BzhZYUUwOmvVwf6x5kf0ywMC257s648dmuhsnB6g3gk,11041
28
29
  modal/container_process.py,sha256=WTqLn01dJPVkPpwR_0w_JH96ceN5mV4TGtiu1ZR2RRA,6108
29
30
  modal/container_process.pyi,sha256=dqtqBmyRpXXpRrDooESL6WBVU_1Rh6OG-66P2Hk9E5U,2666
30
- modal/dict.py,sha256=ei9jsA5iTj4UFGPJxTAed6vjd49W47ezDtj0koUmVts,12497
31
- modal/dict.pyi,sha256=VmbzxltA2vFlIHZCxpNGtd-ieXwcUwdw3iyy3WCweqU,7115
32
- modal/environments.py,sha256=wbv9ttFCbzATGfwcmvYiG608PfHovx0AQmawsg-jmic,6660
33
- modal/environments.pyi,sha256=rF7oaaELoSNuoD6qImGnIbuGPtgWwR5SlcExyYJ61hQ,3515
31
+ modal/dict.py,sha256=lKxvBcbcFZRARiqfolyRUW08x3RcozWL3MZuW2-Eu4U,12498
32
+ modal/dict.pyi,sha256=VM3dmNqQzV1piZbRncXDqkpiKpmVracmuZB_VXRkrTw,7137
33
+ modal/environments.py,sha256=20doFhRnm1fae30LMOp8hSYbIfR7yFZTtbLdo5PrSj4,6661
34
+ modal/environments.pyi,sha256=RXE3slyEr9tWpfS84Fj7iUzNJy-SujlqWOQTE8A4Qaw,3537
34
35
  modal/exception.py,sha256=4JyO-SACaLNDe2QC48EjsK8GMkZ8AgEurZ8j1YdRu8E,5263
35
36
  modal/experimental.py,sha256=npfKbyMpI41uZZs9HW_QiB3E4ykWfDXZbACXXbw6qeA,2385
36
37
  modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
37
38
  modal/file_io.pyi,sha256=NrIoB0YjIqZ8MDMe826xAnybT0ww_kxQM3iPLo82REU,8898
38
39
  modal/file_pattern_matcher.py,sha256=dSo7BMQGZBAuoBFOX-e_72HxmF3FLzjQlEtnGtJiaD4,6506
39
- modal/functions.py,sha256=3uJPbrEAWhpFfLfUnoRjGmvEUC-_wVh-8yNJBx8eVeM,68249
40
- modal/functions.pyi,sha256=LiSDgH-X7jcZ56pAoLMwo3x9Dzdp_3Sd7W5MVAJPoCg,25407
40
+ modal/functions.py,sha256=IP-6oHMmt-wUJPBWJ7Y7Vw2vqk2bYFRSQmV38T2STTI,68371
41
+ modal/functions.pyi,sha256=EcGd1uGnJVbnMmdsnANYeDjLzjaL8BREG3XgxaDPcvM,25473
41
42
  modal/gpu.py,sha256=MTxj6ql8EpgfBg8YmZ5a1cLznyuZFssX1qXbEX4LKVM,7503
42
- modal/image.py,sha256=IRNG4g6mrx7sf038yVWCBK3AU2IEJjibt0OqNvLNtGU,90921
43
- modal/image.pyi,sha256=NfZyLkl4rmxpc5fokaO4mmEeGFOwGn0AndV1vKwBdbs,26027
43
+ modal/image.py,sha256=leeY7fLfFjS0IqTi3D4cRxIDOb80BPtb3jsQfqvVJ8c,90912
44
+ modal/image.pyi,sha256=X9vj6cwBdYh8q_2cOd-2RSYNMF49ujcy0lrOXh_v1xc,26049
44
45
  modal/io_streams.py,sha256=QkQiizKRzd5bnbKQsap31LJgBYlAnj4-XkV_50xPYX0,15079
45
46
  modal/io_streams.pyi,sha256=bCCVSxkMcosYd8O3PQDDwJw7TQ8JEcnYonLJ5t27TQs,4804
46
- modal/mount.py,sha256=JVaJ9znu81WKP3Wjn3vvAIkaSnEgRSQqppXz6Fh_G6o,31798
47
- modal/mount.pyi,sha256=mcKMYwt8dX3oO8OzzKqCdh7K2EhMhWIHEPoJwzi1rl8,12194
48
- modal/network_file_system.py,sha256=INj1TfN_Fsmabmlte7anvey1epodjbMmjBW_TIJSST4,14406
49
- modal/network_file_system.pyi,sha256=61M-sdWrtaRjmuNVsvusI6kf1Qw-jUOVXvEAeOkM8Aw,7751
50
- modal/object.py,sha256=HZs3N59C6JxlMuPQWJYvrWV1FEEkH9txUovVDorVUbs,9763
51
- modal/object.pyi,sha256=MO78H9yFSE5i1gExPEwyyQzLdlshkcGHN1aQ0ylyvq0,8802
47
+ modal/mount.py,sha256=LoAKUM4iHqXDpTRoDY0RDa7LRfCXnSydHxNTuv75i38,31799
48
+ modal/mount.pyi,sha256=OIyKC7WyClkOWjpdGClmGp4pc8u4O7Rw8LctD6vMV7g,12216
49
+ modal/network_file_system.py,sha256=Jcr5Whar0MgA2YItJLJWmzHDnkkDlcOzO63TRkA64zA,14407
50
+ modal/network_file_system.pyi,sha256=lgxQ--gbxCGJ-0l_QM_Nuop6tmvU_tbSZb4rDTKBN1c,7773
51
+ modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
52
+ modal/object.pyi,sha256=xjTAMYjMm1t5SeFGHlHdyTiKKzoeg03NglufpY7tg5k,5116
52
53
  modal/output.py,sha256=N0xf4qeudEaYrslzdAl35VKV8rapstgIM2e9wO8_iy0,1967
53
54
  modal/parallel_map.py,sha256=4aoMXIrlG3wl5Ifk2YDNOQkXsGRsm6Xbfm6WtJ2t3WY,16002
54
55
  modal/parallel_map.pyi,sha256=pOhT0P3DDYlwLx0fR3PTsecA7DI8uOdXC1N8i-ZkyOY,2328
55
56
  modal/partial_function.py,sha256=PjsbsQ11lcLFy69qYXzRzM3FkX6DcPh9aoUYm7nLP6U,28295
56
57
  modal/partial_function.pyi,sha256=osYgJWVKmtz_noJ8OzBjcp7oH46PuIpURD_M7B2tXPs,9388
57
- modal/proxy.py,sha256=ZrOsuQP7dSZFq1OrIxalNnt0Zvsnp1h86Th679sSL40,1417
58
- modal/proxy.pyi,sha256=UvygdOYneLTuoDY6hVaMNCyZ947Tmx93IdLjErUqkvM,368
58
+ modal/proxy.py,sha256=NrOevrWxG3G7-zlyRzG6BcIvop7AWLeyahZxitbBaOk,1418
59
+ modal/proxy.pyi,sha256=1OEKIVUyC-xb7fHMzngakQso0nTsK60TVhXtlcMj6Wk,390
59
60
  modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
- modal/queue.py,sha256=zMUQtdAyqZzBg-2iAo3c3G54HLP7TEWfVhiQXLjewb4,18556
61
- modal/queue.pyi,sha256=gGV97pWelSSYqMV9Bl4ys3mSP7q82fS71oqSWeAwyDE,9818
61
+ modal/queue.py,sha256=HPnyJuX-THDEl2ak-xqf2lxYJMiQw4e37y4vHz6FRCg,18557
62
+ modal/queue.pyi,sha256=JhJBSRerN0l3dK9f8Ut8uslgkJWnE8s4tGB8c4SAYe4,9840
62
63
  modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
63
- modal/runner.py,sha256=mhqgRdjD5cUDpBQIokiX7OCfVblpGV6aWmZ-WvWJgGg,24114
64
+ modal/runner.py,sha256=naErUpZ9_slIscuOByD25xs0gVmSYdV_FZzaCqrD78E,24105
64
65
  modal/runner.pyi,sha256=YmP4EOCNjjkwSIPi2Gl6hF_ji_ytkxz9dw3iB9KXaOI,5275
65
66
  modal/running_app.py,sha256=v61mapYNV1-O-Uaho5EfJlryMLvIT9We0amUOSvSGx8,1188
66
- modal/sandbox.py,sha256=P7Ke6Rpj_qoVX6jdp1OzVNV05bloNkPy_TAPEJkyJhM,28677
67
- modal/sandbox.pyi,sha256=lceWDeXqzdeRc1iIuM5YmpoZlBJcVBpQO1Jc3AT1AQI,20809
67
+ modal/sandbox.py,sha256=6Z-ull5wI5WDKG6v4JVw-6CHx4Y8cMmpzp9CU3uNrtA,28678
68
+ modal/sandbox.pyi,sha256=dCyU848YARwQwoYR19o2A9L6rfB5JFz276VGQ-aZId8,20831
68
69
  modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
69
70
  modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
70
- modal/secret.py,sha256=lebVTZi4fC9PXQpLVmsvgQLzy-2Kzxv1WBD0Jr2wsxQ,10117
71
- modal/secret.pyi,sha256=0SyCyiYamr97htTmMjPZKvp5AQZKFF9GO_Ia2VcgrtA,2952
71
+ modal/secret.py,sha256=XTqrpR4rnkuUb-bth3qM_xxPqqEWorSoN9qDwjWRcXo,10118
72
+ modal/secret.pyi,sha256=W4g_BOSxafYm-K9PvFc7-li3a-rsCFNkYgHTZXr1AFA,2974
72
73
  modal/serving.py,sha256=MnVuTsimN05LfNPxuJZ4sr5s1_BPUkIsOP_VC-bkp78,4464
73
74
  modal/serving.pyi,sha256=ncV-9jY_vZYFnGs5ZnMb3ffrX8LmcLdIMHBC56xRbtE,1711
74
75
  modal/stream_type.py,sha256=A6320qoAAWhEfwOCZfGtymQTu5AfLfJXXgARqooTPvY,417
75
76
  modal/token_flow.py,sha256=LcgSce_MSQ2p7j55DPwpVRpiAtCDe8GRSEwzO7muNR8,6774
76
77
  modal/token_flow.pyi,sha256=gOYtYujrWt_JFZeiI8EmfahXPx5GCR5Na-VaPQcWgEY,1937
77
- modal/volume.py,sha256=NoqdOTrjSUEBkUj-Of_oi7I_yCuNmaLqr3TIsTWOddM,29674
78
- modal/volume.pyi,sha256=GfyVeLyM7DMiBlg0I5N6OtJl0Bzv0-rNQXkWVO0j5c0,11903
78
+ modal/volume.py,sha256=DdM9NhqNkqrk4BbAZdAgzI1jZws7NN2tYANO4OuM8hQ,29675
79
+ modal/volume.pyi,sha256=fp8B_RIHrqpYD_zyd-m2eQnpwEr8FnkwmjjFcmqChfM,11925
79
80
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
80
81
  modal/_runtime/asgi.py,sha256=c4hmaMW1pLo-cm7ouriJjieuFm4ZF6D2LMy0638sfOs,22139
81
82
  modal/_runtime/container_io_manager.py,sha256=drb-cY78h8P9Krzmmjex7uZlSSocniEF5cIXmUcvGnY,43145
82
83
  modal/_runtime/execution_context.py,sha256=E6ofm6j1POXGPxS841X3V7JU6NheVb8OkQc7JpLq4Kg,2712
83
84
  modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
84
- modal/_runtime/user_code_imports.py,sha256=n4CQOojzSdf0jwSKSy6MEnVX3IWl3t3Dq54-x9VS2Ds,14663
85
+ modal/_runtime/user_code_imports.py,sha256=c06azC0MtYHHCGWWRGxsVY0uMAjQKe1QEj-i0oXqbWM,14699
85
86
  modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
86
87
  modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
87
88
  modal/_utils/async_utils.py,sha256=9ubwMkwiDB4gzOYG2jL9j7Fs-5dxHjcifZe3r7JRg-k,25091
@@ -108,9 +109,9 @@ modal/_vendor/tblib.py,sha256=g1O7QUDd3sDoLd8YPFltkXkih7r_fyZOjgmGuligv3s,9722
108
109
  modal/cli/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
109
110
  modal/cli/_download.py,sha256=t6BXZwjTd9MgznDvbsV8rp0FZWggdzC-lUAGZU4xx1g,3984
110
111
  modal/cli/_traceback.py,sha256=QlLa_iw3fAOA-mqCqjS8qAxvNT48J3YY3errtVVc2cw,7316
111
- modal/cli/app.py,sha256=UlLT1MI-b_6wHxpXNOBYBFeoL8yL3QxBSwc2fkTUQYI,7817
112
+ modal/cli/app.py,sha256=TmUiFKAE1yc6ll8pfl-wZ2lh9crC31Fu_8_YKCX8NJc,7818
112
113
  modal/cli/config.py,sha256=pXPLmX0bIoV57rQNqIPK7V-yllj-GPRY4jiBO_EklGg,1667
113
- modal/cli/container.py,sha256=nCySVD10VJPzmX3ghTsGmpxdYeVYYMW6ofjsyt2gQcM,3667
114
+ modal/cli/container.py,sha256=FYwEgjf93j4NMorAjGbSV98i1wpebqdAeNU1wfrFp1k,3668
114
115
  modal/cli/dict.py,sha256=HaEcjfll7i3Uj3Fg56aj4407if5UljsYfr6fIq-D2W8,4589
115
116
  modal/cli/entry_point.py,sha256=aaNxFAqZcmtSjwzkYIA_Ba9CkL4cL4_i2gy5VjoXxkM,4228
116
117
  modal/cli/environment.py,sha256=Ayddkiq9jdj3XYDJ8ZmUqFpPPH8xajYlbexRkzGtUcg,4334
@@ -148,10 +149,10 @@ modal_global_objects/mounts/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0
148
149
  modal_global_objects/mounts/modal_client_package.py,sha256=W0E_yShsRojPzWm6LtIQqNVolapdnrZkm2hVEQuZK_4,767
149
150
  modal_global_objects/mounts/python_standalone.py,sha256=pEML5GaV2_0ahci_1vpfc_FnySpsfi2fhYmFF5I7IiQ,1837
150
151
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
151
- modal_proto/api.proto,sha256=JPmJxNdZPbBPumoC018p8u3boMuuvyR1d7guf_ykBEY,82787
152
+ modal_proto/api.proto,sha256=hReQ7d8S82HSWZxPDoBEyUVx83AZm8z0vD7lJSYNI84,82883
152
153
  modal_proto/api_grpc.py,sha256=U2-xzAtfSS017rCpNHmscNHLl6FSQ1mjJY8BhPXovpk,104423
153
- modal_proto/api_pb2.py,sha256=QejGk8FYbFoCHJCXwjnVEh9E5CmLNHT-e9nAqJWeZpo,302428
154
- modal_proto/api_pb2.pyi,sha256=mD3smLXwdjMl_DSI2DBCxsgGiSyBeG2082I2e0Lb9lQ,404511
154
+ modal_proto/api_pb2.py,sha256=m841BuoFLlZ6M392yed-B-xBHNH_MkBlNdK3fJmt27I,302465
155
+ modal_proto/api_pb2.pyi,sha256=6lTuMh0VgQLZ_Pe5gUyu5sf0h9dR6JtTkRriI3a_Wlc,404911
155
156
  modal_proto/api_pb2_grpc.py,sha256=upL_jT9kJXcvOq-fl6VU8OBPqvDj6bqh0UE2ipgrY4I,225767
156
157
  modal_proto/api_pb2_grpc.pyi,sha256=zEO6zm_ImjG7a8PtkdohHRsPSnrZQKzg5y1ZVi6dFF8,52620
157
158
  modal_proto/modal_api_grpc.py,sha256=f6SJgIPmHx4RJmi5vPIanOCtIFXFdxHoUqcU8wPdn8g,13952
@@ -165,10 +166,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
165
166
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
166
167
  modal_version/__init__.py,sha256=kGya2ZlItX2zB7oHORs-wvP4PG8lg_mtbi1QIK3G6SQ,470
167
168
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
168
- modal_version/_version_generated.py,sha256=zszePePZlKIur-4eGGPVqHGOUFtIr_f0irJ0aBbKJKs,149
169
- modal-0.72.21.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
170
- modal-0.72.21.dist-info/METADATA,sha256=NlMtlDzDoHG-x8LzqIcHfsmeWsidEr-JVsmJKNYqxUQ,2329
171
- modal-0.72.21.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
172
- modal-0.72.21.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
173
- modal-0.72.21.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
174
- modal-0.72.21.dist-info/RECORD,,
169
+ modal_version/_version_generated.py,sha256=7t3sZ0hizGmGicCBdVPNkmCDMo5RpTycigqk-Zz329s,149
170
+ modal-0.72.23.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
171
+ modal-0.72.23.dist-info/METADATA,sha256=rk93OQTYs6q87B8UtykTuwkILcj9nZez1ncHceRxPag,2329
172
+ modal-0.72.23.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
173
+ modal-0.72.23.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
174
+ modal-0.72.23.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
175
+ modal-0.72.23.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -2242,7 +2242,7 @@ message SandboxGetLogsRequest {
2242
2242
 
2243
2243
  message SandboxGetTaskIdRequest {
2244
2244
  string sandbox_id = 1;
2245
- float timeout = 2;
2245
+ optional float timeout = 2; // Legacy clients do not provide a timeout. New clients must always provide a timeout.
2246
2246
  bool wait_until_ready = 3; // If true, waits until the container's postStart hook has been run before returning. Useful for detecting init failures.
2247
2247
  }
2248
2248