modal 1.1.1.dev41__py3-none-any.whl → 1.1.2__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 (68) hide show
  1. modal/__main__.py +1 -2
  2. modal/_container_entrypoint.py +18 -7
  3. modal/_functions.py +135 -13
  4. modal/_object.py +13 -2
  5. modal/_partial_function.py +8 -8
  6. modal/_runtime/asgi.py +3 -2
  7. modal/_runtime/container_io_manager.py +20 -14
  8. modal/_runtime/container_io_manager.pyi +38 -13
  9. modal/_runtime/execution_context.py +18 -2
  10. modal/_runtime/execution_context.pyi +4 -1
  11. modal/_runtime/gpu_memory_snapshot.py +158 -54
  12. modal/_utils/blob_utils.py +83 -24
  13. modal/_utils/function_utils.py +4 -3
  14. modal/_utils/time_utils.py +28 -4
  15. modal/app.py +8 -4
  16. modal/app.pyi +8 -8
  17. modal/cli/dict.py +14 -11
  18. modal/cli/entry_point.py +9 -3
  19. modal/cli/launch.py +102 -4
  20. modal/cli/profile.py +1 -0
  21. modal/cli/programs/launch_instance_ssh.py +94 -0
  22. modal/cli/programs/run_marimo.py +95 -0
  23. modal/cli/queues.py +49 -19
  24. modal/cli/secret.py +45 -18
  25. modal/cli/volume.py +14 -16
  26. modal/client.pyi +2 -10
  27. modal/cls.py +12 -2
  28. modal/cls.pyi +9 -1
  29. modal/config.py +7 -7
  30. modal/dict.py +206 -12
  31. modal/dict.pyi +358 -4
  32. modal/experimental/__init__.py +130 -0
  33. modal/file_io.py +1 -1
  34. modal/file_io.pyi +2 -2
  35. modal/file_pattern_matcher.py +25 -16
  36. modal/functions.pyi +111 -11
  37. modal/image.py +9 -3
  38. modal/image.pyi +7 -7
  39. modal/mount.py +20 -13
  40. modal/mount.pyi +16 -3
  41. modal/network_file_system.py +8 -2
  42. modal/object.pyi +3 -0
  43. modal/parallel_map.py +346 -101
  44. modal/parallel_map.pyi +108 -0
  45. modal/proxy.py +2 -1
  46. modal/queue.py +199 -9
  47. modal/queue.pyi +357 -3
  48. modal/sandbox.py +6 -5
  49. modal/sandbox.pyi +17 -14
  50. modal/secret.py +196 -3
  51. modal/secret.pyi +372 -0
  52. modal/volume.py +239 -23
  53. modal/volume.pyi +405 -10
  54. {modal-1.1.1.dev41.dist-info → modal-1.1.2.dist-info}/METADATA +2 -2
  55. {modal-1.1.1.dev41.dist-info → modal-1.1.2.dist-info}/RECORD +68 -66
  56. modal_docs/mdmd/mdmd.py +11 -1
  57. modal_proto/api.proto +37 -10
  58. modal_proto/api_grpc.py +32 -0
  59. modal_proto/api_pb2.py +627 -597
  60. modal_proto/api_pb2.pyi +107 -19
  61. modal_proto/api_pb2_grpc.py +67 -2
  62. modal_proto/api_pb2_grpc.pyi +24 -8
  63. modal_proto/modal_api_grpc.py +2 -0
  64. modal_version/__init__.py +1 -1
  65. {modal-1.1.1.dev41.dist-info → modal-1.1.2.dist-info}/WHEEL +0 -0
  66. {modal-1.1.1.dev41.dist-info → modal-1.1.2.dist-info}/entry_points.txt +0 -0
  67. {modal-1.1.1.dev41.dist-info → modal-1.1.2.dist-info}/licenses/LICENSE +0 -0
  68. {modal-1.1.1.dev41.dist-info → modal-1.1.2.dist-info}/top_level.txt +0 -0
