modal 1.0.6.dev58__py3-none-any.whl → 1.2.3.dev7__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.

Potentially problematic release.


This version of modal might be problematic. Click here for more details.

Files changed (147) hide show
  1. modal/__main__.py +3 -4
  2. modal/_billing.py +80 -0
  3. modal/_clustered_functions.py +7 -3
  4. modal/_clustered_functions.pyi +4 -2
  5. modal/_container_entrypoint.py +41 -49
  6. modal/_functions.py +424 -195
  7. modal/_grpc_client.py +171 -0
  8. modal/_load_context.py +105 -0
  9. modal/_object.py +68 -20
  10. modal/_output.py +58 -45
  11. modal/_partial_function.py +36 -11
  12. modal/_pty.py +7 -3
  13. modal/_resolver.py +21 -35
  14. modal/_runtime/asgi.py +4 -3
  15. modal/_runtime/container_io_manager.py +301 -186
  16. modal/_runtime/container_io_manager.pyi +70 -61
  17. modal/_runtime/execution_context.py +18 -2
  18. modal/_runtime/execution_context.pyi +4 -1
  19. modal/_runtime/gpu_memory_snapshot.py +170 -63
  20. modal/_runtime/user_code_imports.py +28 -58
  21. modal/_serialization.py +57 -1
  22. modal/_utils/async_utils.py +33 -12
  23. modal/_utils/auth_token_manager.py +2 -5
  24. modal/_utils/blob_utils.py +110 -53
  25. modal/_utils/function_utils.py +49 -42
  26. modal/_utils/grpc_utils.py +80 -50
  27. modal/_utils/mount_utils.py +26 -1
  28. modal/_utils/name_utils.py +17 -3
  29. modal/_utils/task_command_router_client.py +536 -0
  30. modal/_utils/time_utils.py +34 -6
  31. modal/app.py +219 -83
  32. modal/app.pyi +229 -56
  33. modal/billing.py +5 -0
  34. modal/{requirements → builder}/2025.06.txt +1 -0
  35. modal/{requirements → builder}/PREVIEW.txt +1 -0
  36. modal/cli/_download.py +19 -3
  37. modal/cli/_traceback.py +3 -2
  38. modal/cli/app.py +4 -4
  39. modal/cli/cluster.py +15 -7
  40. modal/cli/config.py +5 -3
  41. modal/cli/container.py +7 -6
  42. modal/cli/dict.py +22 -16
  43. modal/cli/entry_point.py +12 -5
  44. modal/cli/environment.py +5 -4
  45. modal/cli/import_refs.py +3 -3
  46. modal/cli/launch.py +102 -5
  47. modal/cli/network_file_system.py +9 -13
  48. modal/cli/profile.py +3 -2
  49. modal/cli/programs/launch_instance_ssh.py +94 -0
  50. modal/cli/programs/run_jupyter.py +1 -1
  51. modal/cli/programs/run_marimo.py +95 -0
  52. modal/cli/programs/vscode.py +1 -1
  53. modal/cli/queues.py +57 -26
  54. modal/cli/run.py +58 -16
  55. modal/cli/secret.py +48 -22
  56. modal/cli/utils.py +3 -4
  57. modal/cli/volume.py +28 -25
  58. modal/client.py +13 -116
  59. modal/client.pyi +9 -91
  60. modal/cloud_bucket_mount.py +5 -3
  61. modal/cloud_bucket_mount.pyi +5 -1
  62. modal/cls.py +130 -102
  63. modal/cls.pyi +45 -85
  64. modal/config.py +29 -10
  65. modal/container_process.py +291 -13
  66. modal/container_process.pyi +95 -32
  67. modal/dict.py +282 -63
  68. modal/dict.pyi +423 -73
  69. modal/environments.py +15 -27
  70. modal/environments.pyi +5 -15
  71. modal/exception.py +8 -0
  72. modal/experimental/__init__.py +143 -38
  73. modal/experimental/flash.py +247 -78
  74. modal/experimental/flash.pyi +137 -9
  75. modal/file_io.py +14 -28
  76. modal/file_io.pyi +2 -2
  77. modal/file_pattern_matcher.py +25 -16
  78. modal/functions.pyi +134 -61
  79. modal/image.py +255 -86
  80. modal/image.pyi +300 -62
  81. modal/io_streams.py +436 -126
  82. modal/io_streams.pyi +236 -171
  83. modal/mount.py +62 -157
  84. modal/mount.pyi +45 -172
  85. modal/network_file_system.py +30 -53
  86. modal/network_file_system.pyi +16 -76
  87. modal/object.pyi +42 -8
  88. modal/parallel_map.py +821 -113
  89. modal/parallel_map.pyi +134 -0
  90. modal/partial_function.pyi +4 -1
  91. modal/proxy.py +16 -7
  92. modal/proxy.pyi +10 -2
  93. modal/queue.py +263 -61
  94. modal/queue.pyi +409 -66
  95. modal/runner.py +112 -92
  96. modal/runner.pyi +45 -27
  97. modal/sandbox.py +451 -124
  98. modal/sandbox.pyi +513 -67
  99. modal/secret.py +291 -67
  100. modal/secret.pyi +425 -19
  101. modal/serving.py +7 -11
  102. modal/serving.pyi +7 -8
  103. modal/snapshot.py +11 -8
  104. modal/token_flow.py +4 -4
  105. modal/volume.py +344 -98
  106. modal/volume.pyi +464 -68
  107. {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/METADATA +9 -8
  108. modal-1.2.3.dev7.dist-info/RECORD +195 -0
  109. modal_docs/mdmd/mdmd.py +11 -1
  110. modal_proto/api.proto +399 -67
  111. modal_proto/api_grpc.py +241 -1
  112. modal_proto/api_pb2.py +1395 -1000
  113. modal_proto/api_pb2.pyi +1239 -79
  114. modal_proto/api_pb2_grpc.py +499 -4
  115. modal_proto/api_pb2_grpc.pyi +162 -14
  116. modal_proto/modal_api_grpc.py +175 -160
  117. modal_proto/sandbox_router.proto +145 -0
  118. modal_proto/sandbox_router_grpc.py +105 -0
  119. modal_proto/sandbox_router_pb2.py +149 -0
  120. modal_proto/sandbox_router_pb2.pyi +333 -0
  121. modal_proto/sandbox_router_pb2_grpc.py +203 -0
  122. modal_proto/sandbox_router_pb2_grpc.pyi +75 -0
  123. modal_proto/task_command_router.proto +144 -0
  124. modal_proto/task_command_router_grpc.py +105 -0
  125. modal_proto/task_command_router_pb2.py +149 -0
  126. modal_proto/task_command_router_pb2.pyi +333 -0
  127. modal_proto/task_command_router_pb2_grpc.py +203 -0
  128. modal_proto/task_command_router_pb2_grpc.pyi +75 -0
  129. modal_version/__init__.py +1 -1
  130. modal-1.0.6.dev58.dist-info/RECORD +0 -183
  131. modal_proto/modal_options_grpc.py +0 -3
  132. modal_proto/options.proto +0 -19
  133. modal_proto/options_grpc.py +0 -3
  134. modal_proto/options_pb2.py +0 -35
  135. modal_proto/options_pb2.pyi +0 -20
  136. modal_proto/options_pb2_grpc.py +0 -4
  137. modal_proto/options_pb2_grpc.pyi +0 -7
  138. /modal/{requirements → builder}/2023.12.312.txt +0 -0
  139. /modal/{requirements → builder}/2023.12.txt +0 -0
  140. /modal/{requirements → builder}/2024.04.txt +0 -0
  141. /modal/{requirements → builder}/2024.10.txt +0 -0
  142. /modal/{requirements → builder}/README.md +0 -0
  143. /modal/{requirements → builder}/base-images.json +0 -0
  144. {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/WHEEL +0 -0
  145. {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/entry_points.txt +0 -0
  146. {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/licenses/LICENSE +0 -0
  147. {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/top_level.txt +0 -0
modal/sandbox.pyi CHANGED
@@ -3,6 +3,7 @@ import collections.abc
3
3
  import google.protobuf.message
4
4
  import modal._object
5
5
  import modal._tunnel
6
+ import modal._utils.task_command_router_client
6
7
  import modal.app
7
8
  import modal.client
8
9
  import modal.cloud_bucket_mount
@@ -25,7 +26,48 @@ import os
25
26
  import typing
26
27
  import typing_extensions
27
28
 
28
- def _validate_exec_args(entrypoint_args: collections.abc.Sequence[str]) -> None: ...
29
+ def _validate_exec_args(args: collections.abc.Sequence[str]) -> None: ...
30
+
31
+ class DefaultSandboxNameOverride(str):
32
+ """A singleton class that represents the default sandbox name override.
33
+
34
+ It is used to indicate that the sandbox name should not be overridden.
35
+ """
36
+ def __repr__(self) -> str:
37
+ """Return repr(self)."""
38
+ ...
39
+
40
+ _DEFAULT_SANDBOX_NAME_OVERRIDE: DefaultSandboxNameOverride
41
+
42
+ class SandboxConnectCredentials:
43
+ """Simple data structure storing credentials for making HTTP connections to a sandbox."""
44
+
45
+ url: str
46
+ token: str
47
+
48
+ def __init__(self, url: str, token: str) -> None:
49
+ """Initialize self. See help(type(self)) for accurate signature."""
50
+ ...
51
+
52
+ def __repr__(self):
53
+ """Return repr(self)."""
54
+ ...
55
+
56
+ def __eq__(self, other):
57
+ """Return self==value."""
58
+ ...
59
+
60
+ def __setattr__(self, name, value):
61
+ """Implement setattr(self, name, value)."""
62
+ ...
63
+
64
+ def __delattr__(self, name):
65
+ """Implement delattr(self, name)."""
66
+ ...
67
+
68
+ def __hash__(self):
69
+ """Return hash(self)."""
70
+ ...
29
71
 
30
72
  class _Sandbox(modal._object._Object):
31
73
  """A `Sandbox` object lets you interact with a running sandbox. This API is similar to Python's
@@ -41,13 +83,18 @@ class _Sandbox(modal._object._Object):
41
83
  _task_id: typing.Optional[str]
42
84
  _tunnels: typing.Optional[dict[int, modal._tunnel.Tunnel]]
43
85
  _enable_snapshot: bool
86
+ _command_router_client: typing.Optional[modal._utils.task_command_router_client.TaskCommandRouterClient]
44
87
 
88
+ @staticmethod
89
+ def _default_pty_info() -> modal_proto.api_pb2.PTYInfo: ...
45
90
  @staticmethod
46
91
  def _new(
47
- entrypoint_args: collections.abc.Sequence[str],
92
+ args: collections.abc.Sequence[str],
48
93
  image: modal.image._Image,
49
- secrets: collections.abc.Sequence[modal.secret._Secret],
50
- timeout: typing.Optional[int] = None,
94
+ secrets: collections.abc.Collection[modal.secret._Secret],
95
+ name: typing.Optional[str] = None,
96
+ timeout: int = 300,
97
+ idle_timeout: typing.Optional[int] = None,
51
98
  workdir: typing.Optional[str] = None,
52
99
  gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
53
100
  cloud: typing.Optional[str] = None,
@@ -62,11 +109,13 @@ class _Sandbox(modal._object._Object):
62
109
  typing.Union[str, os.PathLike],
63
110
  typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
64
111
  ] = {},
112
+ pty: bool = False,
65
113
  pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
66
114
  encrypted_ports: collections.abc.Sequence[int] = [],
67
115
  h2_ports: collections.abc.Sequence[int] = [],
68
116
  unencrypted_ports: collections.abc.Sequence[int] = [],
69
117
  proxy: typing.Optional[modal.proxy._Proxy] = None,
118
+ experimental_options: typing.Optional[dict[str, bool]] = None,
70
119
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
71
120
  enable_snapshot: bool = False,
72
121
  verbose: bool = False,
@@ -76,12 +125,15 @@ class _Sandbox(modal._object._Object):
76
125
 
77
126
  @staticmethod
78
127
  async def create(
79
- *entrypoint_args: str,
128
+ *args: str,
80
129
  app: typing.Optional[modal.app._App] = None,
130
+ name: typing.Optional[str] = None,
81
131
  image: typing.Optional[modal.image._Image] = None,
82
- secrets: collections.abc.Sequence[modal.secret._Secret] = (),
132
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
133
+ secrets: typing.Optional[collections.abc.Collection[modal.secret._Secret]] = None,
83
134
  network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system._NetworkFileSystem] = {},
84
- timeout: typing.Optional[int] = None,
135
+ timeout: int = 300,
136
+ idle_timeout: typing.Optional[int] = None,
85
137
  workdir: typing.Optional[str] = None,
86
138
  gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
87
139
  cloud: typing.Optional[str] = None,
@@ -94,19 +146,22 @@ class _Sandbox(modal._object._Object):
94
146
  typing.Union[str, os.PathLike],
95
147
  typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
96
148
  ] = {},
97
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
149
+ pty: bool = False,
98
150
  encrypted_ports: collections.abc.Sequence[int] = [],
99
151
  h2_ports: collections.abc.Sequence[int] = [],
100
152
  unencrypted_ports: collections.abc.Sequence[int] = [],
101
153
  proxy: typing.Optional[modal.proxy._Proxy] = None,
102
154
  verbose: bool = False,
155
+ experimental_options: typing.Optional[dict[str, bool]] = None,
103
156
  _experimental_enable_snapshot: bool = False,
104
157
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
105
158
  client: typing.Optional[modal.client._Client] = None,
106
159
  environment_name: typing.Optional[str] = None,
160
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
107
161
  ) -> _Sandbox:
108
- """Create a new Sandbox to run untrusted, arbitrary code. The Sandbox's corresponding container
109
- will be created asynchronously.
162
+ """Create a new Sandbox to run untrusted, arbitrary code.
163
+
164
+ The Sandbox's corresponding container will be created asynchronously.
110
165
 
111
166
  **Usage**
112
167
 
@@ -121,13 +176,16 @@ class _Sandbox(modal._object._Object):
121
176
 
122
177
  @staticmethod
123
178
  async def _create(
124
- *entrypoint_args: str,
179
+ *args: str,
125
180
  app: typing.Optional[modal.app._App] = None,
181
+ name: typing.Optional[str] = None,
126
182
  image: typing.Optional[modal.image._Image] = None,
127
- secrets: collections.abc.Sequence[modal.secret._Secret] = (),
183
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
184
+ secrets: typing.Optional[collections.abc.Collection[modal.secret._Secret]] = None,
128
185
  mounts: collections.abc.Sequence[modal.mount._Mount] = (),
129
186
  network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system._NetworkFileSystem] = {},
130
- timeout: typing.Optional[int] = None,
187
+ timeout: int = 300,
188
+ idle_timeout: typing.Optional[int] = None,
131
189
  workdir: typing.Optional[str] = None,
132
190
  gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
133
191
  cloud: typing.Optional[str] = None,
@@ -140,17 +198,42 @@ class _Sandbox(modal._object._Object):
140
198
  typing.Union[str, os.PathLike],
141
199
  typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
142
200
  ] = {},
143
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
201
+ pty: bool = False,
144
202
  encrypted_ports: collections.abc.Sequence[int] = [],
145
203
  h2_ports: collections.abc.Sequence[int] = [],
146
204
  unencrypted_ports: collections.abc.Sequence[int] = [],
147
205
  proxy: typing.Optional[modal.proxy._Proxy] = None,
206
+ experimental_options: typing.Optional[dict[str, bool]] = None,
148
207
  _experimental_enable_snapshot: bool = False,
149
208
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
150
209
  client: typing.Optional[modal.client._Client] = None,
151
210
  verbose: bool = False,
152
- ): ...
211
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
212
+ ):
213
+ """Private method used internally.
214
+
215
+ This method exposes some internal arguments (currently `mounts`) which are not in the public API.
216
+ `mounts` is currently only used by modal shell (cli) to provide a function's mounts to the
217
+ sandbox that runs the shell session.
218
+ """
219
+ ...
220
+
153
221
  def _hydrate_metadata(self, handle_metadata: typing.Optional[google.protobuf.message.Message]): ...
222
+ @staticmethod
223
+ async def from_name(
224
+ app_name: str,
225
+ name: str,
226
+ *,
227
+ environment_name: typing.Optional[str] = None,
228
+ client: typing.Optional[modal.client._Client] = None,
229
+ ) -> _Sandbox:
230
+ """Get a running Sandbox by name from a deployed App.
231
+
232
+ Raises a modal.exception.NotFoundError if no running sandbox is found with the given name.
233
+ A Sandbox's name is the `name` argument passed to `Sandbox.create`.
234
+ """
235
+ ...
236
+
154
237
  @staticmethod
155
238
  async def from_id(sandbox_id: str, client: typing.Optional[modal.client._Client] = None) -> _Sandbox:
156
239
  """Construct a Sandbox from an id and look up the Sandbox result.
@@ -159,7 +242,11 @@ class _Sandbox(modal._object._Object):
159
242
  """
160
243
  ...
161
244
 
162
- async def set_tags(self, tags: dict[str, str], *, client: typing.Optional[modal.client._Client] = None):
245
+ async def get_tags(self) -> dict[str, str]:
246
+ """Fetches any tags (key-value pairs) currently attached to this Sandbox from the server."""
247
+ ...
248
+
249
+ async def set_tags(self, tags: dict[str, str], *, client: typing.Optional[modal.client._Client] = None) -> None:
163
250
  """Set tags (key-value pairs) on the Sandbox. Tags can be used to filter results in `Sandbox.list`."""
164
251
  ...
165
252
 
@@ -187,8 +274,21 @@ class _Sandbox(modal._object._Object):
187
274
  """
188
275
  ...
189
276
 
277
+ async def create_connect_token(
278
+ self, user_metadata: typing.Union[str, dict[str, typing.Any], None] = None
279
+ ) -> SandboxConnectCredentials:
280
+ """[Alpha] Create a token for making HTTP connections to the Sandbox.
281
+
282
+ Also accepts an optional user_metadata string or dict to associate with the token. This metadata
283
+ will be added to the headers by the proxy when forwarding requests to the Sandbox.
284
+ """
285
+ ...
286
+
190
287
  async def reload_volumes(self) -> None:
191
- """Reload all Volumes mounted in the Sandbox."""
288
+ """Reload all Volumes mounted in the Sandbox.
289
+
290
+ Added in v1.1.0.
291
+ """
192
292
  ...
193
293
 
194
294
  async def terminate(self) -> None:
@@ -206,38 +306,102 @@ class _Sandbox(modal._object._Object):
206
306
  ...
207
307
 
208
308
  async def _get_task_id(self) -> str: ...
309
+ async def _get_command_router_client(
310
+ self, task_id: str
311
+ ) -> typing.Optional[modal._utils.task_command_router_client.TaskCommandRouterClient]: ...
209
312
  @typing.overload
210
313
  async def exec(
211
314
  self,
212
- *cmds: str,
213
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
315
+ *args: str,
214
316
  stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
215
317
  stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
216
318
  timeout: typing.Optional[int] = None,
217
319
  workdir: typing.Optional[str] = None,
218
- secrets: collections.abc.Sequence[modal.secret._Secret] = (),
320
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
321
+ secrets: typing.Optional[collections.abc.Collection[modal.secret._Secret]] = None,
219
322
  text: typing.Literal[True] = True,
220
323
  bufsize: typing.Literal[-1, 1] = -1,
324
+ pty: bool = False,
325
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
221
326
  _pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
222
327
  ) -> modal.container_process._ContainerProcess[str]: ...
223
328
  @typing.overload
224
329
  async def exec(
225
330
  self,
226
- *cmds: str,
227
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
331
+ *args: str,
228
332
  stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
229
333
  stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
230
334
  timeout: typing.Optional[int] = None,
231
335
  workdir: typing.Optional[str] = None,
232
- secrets: collections.abc.Sequence[modal.secret._Secret] = (),
336
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
337
+ secrets: typing.Optional[collections.abc.Collection[modal.secret._Secret]] = None,
233
338
  text: typing.Literal[False] = False,
234
339
  bufsize: typing.Literal[-1, 1] = -1,
340
+ pty: bool = False,
341
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
235
342
  _pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
236
343
  ) -> modal.container_process._ContainerProcess[bytes]: ...
344
+ async def _exec(
345
+ self,
346
+ *args: str,
347
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
348
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
349
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
350
+ timeout: typing.Optional[int] = None,
351
+ workdir: typing.Optional[str] = None,
352
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
353
+ secrets: typing.Optional[collections.abc.Collection[modal.secret._Secret]] = None,
354
+ text: bool = True,
355
+ bufsize: typing.Literal[-1, 1] = -1,
356
+ ) -> typing.Union[modal.container_process._ContainerProcess[bytes], modal.container_process._ContainerProcess[str]]:
357
+ """Private method used internally.
358
+
359
+ This method exposes some internal arguments (currently `pty_info`) which are not in the public API.
360
+ """
361
+ ...
362
+
363
+ async def _exec_through_server(
364
+ self,
365
+ *args: str,
366
+ task_id: str,
367
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
368
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
369
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
370
+ timeout: typing.Optional[int] = None,
371
+ workdir: typing.Optional[str] = None,
372
+ secret_ids: typing.Optional[collections.abc.Collection[str]] = None,
373
+ text: bool = True,
374
+ bufsize: typing.Literal[-1, 1] = -1,
375
+ runtime_debug: bool = False,
376
+ ) -> typing.Union[modal.container_process._ContainerProcess[bytes], modal.container_process._ContainerProcess[str]]:
377
+ """Execute a command through the Modal server."""
378
+ ...
379
+
380
+ async def _exec_through_command_router(
381
+ self,
382
+ *args: str,
383
+ task_id: str,
384
+ command_router_client: modal._utils.task_command_router_client.TaskCommandRouterClient,
385
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
386
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
387
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
388
+ timeout: typing.Optional[int] = None,
389
+ workdir: typing.Optional[str] = None,
390
+ secret_ids: typing.Optional[collections.abc.Collection[str]] = None,
391
+ text: bool = True,
392
+ bufsize: typing.Literal[-1, 1] = -1,
393
+ runtime_debug: bool = False,
394
+ ) -> typing.Union[modal.container_process._ContainerProcess[bytes], modal.container_process._ContainerProcess[str]]:
395
+ """Execute a command through a task command router running on the Modal worker."""
396
+ ...
397
+
237
398
  async def _experimental_snapshot(self) -> modal.snapshot._SandboxSnapshot: ...
238
399
  @staticmethod
239
400
  async def _experimental_from_snapshot(
240
- snapshot: modal.snapshot._SandboxSnapshot, client: typing.Optional[modal.client._Client] = None
401
+ snapshot: modal.snapshot._SandboxSnapshot,
402
+ client: typing.Optional[modal.client._Client] = None,
403
+ *,
404
+ name: typing.Optional[str] = _DEFAULT_SANDBOX_NAME_OVERRIDE,
241
405
  ): ...
242
406
  @typing.overload
243
407
  async def open(self, path: str, mode: _typeshed.OpenTextMode) -> modal.file_io._FileIO[str]: ...
@@ -319,17 +483,22 @@ class Sandbox(modal.object.Object):
319
483
  _task_id: typing.Optional[str]
320
484
  _tunnels: typing.Optional[dict[int, modal._tunnel.Tunnel]]
321
485
  _enable_snapshot: bool
486
+ _command_router_client: typing.Optional[modal._utils.task_command_router_client.TaskCommandRouterClient]
322
487
 
323
488
  def __init__(self, *args, **kwargs):
324
489
  """mdmd:hidden"""
325
490
  ...
326
491
 
492
+ @staticmethod
493
+ def _default_pty_info() -> modal_proto.api_pb2.PTYInfo: ...
327
494
  @staticmethod
328
495
  def _new(
329
- entrypoint_args: collections.abc.Sequence[str],
496
+ args: collections.abc.Sequence[str],
330
497
  image: modal.image.Image,
331
- secrets: collections.abc.Sequence[modal.secret.Secret],
332
- timeout: typing.Optional[int] = None,
498
+ secrets: collections.abc.Collection[modal.secret.Secret],
499
+ name: typing.Optional[str] = None,
500
+ timeout: int = 300,
501
+ idle_timeout: typing.Optional[int] = None,
333
502
  workdir: typing.Optional[str] = None,
334
503
  gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
335
504
  cloud: typing.Optional[str] = None,
@@ -343,11 +512,13 @@ class Sandbox(modal.object.Object):
343
512
  volumes: dict[
344
513
  typing.Union[str, os.PathLike], typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount]
345
514
  ] = {},
515
+ pty: bool = False,
346
516
  pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
347
517
  encrypted_ports: collections.abc.Sequence[int] = [],
348
518
  h2_ports: collections.abc.Sequence[int] = [],
349
519
  unencrypted_ports: collections.abc.Sequence[int] = [],
350
520
  proxy: typing.Optional[modal.proxy.Proxy] = None,
521
+ experimental_options: typing.Optional[dict[str, bool]] = None,
351
522
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
352
523
  enable_snapshot: bool = False,
353
524
  verbose: bool = False,
@@ -359,14 +530,17 @@ class Sandbox(modal.object.Object):
359
530
  def __call__(
360
531
  self,
361
532
  /,
362
- *entrypoint_args: str,
533
+ *args: str,
363
534
  app: typing.Optional[modal.app.App] = None,
535
+ name: typing.Optional[str] = None,
364
536
  image: typing.Optional[modal.image.Image] = None,
365
- secrets: collections.abc.Sequence[modal.secret.Secret] = (),
537
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
538
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
366
539
  network_file_systems: dict[
367
540
  typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
368
541
  ] = {},
369
- timeout: typing.Optional[int] = None,
542
+ timeout: int = 300,
543
+ idle_timeout: typing.Optional[int] = None,
370
544
  workdir: typing.Optional[str] = None,
371
545
  gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
372
546
  cloud: typing.Optional[str] = None,
@@ -379,19 +553,22 @@ class Sandbox(modal.object.Object):
379
553
  typing.Union[str, os.PathLike],
380
554
  typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
381
555
  ] = {},
382
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
556
+ pty: bool = False,
383
557
  encrypted_ports: collections.abc.Sequence[int] = [],
384
558
  h2_ports: collections.abc.Sequence[int] = [],
385
559
  unencrypted_ports: collections.abc.Sequence[int] = [],
386
560
  proxy: typing.Optional[modal.proxy.Proxy] = None,
387
561
  verbose: bool = False,
562
+ experimental_options: typing.Optional[dict[str, bool]] = None,
388
563
  _experimental_enable_snapshot: bool = False,
389
564
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
390
565
  client: typing.Optional[modal.client.Client] = None,
391
566
  environment_name: typing.Optional[str] = None,
567
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
392
568
  ) -> Sandbox:
393
- """Create a new Sandbox to run untrusted, arbitrary code. The Sandbox's corresponding container
394
- will be created asynchronously.
569
+ """Create a new Sandbox to run untrusted, arbitrary code.
570
+
571
+ The Sandbox's corresponding container will be created asynchronously.
395
572
 
396
573
  **Usage**
397
574
 
@@ -407,14 +584,17 @@ class Sandbox(modal.object.Object):
407
584
  async def aio(
408
585
  self,
409
586
  /,
410
- *entrypoint_args: str,
587
+ *args: str,
411
588
  app: typing.Optional[modal.app.App] = None,
589
+ name: typing.Optional[str] = None,
412
590
  image: typing.Optional[modal.image.Image] = None,
413
- secrets: collections.abc.Sequence[modal.secret.Secret] = (),
591
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
592
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
414
593
  network_file_systems: dict[
415
594
  typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
416
595
  ] = {},
417
- timeout: typing.Optional[int] = None,
596
+ timeout: int = 300,
597
+ idle_timeout: typing.Optional[int] = None,
418
598
  workdir: typing.Optional[str] = None,
419
599
  gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
420
600
  cloud: typing.Optional[str] = None,
@@ -427,19 +607,22 @@ class Sandbox(modal.object.Object):
427
607
  typing.Union[str, os.PathLike],
428
608
  typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
429
609
  ] = {},
430
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
610
+ pty: bool = False,
431
611
  encrypted_ports: collections.abc.Sequence[int] = [],
432
612
  h2_ports: collections.abc.Sequence[int] = [],
433
613
  unencrypted_ports: collections.abc.Sequence[int] = [],
434
614
  proxy: typing.Optional[modal.proxy.Proxy] = None,
435
615
  verbose: bool = False,
616
+ experimental_options: typing.Optional[dict[str, bool]] = None,
436
617
  _experimental_enable_snapshot: bool = False,
437
618
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
438
619
  client: typing.Optional[modal.client.Client] = None,
439
620
  environment_name: typing.Optional[str] = None,
621
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
440
622
  ) -> Sandbox:
441
- """Create a new Sandbox to run untrusted, arbitrary code. The Sandbox's corresponding container
442
- will be created asynchronously.
623
+ """Create a new Sandbox to run untrusted, arbitrary code.
624
+
625
+ The Sandbox's corresponding container will be created asynchronously.
443
626
 
444
627
  **Usage**
445
628
 
@@ -458,15 +641,18 @@ class Sandbox(modal.object.Object):
458
641
  def __call__(
459
642
  self,
460
643
  /,
461
- *entrypoint_args: str,
644
+ *args: str,
462
645
  app: typing.Optional[modal.app.App] = None,
646
+ name: typing.Optional[str] = None,
463
647
  image: typing.Optional[modal.image.Image] = None,
464
- secrets: collections.abc.Sequence[modal.secret.Secret] = (),
648
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
649
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
465
650
  mounts: collections.abc.Sequence[modal.mount.Mount] = (),
466
651
  network_file_systems: dict[
467
652
  typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
468
653
  ] = {},
469
- timeout: typing.Optional[int] = None,
654
+ timeout: int = 300,
655
+ idle_timeout: typing.Optional[int] = None,
470
656
  workdir: typing.Optional[str] = None,
471
657
  gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
472
658
  cloud: typing.Optional[str] = None,
@@ -479,28 +665,41 @@ class Sandbox(modal.object.Object):
479
665
  typing.Union[str, os.PathLike],
480
666
  typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
481
667
  ] = {},
482
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
668
+ pty: bool = False,
483
669
  encrypted_ports: collections.abc.Sequence[int] = [],
484
670
  h2_ports: collections.abc.Sequence[int] = [],
485
671
  unencrypted_ports: collections.abc.Sequence[int] = [],
486
672
  proxy: typing.Optional[modal.proxy.Proxy] = None,
673
+ experimental_options: typing.Optional[dict[str, bool]] = None,
487
674
  _experimental_enable_snapshot: bool = False,
488
675
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
489
676
  client: typing.Optional[modal.client.Client] = None,
490
677
  verbose: bool = False,
491
- ): ...
678
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
679
+ ):
680
+ """Private method used internally.
681
+
682
+ This method exposes some internal arguments (currently `mounts`) which are not in the public API.
683
+ `mounts` is currently only used by modal shell (cli) to provide a function's mounts to the
684
+ sandbox that runs the shell session.
685
+ """
686
+ ...
687
+
492
688
  async def aio(
493
689
  self,
494
690
  /,
495
- *entrypoint_args: str,
691
+ *args: str,
496
692
  app: typing.Optional[modal.app.App] = None,
693
+ name: typing.Optional[str] = None,
497
694
  image: typing.Optional[modal.image.Image] = None,
498
- secrets: collections.abc.Sequence[modal.secret.Secret] = (),
695
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
696
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
499
697
  mounts: collections.abc.Sequence[modal.mount.Mount] = (),
500
698
  network_file_systems: dict[
501
699
  typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
502
700
  ] = {},
503
- timeout: typing.Optional[int] = None,
701
+ timeout: int = 300,
702
+ idle_timeout: typing.Optional[int] = None,
504
703
  workdir: typing.Optional[str] = None,
505
704
  gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
506
705
  cloud: typing.Optional[str] = None,
@@ -513,21 +712,65 @@ class Sandbox(modal.object.Object):
513
712
  typing.Union[str, os.PathLike],
514
713
  typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
515
714
  ] = {},
516
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
715
+ pty: bool = False,
517
716
  encrypted_ports: collections.abc.Sequence[int] = [],
518
717
  h2_ports: collections.abc.Sequence[int] = [],
519
718
  unencrypted_ports: collections.abc.Sequence[int] = [],
520
719
  proxy: typing.Optional[modal.proxy.Proxy] = None,
720
+ experimental_options: typing.Optional[dict[str, bool]] = None,
521
721
  _experimental_enable_snapshot: bool = False,
522
722
  _experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
523
723
  client: typing.Optional[modal.client.Client] = None,
524
724
  verbose: bool = False,
525
- ): ...
725
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
726
+ ):
727
+ """Private method used internally.
728
+
729
+ This method exposes some internal arguments (currently `mounts`) which are not in the public API.
730
+ `mounts` is currently only used by modal shell (cli) to provide a function's mounts to the
731
+ sandbox that runs the shell session.
732
+ """
733
+ ...
526
734
 