modal/queue.py CHANGED
@@ -5,24 +5,31 @@ import warnings
5
5
  from collections.abc import AsyncGenerator, AsyncIterator
6
6
  from dataclasses import dataclass
7
7
  from datetime import datetime
8
- from typing import Any, Optional
8
+ from typing import Any, Optional, Union
9
9
 
10
10
  from google.protobuf.message import Message
11
11
  from grpclib import GRPCError, Status
12
+ from synchronicity import classproperty
12
13
  from synchronicity.async_wrap import asynccontextmanager
13
14
 
14
15
  from modal_proto import api_pb2
15
16
 
16
- from ._object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
17
+ from ._object import (
18
+ EPHEMERAL_OBJECT_HEARTBEAT_SLEEP,
19
+ _get_environment_name,
20
+ _Object,
21
+ live_method,
22
+ live_method_gen,
23
+ )
17
24
  from ._resolver import Resolver
18
25
  from ._serialization import deserialize, serialize
19
26
  from ._utils.async_utils import TaskContext, synchronize_api, warn_if_generator_is_not_consumed
20
27
  from ._utils.deprecation import deprecation_warning, warn_if_passing_namespace
21
28
  from ._utils.grpc_utils import retry_transient_errors
22
29
  from ._utils.name_utils import check_object_name
23
- from ._utils.time_utils import timestamp_to_localized_dt
30
+ from ._utils.time_utils import as_timestamp, timestamp_to_localized_dt
24
31
  from .client import _Client
25
- from .exception import InvalidError, RequestSizeError
32
+ from .exception import AlreadyExistsError, InvalidError, NotFoundError, RequestSizeError
26
33
 
27
34
 
28
35
  @dataclass
@@ -37,6 +44,173 @@ class QueueInfo:
37
44
  created_by: Optional[str]
38
45
 
39
46
 