527
735
  _create: ___create_spec
528
736
 
529
737
  def _hydrate_metadata(self, handle_metadata: typing.Optional[google.protobuf.message.Message]): ...
530
738
 
739
+ class __from_name_spec(typing_extensions.Protocol):
740
+ def __call__(
741
+ self,
742
+ /,
743
+ app_name: str,
744
+ name: str,
745
+ *,
746
+ environment_name: typing.Optional[str] = None,
747
+ client: typing.Optional[modal.client.Client] = None,
748
+ ) -> Sandbox:
749
+ """Get a running Sandbox by name from a deployed App.
750
+
751
+ Raises a modal.exception.NotFoundError if no running sandbox is found with the given name.
752
+ A Sandbox's name is the `name` argument passed to `Sandbox.create`.
753
+ """
754
+ ...
755
+
756
+ async def aio(
757
+ self,
758
+ /,
759
+ app_name: str,
760
+ name: str,
761
+ *,
762
+ environment_name: typing.Optional[str] = None,
763
+ client: typing.Optional[modal.client.Client] = None,
764
+ ) -> Sandbox:
765
+ """Get a running Sandbox by name from a deployed App.
766
+
767
+ Raises a modal.exception.NotFoundError if no running sandbox is found with the given name.
768
+ A Sandbox's name is the `name` argument passed to `Sandbox.create`.
769
+ """
770
+ ...
771
+
772
+ from_name: __from_name_spec
773
+
531
774
  class __from_id_spec(typing_extensions.Protocol):
532
775
  def __call__(self, /, sandbox_id: str, client: typing.Optional[modal.client.Client] = None) -> Sandbox:
533
776
  """Construct a Sandbox from an id and look up the Sandbox result.
@@ -545,12 +788,23 @@ class Sandbox(modal.object.Object):
545
788
 
546
789
  from_id: __from_id_spec
547
790
 
791
+ class __get_tags_spec(typing_extensions.Protocol[SUPERSELF]):
792
+ def __call__(self, /) -> dict[str, str]:
793
+ """Fetches any tags (key-value pairs) currently attached to this Sandbox from the server."""
794
+ ...
795
+
796
+ async def aio(self, /) -> dict[str, str]:
797
+ """Fetches any tags (key-value pairs) currently attached to this Sandbox from the server."""
798
+ ...
799
+
800
+ get_tags: __get_tags_spec[typing_extensions.Self]
801
+
548
802
  class __set_tags_spec(typing_extensions.Protocol[SUPERSELF]):
549
- def __call__(self, /, tags: dict[str, str], *, client: typing.Optional[modal.client.Client] = None):
803
+ def __call__(self, /, tags: dict[str, str], *, client: typing.Optional[modal.client.Client] = None) -> None:
550
804
  """Set tags (key-value pairs) on the Sandbox. Tags can be used to filter results in `Sandbox.list`."""
551
805
  ...
552
806
 
553
- async def aio(self, /, tags: dict[str, str], *, client: typing.Optional[modal.client.Client] = None):
807
+ async def aio(self, /, tags: dict[str, str], *, client: typing.Optional[modal.client.Client] = None) -> None:
554
808
  """Set tags (key-value pairs) on the Sandbox. Tags can be used to filter results in `Sandbox.list`."""
555
809
  ...
556
810
 
@@ -613,13 +867,42 @@ class Sandbox(modal.object.Object):
613
867
 
614
868
  tunnels: __tunnels_spec[typing_extensions.Self]
615
869
 
870
+ class __create_connect_token_spec(typing_extensions.Protocol[SUPERSELF]):
871
+ def __call__(
872
+ self, /, user_metadata: typing.Union[str, dict[str, typing.Any], None] = None
873
+ ) -> SandboxConnectCredentials:
874
+ """[Alpha] Create a token for making HTTP connections to the Sandbox.
875
+
876
+ Also accepts an optional user_metadata string or dict to associate with the token. This metadata
877
+ will be added to the headers by the proxy when forwarding requests to the Sandbox.
878
+ """
879
+ ...
880
+
881
+ async def aio(
882
+ self, /, user_metadata: typing.Union[str, dict[str, typing.Any], None] = None
883
+ ) -> SandboxConnectCredentials:
884
+ """[Alpha] Create a token for making HTTP connections to the Sandbox.
885
+
886
+ Also accepts an optional user_metadata string or dict to associate with the token. This metadata
887
+ will be added to the headers by the proxy when forwarding requests to the Sandbox.
888
+ """
889
+ ...
890
+
891
+ create_connect_token: __create_connect_token_spec[typing_extensions.Self]
892
+
616
893
  class __reload_volumes_spec(typing_extensions.Protocol[SUPERSELF]):
617
894
  def __call__(self, /) -> None:
618
- """Reload all Volumes mounted in the Sandbox."""
895
+ """Reload all Volumes mounted in the Sandbox.
896
+
897
+ Added in v1.1.0.
898
+ """
619
899
  ...
620
900
 
621
901
  async def aio(self, /) -> None:
622
- """Reload all Volumes mounted in the Sandbox."""
902
+ """Reload all Volumes mounted in the Sandbox.
903
+
904
+ Added in v1.1.0.
905
+ """
623
906
  ...
624
907
 
625
908
  reload_volumes: __reload_volumes_spec[typing_extensions.Self]
@@ -664,70 +947,223 @@ class Sandbox(modal.object.Object):
664
947
 
665
948
  _get_task_id: ___get_task_id_spec[typing_extensions.Self]
666
949
 
950
+ class ___get_command_router_client_spec(typing_extensions.Protocol[SUPERSELF]):
951
+ def __call__(
952
+ self, /, task_id: str
953
+ ) -> typing.Optional[modal._utils.task_command_router_client.TaskCommandRouterClient]: ...
954
+ async def aio(
955
+ self, /, task_id: str
956
+ ) -> typing.Optional[modal._utils.task_command_router_client.TaskCommandRouterClient]: ...
957
+
958
+ _get_command_router_client: ___get_command_router_client_spec[typing_extensions.Self]
959
+
667
960
  class __exec_spec(typing_extensions.Protocol[SUPERSELF]):
668
961
  @typing.overload
669
962
  def __call__(
670
963
  self,
671
964
  /,
672
- *cmds: str,
673
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
965
+ *args: str,
674
966
  stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
675
967
  stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
676
968
  timeout: typing.Optional[int] = None,
677
969
  workdir: typing.Optional[str] = None,
678
- secrets: collections.abc.Sequence[modal.secret.Secret] = (),
970
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
971
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
679
972
  text: typing.Literal[True] = True,
680
973
  bufsize: typing.Literal[-1, 1] = -1,
974
+ pty: bool = False,
975
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
681
976
  _pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
682
977
  ) -> modal.container_process.ContainerProcess[str]: ...
683
978
  @typing.overload
684
979
  def __call__(
685
980
  self,
686
981
  /,
687
- *cmds: str,
688
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
982
+ *args: str,
689
983
  stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
690
984
  stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
691
985
  timeout: typing.Optional[int] = None,
692
986
  workdir: typing.Optional[str] = None,
693
- secrets: collections.abc.Sequence[modal.secret.Secret] = (),
987
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
988
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
694
989
  text: typing.Literal[False] = False,
695
990
  bufsize: typing.Literal[-1, 1] = -1,
991
+ pty: bool = False,
992
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
696
993
  _pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
697
994
  ) -> modal.container_process.ContainerProcess[bytes]: ...
698
995
  @typing.overload
699
996
  async def aio(
700
997
  self,
701
998
  /,
702
- *cmds: str,
703
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
999
+ *args: str,
704
1000
  stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
705
1001
  stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
706
1002
  timeout: typing.Optional[int] = None,
707
1003
  workdir: typing.Optional[str] = None,
708
- secrets: collections.abc.Sequence[modal.secret.Secret] = (),
1004
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
1005
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
709
1006
  text: typing.Literal[True] = True,
710
1007
  bufsize: typing.Literal[-1, 1] = -1,
1008
+ pty: bool = False,
1009
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
711
1010
  _pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
712
1011
  ) -> modal.container_process.ContainerProcess[str]: ...
713
1012
  @typing.overload
714
1013
  async def aio(
715
1014
  self,
716
1015
  /,
717
- *cmds: str,
718
- pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
1016
+ *args: str,
719
1017
  stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
720
1018
  stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
721
1019
  timeout: typing.Optional[int] = None,
722
1020
  workdir: typing.Optional[str] = None,
723
- secrets: collections.abc.Sequence[modal.secret.Secret] = (),
1021
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
1022
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
724
1023
  text: typing.Literal[False] = False,
725
1024
  bufsize: typing.Literal[-1, 1] = -1,
1025
+ pty: bool = False,
1026
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
726
1027
  _pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
727
1028
  ) -> modal.container_process.ContainerProcess[bytes]: ...
728
1029
 
729
1030
  exec: __exec_spec[typing_extensions.Self]
730
1031
 
1032
+ class ___exec_spec(typing_extensions.Protocol[SUPERSELF]):
1033
+ def __call__(
1034
+ self,
1035
+ /,
1036
+ *args: str,
1037
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
1038
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1039
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1040
+ timeout: typing.Optional[int] = None,
1041
+ workdir: typing.Optional[str] = None,
1042
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
1043
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
1044
+ text: bool = True,
1045
+ bufsize: typing.Literal[-1, 1] = -1,
1046
+ ) -> typing.Union[
1047
+ modal.container_process.ContainerProcess[bytes], modal.container_process.ContainerProcess[str]
1048
+ ]:
1049
+ """Private method used internally.
1050
+
1051
+ This method exposes some internal arguments (currently `pty_info`) which are not in the public API.
1052
+ """
1053
+ ...
1054
+
1055
+ async def aio(
1056
+ self,
1057
+ /,
1058
+ *args: str,
1059
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
1060
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1061
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1062
+ timeout: typing.Optional[int] = None,
1063
+ workdir: typing.Optional[str] = None,
1064
+ env: typing.Optional[dict[str, typing.Optional[str]]] = None,
1065
+ secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
1066
+ text: bool = True,
1067
+ bufsize: typing.Literal[-1, 1] = -1,
1068
+ ) -> typing.Union[
1069
+ modal.container_process.ContainerProcess[bytes], modal.container_process.ContainerProcess[str]
1070
+ ]:
1071
+ """Private method used internally.
1072
+
1073
+ This method exposes some internal arguments (currently `pty_info`) which are not in the public API.
1074
+ """
1075
+ ...
1076
+
1077
+ _exec: ___exec_spec[typing_extensions.Self]
1078
+
1079
+ class ___exec_through_server_spec(typing_extensions.Protocol[SUPERSELF]):
1080
+ def __call__(
1081
+ self,
1082
+ /,
1083
+ *args: str,
1084
+ task_id: str,
1085
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
1086
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1087
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1088
+ timeout: typing.Optional[int] = None,
1089
+ workdir: typing.Optional[str] = None,
1090
+ secret_ids: typing.Optional[collections.abc.Collection[str]] = None,
1091
+ text: bool = True,
1092
+ bufsize: typing.Literal[-1, 1] = -1,
1093
+ runtime_debug: bool = False,
1094
+ ) -> typing.Union[
1095
+ modal.container_process.ContainerProcess[bytes], modal.container_process.ContainerProcess[str]
1096
+ ]:
1097
+ """Execute a command through the Modal server."""
1098
+ ...
1099
+
1100
+ async def aio(
1101
+ self,
1102
+ /,
1103
+ *args: str,
1104
+ task_id: str,
1105
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
1106
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1107
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1108
+ timeout: typing.Optional[int] = None,
1109
+ workdir: typing.Optional[str] = None,
1110
+ secret_ids: typing.Optional[collections.abc.Collection[str]] = None,
1111
+ text: bool = True,
1112
+ bufsize: typing.Literal[-1, 1] = -1,
1113
+ runtime_debug: bool = False,
1114
+ ) -> typing.Union[
1115
+ modal.container_process.ContainerProcess[bytes], modal.container_process.ContainerProcess[str]
1116
+ ]:
1117
+ """Execute a command through the Modal server."""
1118
+ ...
1119
+
1120
+ _exec_through_server: ___exec_through_server_spec[typing_extensions.Self]
1121
+
1122
+ class ___exec_through_command_router_spec(typing_extensions.Protocol[SUPERSELF]):
1123
+ def __call__(
1124
+ self,
1125
+ /,
1126
+ *args: str,
1127
+ task_id: str,
1128
+ command_router_client: modal._utils.task_command_router_client.TaskCommandRouterClient,
1129
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
1130
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1131
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1132
+ timeout: typing.Optional[int] = None,
1133
+ workdir: typing.Optional[str] = None,
1134
+ secret_ids: typing.Optional[collections.abc.Collection[str]] = None,
1135
+ text: bool = True,
1136
+ bufsize: typing.Literal[-1, 1] = -1,
1137
+ runtime_debug: bool = False,
1138
+ ) -> typing.Union[
1139
+ modal.container_process.ContainerProcess[bytes], modal.container_process.ContainerProcess[str]
1140
+ ]:
1141
+ """Execute a command through a task command router running on the Modal worker."""
1142
+ ...
1143
+
1144
+ async def aio(
1145
+ self,
1146
+ /,
1147
+ *args: str,
1148
+ task_id: str,
1149
+ command_router_client: modal._utils.task_command_router_client.TaskCommandRouterClient,
1150
+ pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
1151
+ stdout: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1152
+ stderr: modal.stream_type.StreamType = modal.stream_type.StreamType.PIPE,
1153
+ timeout: typing.Optional[int] = None,
1154
+ workdir: typing.Optional[str] = None,
1155
+ secret_ids: typing.Optional[collections.abc.Collection[str]] = None,
1156
+ text: bool = True,
1157
+ bufsize: typing.Literal[-1, 1] = -1,
1158
+ runtime_debug: bool = False,
1159
+ ) -> typing.Union[
1160
+ modal.container_process.ContainerProcess[bytes], modal.container_process.ContainerProcess[str]
1161
+ ]:
1162
+ """Execute a command through a task command router running on the Modal worker."""
1163
+ ...
1164
+
1165
+ _exec_through_command_router: ___exec_through_command_router_spec[typing_extensions.Self]
1166
+
731
1167
  class ___experimental_snapshot_spec(typing_extensions.Protocol[SUPERSELF]):
732
1168
  def __call__(self, /) -> modal.snapshot.SandboxSnapshot: ...
733
1169
  async def aio(self, /) -> modal.snapshot.SandboxSnapshot: ...
@@ -736,10 +1172,20 @@ class Sandbox(modal.object.Object):
736
1172
 
737
1173
  class ___experimental_from_snapshot_spec(typing_extensions.Protocol):
738
1174
  def __call__(
739
- self, /, snapshot: modal.snapshot.SandboxSnapshot, client: typing.Optional[modal.client.Client] = None
1175
+ self,
1176
+ /,
1177
+ snapshot: modal.snapshot.SandboxSnapshot,
1178
+ client: typing.Optional[modal.client.Client] = None,
1179
+ *,
1180
+ name: typing.Optional[str] = _DEFAULT_SANDBOX_NAME_OVERRIDE,
740
1181
  ): ...
741
1182
  async def aio(
742
- self, /, snapshot: modal.snapshot.SandboxSnapshot, client: typing.Optional[modal.client.Client] = None
1183
+ self,
1184
+ /,
1185
+ snapshot: modal.snapshot.SandboxSnapshot,
1186
+ client: typing.Optional[modal.client.Client] = None,
1187
+ *,
1188
+ name: typing.Optional[str] = _DEFAULT_SANDBOX_NAME_OVERRIDE,
743
1189
  ): ...
744
1190
 
745
1191
  _experimental_from_snapshot: ___experimental_from_snapshot_spec