47
+ class _QueueManager:
48
+ """Namespace with methods for managing named Queue objects."""
49
+
50
+ @staticmethod
51
+ async def create(
52
+ name: str, # Name to use for the new Queue
53
+ *,
54
+ allow_existing: bool = False, # If True, no-op when the Queue already exists
55
+ environment_name: Optional[str] = None, # Uses active environment if not specified
56
+ client: Optional[_Client] = None, # Optional client with Modal credentials
57
+ ) -> None:
58
+ """Create a new Queue object.
59
+
60
+ **Examples:**
61
+
62
+ ```python notest
63
+ modal.Queue.objects.create("my-queue")
64
+ ```
65
+
66
+ Queues will be created in the active environment, or another one can be specified:
67
+
68
+ ```python notest
69
+ modal.Queue.objects.create("my-queue", environment_name="dev")
70
+ ```
71
+
72
+ By default, an error will be raised if the Queue already exists, but passing
73
+ `allow_existing=True` will make the creation attempt a no-op in this case.
74
+
75
+ ```python notest
76
+ modal.Queue.objects.create("my-queue", allow_existing=True)
77
+ ```
78
+
79
+ Note that this method does not return a local instance of the Queue. You can use
80
+ `modal.Queue.from_name` to perform a lookup after creation.
81
+
82
+ Added in v1.1.2.
83
+
84
+ """
85
+ check_object_name(name, "Queue")
86
+ client = await _Client.from_env() if client is None else client
87
+ object_creation_type = (
88
+ api_pb2.OBJECT_CREATION_TYPE_CREATE_IF_MISSING
89
+ if allow_existing
90
+ else api_pb2.OBJECT_CREATION_TYPE_CREATE_FAIL_IF_EXISTS
91
+ )
92
+ req = api_pb2.QueueGetOrCreateRequest(
93
+ deployment_name=name,
94
+ environment_name=_get_environment_name(environment_name),
95
+ object_creation_type=object_creation_type,
96
+ )
97
+ try:
98
+ await retry_transient_errors(client.stub.QueueGetOrCreate, req)
99
+ except GRPCError as exc:
100
+ if exc.status == Status.ALREADY_EXISTS and not allow_existing:
101
+ raise AlreadyExistsError(exc.message)
102
+ else:
103
+ raise
104
+
105
+ @staticmethod
106
+ async def list(
107
+ *,
108
+ max_objects: Optional[int] = None, # Limit results to this size
109
+ created_before: Optional[Union[datetime, str]] = None, # Limit based on creation date
110
+ environment_name: str = "", # Uses active environment if not specified
111
+ client: Optional[_Client] = None, # Optional client with Modal credentials
112
+ ) -> list["_Queue"]:
113
+ """Return a list of hydrated Queue objects.
114
+
115
+ **Examples:**
116
+
117
+ ```python
118
+ queues = modal.Queue.objects.list()
119
+ print([q.name for q in queues])
120
+ ```
121
+
122
+ Queues will be retreived from the active environment, or another one can be specified:
123
+
124
+ ```python notest
125
+ dev_queues = modal.Queue.objects.list(environment_name="dev")
126
+ ```
127
+
128
+ By default, all named Queues are returned, newest to oldest. It's also possible to limit the
129
+ number of results and to filter by creation date:
130
+
131
+ ```python
132
+ queues = modal.Queue.objects.list(max_objects=10, created_before="2025-01-01")
133
+ ```
134
+
135
+ Added in v1.1.2.
136
+
137
+ """
138
+ client = await _Client.from_env() if client is None else client
139
+ if max_objects is not None and max_objects < 0:
140
+ raise InvalidError("max_objects cannot be negative")
141
+
142
+ items: list[api_pb2.QueueListResponse.QueueInfo] = []
143
+
144
+ async def retrieve_page(created_before: float) -> bool:
145
+ max_page_size = 100 if max_objects is None else min(100, max_objects - len(items))
146
+ pagination = api_pb2.ListPagination(max_objects=max_page_size, created_before=created_before)
147
+ req = api_pb2.QueueListRequest(
148
+ environment_name=_get_environment_name(environment_name), pagination=pagination
149
+ )
150
+ resp = await retry_transient_errors(client.stub.QueueList, req)
151
+ items.extend(resp.queues)
152
+ finished = (len(resp.queues) < max_page_size) or (max_objects is not None and len(items) >= max_objects)
153
+ return finished
154
+
155
+ finished = await retrieve_page(as_timestamp(created_before))
156
+ while True:
157
+ if finished:
158
+ break
159
+ finished = await retrieve_page(items[-1].metadata.creation_info.created_at)
160
+
161
+ queues = [
162
+ _Queue._new_hydrated(
163
+ item.queue_id,
164
+ client,
165
+ item.metadata,
166
+ is_another_app=True,
167
+ rep=_Queue._repr(item.name, environment_name),
168
+ )
169
+ for item in items
170
+ ]
171
+ return queues[:max_objects] if max_objects is not None else queues
172
+
173
+ @staticmethod
174
+ async def delete(
175
+ name: str, # Name of the Queue to delete
176
+ *,
177
+ allow_missing: bool = False, # If True, don't raise an error if the Queue doesn't exist
178
+ environment_name: Optional[str] = None, # Uses active environment if not specified
179
+ client: Optional[_Client] = None, # Optional client with Modal credentials
180
+ ):
181
+ """Delete a named Queue.
182
+
183
+ Warning: This deletes an *entire Queue*, not just a specific entry or partition.
184
+ Deletion is irreversible and will affect any Apps currently using the Queue.
185
+
186
+ **Examples:**
187
+
188
+ ```python notest
189
+ await modal.Queue.objects.delete("my-queue")
190
+ ```
191
+
192
+ Queues will be deleted from the active environment, or another one can be specified:
193
+
194
+ ```python notest
195
+ await modal.Queue.objects.delete("my-queue", environment_name="dev")
196
+ ```
197
+
198
+ Added in v1.1.2.
199
+
200
+ """
201
+ try:
202
+ obj = await _Queue.from_name(name, environment_name=environment_name).hydrate(client)
203
+ except NotFoundError:
204
+ if not allow_missing:
205
+ raise
206
+ else:
207
+ req = api_pb2.QueueDeleteRequest(queue_id=obj.object_id)
208
+ await retry_transient_errors(obj._client.stub.QueueDelete, req)
209
+
210
+
211
+ QueueManager = synchronize_api(_QueueManager)
212
+
213
+
40
214
  class _Queue(_Object, type_prefix="qu"):
41
215
  """Distributed, FIFO queue for data flow in Modal apps.
42
216
 
@@ -116,6 +290,10 @@ class _Queue(_Object, type_prefix="qu"):
116
290
  """mdmd:hidden"""
117
291
  raise RuntimeError("Queue() is not allowed. Please use `Queue.from_name(...)` or `Queue.ephemeral()` instead.")
118
292
 
293
+ @classproperty
294
+ def objects(cls) -> _QueueManager:
295
+ return _QueueManager
296
+
119
297
  @property
120
298
  def name(self) -> Optional[str]:
121
299
  return self._name
@@ -147,7 +325,7 @@ class _Queue(_Object, type_prefix="qu"):
147
325
  cls: type["_Queue"],
148
326
  client: Optional[_Client] = None,
149
327
  environment_name: Optional[str] = None,
150
- _heartbeat_sleep: float = EPHEMERAL_OBJECT_HEARTBEAT_SLEEP,
328
+ _heartbeat_sleep: float = EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, # mdmd:line-hidden
151
329
  ) -> AsyncIterator["_Queue"]:
152
330
  """Creates a new ephemeral queue within a context manager:
153
331
 
@@ -207,7 +385,8 @@ class _Queue(_Object, type_prefix="qu"):
207
385
  response = await resolver.client.stub.QueueGetOrCreate(req)
208
386
  self._hydrate(response.queue_id, resolver.client, response.metadata)
209
387
 
210
- return _Queue._from_loader(_load, "Queue()", is_another_app=True, hydrate_lazily=True, name=name)
388
+ rep = _Queue._repr(name, environment_name)
389
+ return _Queue._from_loader(_load, rep, is_another_app=True, hydrate_lazily=True, name=name)
211
390
 
212
391
  @staticmethod
213
392
  async def lookup(
@@ -250,9 +429,20 @@ class _Queue(_Object, type_prefix="qu"):
250
429
 
251
430
  @staticmethod
252
431
  async def delete(name: str, *, client: Optional[_Client] = None, environment_name: Optional[str] = None):
253
- obj = await _Queue.from_name(name, environment_name=environment_name).hydrate(client)
254
- req = api_pb2.QueueDeleteRequest(queue_id=obj.object_id)
255
- await retry_transient_errors(obj._client.stub.QueueDelete, req)
432
+ """mdmd:hidden
433
+ Delete a named Queue.
434
+
435
+ Warning: This deletes an *entire Queue*, not just a specific entry or partition.
436
+ Deletion is irreversible and will affect any Apps currently using the Queue.
437
+
438
+ DEPRECATED: This method is deprecated; we recommend using `modal.Queue.objects.delete` instead.
439
+
440
+ """
441
+ deprecation_warning(
442
+ (2025, 8, 6),
443
+ "`modal.Queue.delete` is deprecated; we recommend using `modal.Queue.objects.delete` instead.",
444
+ )
445
+ await _Queue.objects.delete(name, environment_name=environment_name, client=client)
256
446
 
257
447
  @live_method
258
448
  async def info(self) -> QueueInfo:
modal/queue.pyi CHANGED
@@ -5,6 +5,7 @@ import modal._object
5
5
  import modal.client
6
6
  import modal.object
7
7
  import modal_proto.api_pb2
8
+ import synchronicity
8
9
  import synchronicity.combined_types
9
10
  import typing
10
11
  import typing_extensions
@@ -30,6 +31,326 @@ class QueueInfo:
30
31
  """Return self==value."""
31
32
  ...
32
33
 
34
+ class _QueueManager:
35
+ """Namespace with methods for managing named Queue objects."""
36
+ @staticmethod
37
+ async def create(
38
+ name: str,
39
+ *,
40
+ allow_existing: bool = False,
41
+ environment_name: typing.Optional[str] = None,
42
+ client: typing.Optional[modal.client._Client] = None,
43
+ ) -> None:
44
+ """Create a new Queue object.
45
+
46
+ **Examples:**
47
+
48
+ ```python notest
49
+ modal.Queue.objects.create("my-queue")
50
+ ```
51
+
52
+ Queues will be created in the active environment, or another one can be specified:
53
+
54
+ ```python notest
55
+ modal.Queue.objects.create("my-queue", environment_name="dev")
56
+ ```
57
+
58
+ By default, an error will be raised if the Queue already exists, but passing
59
+ `allow_existing=True` will make the creation attempt a no-op in this case.
60
+
61
+ ```python notest
62
+ modal.Queue.objects.create("my-queue", allow_existing=True)
63
+ ```
64
+
65
+ Note that this method does not return a local instance of the Queue. You can use
66
+ `modal.Queue.from_name` to perform a lookup after creation.
67
+
68
+ Added in v1.1.2.
69
+ """
70
+ ...
71
+
72
+ @staticmethod
73
+ async def list(
74
+ *,
75
+ max_objects: typing.Optional[int] = None,
76
+ created_before: typing.Union[datetime.datetime, str, None] = None,
77
+ environment_name: str = "",
78
+ client: typing.Optional[modal.client._Client] = None,
79
+ ) -> list[_Queue]:
80
+ """Return a list of hydrated Queue objects.
81
+
82
+ **Examples:**
83
+
84
+ ```python
85
+ queues = modal.Queue.objects.list()
86
+ print([q.name for q in queues])
87
+ ```
88
+
89
+ Queues will be retreived from the active environment, or another one can be specified:
90
+
91
+ ```python notest
92
+ dev_queues = modal.Queue.objects.list(environment_name="dev")
93
+ ```
94
+
95
+ By default, all named Queues are returned, newest to oldest. It's also possible to limit the
96
+ number of results and to filter by creation date:
97
+
98
+ ```python
99
+ queues = modal.Queue.objects.list(max_objects=10, created_before="2025-01-01")
100
+ ```
101
+
102
+ Added in v1.1.2.
103
+ """
104
+ ...
105
+
106
+ @staticmethod
107
+ async def delete(
108
+ name: str,
109
+ *,
110
+ allow_missing: bool = False,
111
+ environment_name: typing.Optional[str] = None,
112
+ client: typing.Optional[modal.client._Client] = None,
113
+ ):
114
+ """Delete a named Queue.
115
+
116
+ Warning: This deletes an *entire Queue*, not just a specific entry or partition.
117
+ Deletion is irreversible and will affect any Apps currently using the Queue.
118
+
119
+ **Examples:**
120
+
121
+ ```python notest
122
+ await modal.Queue.objects.delete("my-queue")
123
+ ```
124
+
125
+ Queues will be deleted from the active environment, or another one can be specified:
126
+
127
+ ```python notest
128
+ await modal.Queue.objects.delete("my-queue", environment_name="dev")
129
+ ```
130
+
131
+ Added in v1.1.2.
132
+ """
133
+ ...
134
+
135
+ class QueueManager:
136
+ """Namespace with methods for managing named Queue objects."""
137
+ def __init__(self, /, *args, **kwargs):
138
+ """Initialize self. See help(type(self)) for accurate signature."""
139
+ ...
140
+
141
+ class __create_spec(typing_extensions.Protocol):
142
+ def __call__(
143
+ self,
144
+ /,
145
+ name: str,
146
+ *,
147
+ allow_existing: bool = False,
148
+ environment_name: typing.Optional[str] = None,
149
+ client: typing.Optional[modal.client.Client] = None,
150
+ ) -> None:
151
+ """Create a new Queue object.
152
+
153
+ **Examples:**
154
+
155
+ ```python notest
156
+ modal.Queue.objects.create("my-queue")
157
+ ```
158
+
159
+ Queues will be created in the active environment, or another one can be specified:
160
+
161
+ ```python notest
162
+ modal.Queue.objects.create("my-queue", environment_name="dev")
163
+ ```
164
+
165
+ By default, an error will be raised if the Queue already exists, but passing
166
+ `allow_existing=True` will make the creation attempt a no-op in this case.
167
+
168
+ ```python notest
169
+ modal.Queue.objects.create("my-queue", allow_existing=True)
170
+ ```
171
+
172
+ Note that this method does not return a local instance of the Queue. You can use
173
+ `modal.Queue.from_name` to perform a lookup after creation.
174
+
175
+ Added in v1.1.2.
176
+ """
177
+ ...
178
+
179
+ async def aio(
180
+ self,
181
+ /,
182
+ name: str,
183
+ *,
184
+ allow_existing: bool = False,
185
+ environment_name: typing.Optional[str] = None,
186
+ client: typing.Optional[modal.client.Client] = None,
187
+ ) -> None:
188
+ """Create a new Queue object.
189
+
190
+ **Examples:**
191
+
192
+ ```python notest
193
+ modal.Queue.objects.create("my-queue")
194
+ ```
195
+
196
+ Queues will be created in the active environment, or another one can be specified:
197
+
198
+ ```python notest
199
+ modal.Queue.objects.create("my-queue", environment_name="dev")
200
+ ```
201
+
202
+ By default, an error will be raised if the Queue already exists, but passing
203
+ `allow_existing=True` will make the creation attempt a no-op in this case.
204
+
205
+ ```python notest
206
+ modal.Queue.objects.create("my-queue", allow_existing=True)
207
+ ```
208
+
209
+ Note that this method does not return a local instance of the Queue. You can use
210
+ `modal.Queue.from_name` to perform a lookup after creation.
211
+
212
+ Added in v1.1.2.
213
+ """
214
+ ...
215
+
216
+ create: __create_spec
217
+
218
+ class __list_spec(typing_extensions.Protocol):
219
+ def __call__(
220
+ self,
221
+ /,
222
+ *,
223
+ max_objects: typing.Optional[int] = None,
224
+ created_before: typing.Union[datetime.datetime, str, None] = None,
225
+ environment_name: str = "",
226
+ client: typing.Optional[modal.client.Client] = None,
227
+ ) -> list[Queue]:
228
+ """Return a list of hydrated Queue objects.
229
+
230
+ **Examples:**
231
+
232
+ ```python
233
+ queues = modal.Queue.objects.list()
234
+ print([q.name for q in queues])
235
+ ```
236
+
237
+ Queues will be retreived from the active environment, or another one can be specified:
238
+
239
+ ```python notest
240
+ dev_queues = modal.Queue.objects.list(environment_name="dev")
241
+ ```
242
+
243
+ By default, all named Queues are returned, newest to oldest. It's also possible to limit the
244
+ number of results and to filter by creation date:
245
+
246
+ ```python
247
+ queues = modal.Queue.objects.list(max_objects=10, created_before="2025-01-01")
248
+ ```
249
+
250
+ Added in v1.1.2.
251
+ """
252
+ ...
253
+
254
+ async def aio(
255
+ self,
256
+ /,
257
+ *,
258
+ max_objects: typing.Optional[int] = None,
259
+ created_before: typing.Union[datetime.datetime, str, None] = None,
260
+ environment_name: str = "",
261
+ client: typing.Optional[modal.client.Client] = None,
262
+ ) -> list[Queue]:
263
+ """Return a list of hydrated Queue objects.
264
+
265
+ **Examples:**
266
+
267
+ ```python
268
+ queues = modal.Queue.objects.list()
269
+ print([q.name for q in queues])
270
+ ```
271
+
272
+ Queues will be retreived from the active environment, or another one can be specified:
273
+
274
+ ```python notest
275
+ dev_queues = modal.Queue.objects.list(environment_name="dev")
276
+ ```
277
+
278
+ By default, all named Queues are returned, newest to oldest. It's also possible to limit the
279
+ number of results and to filter by creation date:
280
+
281
+ ```python
282
+ queues = modal.Queue.objects.list(max_objects=10, created_before="2025-01-01")
283
+ ```
284
+
285
+ Added in v1.1.2.
286
+ """
287
+ ...
288
+
289
+ list: __list_spec
290
+
291
+ class __delete_spec(typing_extensions.Protocol):
292
+ def __call__(
293
+ self,
294
+ /,
295
+ name: str,
296
+ *,
297
+ allow_missing: bool = False,
298
+ environment_name: typing.Optional[str] = None,
299
+ client: typing.Optional[modal.client.Client] = None,
300
+ ):
301
+ """Delete a named Queue.
302
+
303
+ Warning: This deletes an *entire Queue*, not just a specific entry or partition.
304
+ Deletion is irreversible and will affect any Apps currently using the Queue.
305
+
306
+ **Examples:**
307
+
308
+ ```python notest
309
+ await modal.Queue.objects.delete("my-queue")
310
+ ```
311
+
312
+ Queues will be deleted from the active environment, or another one can be specified:
313
+
314
+ ```python notest
315
+ await modal.Queue.objects.delete("my-queue", environment_name="dev")
316
+ ```
317
+
318
+ Added in v1.1.2.
319
+ """
320
+ ...
321
+
322
+ async def aio(
323
+ self,
324
+ /,
325
+ name: str,
326
+ *,
327
+ allow_missing: bool = False,
328
+ environment_name: typing.Optional[str] = None,
329
+ client: typing.Optional[modal.client.Client] = None,
330
+ ):
331
+ """Delete a named Queue.
332
+
333
+ Warning: This deletes an *entire Queue*, not just a specific entry or partition.
334
+ Deletion is irreversible and will affect any Apps currently using the Queue.
335
+
336
+ **Examples:**
337
+
338
+ ```python notest
339
+ await modal.Queue.objects.delete("my-queue")
340
+ ```
341
+
342
+ Queues will be deleted from the active environment, or another one can be specified:
343
+
344
+ ```python notest
345
+ await modal.Queue.objects.delete("my-queue", environment_name="dev")
346
+ ```
347
+
348
+ Added in v1.1.2.
349
+ """
350
+ ...
351
+
352
+ delete: __delete_spec
353
+
33
354
  class _Queue(modal._object._Object):
34
355
  """Distributed, FIFO queue for data flow in Modal apps.
35
356
 
@@ -109,6 +430,8 @@ class _Queue(modal._object._Object):
109
430
  """mdmd:hidden"""
110
431
  ...
111
432
 
433
+ @synchronicity.classproperty
434
+ def objects(cls) -> _QueueManager: ...
112
435
  @property
113
436
  def name(self) -> typing.Optional[str]: ...
114
437
  def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
@@ -185,7 +508,17 @@ class _Queue(modal._object._Object):
185
508
  *,
186
509
  client: typing.Optional[modal.client._Client] = None,
187
510
  environment_name: typing.Optional[str] = None,
188
- ): ...
511
+ ):
512
+ """mdmd:hidden
513
+ Delete a named Queue.
514
+
515
+ Warning: This deletes an *entire Queue*, not just a specific entry or partition.
516
+ Deletion is irreversible and will affect any Apps currently using the Queue.
517
+
518
+ DEPRECATED: This method is deprecated; we recommend using `modal.Queue.objects.delete` instead.
519
+ """
520
+ ...
521
+
189
522
  async def info(self) -> QueueInfo:
190
523
  """Return information about the Queue object."""
191
524
  ...
@@ -377,6 +710,8 @@ class Queue(modal.object.Object):
377
710
  """mdmd:hidden"""
378
711
  ...
379
712
 
713
+ @synchronicity.classproperty
714
+ def objects(cls) -> QueueManager: ...
380
715
  @property
381
716
  def name(self) -> typing.Optional[str]: ...
382
717
  def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
@@ -483,7 +818,17 @@ class Queue(modal.object.Object):
483
818
  *,
484
819
  client: typing.Optional[modal.client.Client] = None,
485
820
  environment_name: typing.Optional[str] = None,
486
- ): ...
821
+ ):
822
+ """mdmd:hidden
823
+ Delete a named Queue.
824
+
825
+ Warning: This deletes an *entire Queue*, not just a specific entry or partition.
826
+ Deletion is irreversible and will affect any Apps currently using the Queue.
827
+
828
+ DEPRECATED: This method is deprecated; we recommend using `modal.Queue.objects.delete` instead.
829
+ """
830
+ ...
831
+
487
832
  async def aio(
488
833
  self,
489
834
  /,
@@ -491,7 +836,16 @@ class Queue(modal.object.Object):
491
836
  *,
492
837
  client: typing.Optional[modal.client.Client] = None,
493
838
  environment_name: typing.Optional[str] = None,
494
- ): ...
839
+ ):
840
+ """mdmd:hidden
841
+ Delete a named Queue.
842
+
843
+ Warning: This deletes an *entire Queue*, not just a specific entry or partition.
844
+ Deletion is irreversible and will affect any Apps currently using the Queue.
845
+
846
+ DEPRECATED: This method is deprecated; we recommend using `modal.Queue.objects.delete` instead.
847
+ """
848
+ ...
495
849
 
496
850
  delete: __delete_spec
497
851
 
modal/sandbox.py CHANGED
@@ -108,7 +108,7 @@ class _Sandbox(_Object, type_prefix="sb"):
108
108
  image: _Image,
109
109
  secrets: Sequence[_Secret],
110
110
  name: Optional[str] = None,
111
- timeout: Optional[int] = None,
111
+ timeout: int = 300,
112
112
  workdir: Optional[str] = None,
113
113
  gpu: GPU_T = None,
114
114
  cloud: Optional[str] = None,
@@ -257,7 +257,7 @@ class _Sandbox(_Object, type_prefix="sb"):
257
257
  image: Optional[_Image] = None, # The image to run as the container for the sandbox.
258
258
  secrets: Sequence[_Secret] = (), # Environment variables to inject into the sandbox.
259
259
  network_file_systems: dict[Union[str, os.PathLike], _NetworkFileSystem] = {},
260
- timeout: Optional[int] = None, # Maximum execution time of the sandbox in seconds.
260
+ timeout: int = 300, # Maximum execution time of the sandbox in seconds.
261
261
  workdir: Optional[str] = None, # Working directory of the sandbox.
262
262
  gpu: GPU_T = None,
263
263
  cloud: Optional[str] = None,
@@ -296,8 +296,9 @@ class _Sandbox(_Object, type_prefix="sb"):
296
296
  environment_name: Optional[str] = None, # *DEPRECATED* Optionally override the default environment
297
297
  ) -> "_Sandbox":
298
298
  """
299
- Create a new Sandbox to run untrusted, arbitrary code. The Sandbox's corresponding container
300
- will be created asynchronously.
299
+ Create a new Sandbox to run untrusted, arbitrary code.
300
+
301
+ The Sandbox's corresponding container will be created asynchronously.
301
302
 
302
303
  **Usage**
303
304
 
@@ -354,7 +355,7 @@ class _Sandbox(_Object, type_prefix="sb"):
354
355
  secrets: Sequence[_Secret] = (), # Environment variables to inject into the sandbox.
355
356
  mounts: Sequence[_Mount] = (),
356
357
  network_file_systems: dict[Union[str, os.PathLike], _NetworkFileSystem] = {},
357
- timeout: Optional[int] = None, # Maximum execution time of the sandbox in seconds.
358
+ timeout: int = 300, # Maximum execution time of the sandbox in seconds.
358
359
  workdir: Optional[str] = None, # Working directory of the sandbox.
359
360
  gpu: GPU_T = None,
360
361
  cloud: Optional[str] = None,