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.
- modal/__main__.py +3 -4
- modal/_billing.py +80 -0
- modal/_clustered_functions.py +7 -3
- modal/_clustered_functions.pyi +4 -2
- modal/_container_entrypoint.py +41 -49
- modal/_functions.py +424 -195
- modal/_grpc_client.py +171 -0
- modal/_load_context.py +105 -0
- modal/_object.py +68 -20
- modal/_output.py +58 -45
- modal/_partial_function.py +36 -11
- modal/_pty.py +7 -3
- modal/_resolver.py +21 -35
- modal/_runtime/asgi.py +4 -3
- modal/_runtime/container_io_manager.py +301 -186
- modal/_runtime/container_io_manager.pyi +70 -61
- modal/_runtime/execution_context.py +18 -2
- modal/_runtime/execution_context.pyi +4 -1
- modal/_runtime/gpu_memory_snapshot.py +170 -63
- modal/_runtime/user_code_imports.py +28 -58
- modal/_serialization.py +57 -1
- modal/_utils/async_utils.py +33 -12
- modal/_utils/auth_token_manager.py +2 -5
- modal/_utils/blob_utils.py +110 -53
- modal/_utils/function_utils.py +49 -42
- modal/_utils/grpc_utils.py +80 -50
- modal/_utils/mount_utils.py +26 -1
- modal/_utils/name_utils.py +17 -3
- modal/_utils/task_command_router_client.py +536 -0
- modal/_utils/time_utils.py +34 -6
- modal/app.py +219 -83
- modal/app.pyi +229 -56
- modal/billing.py +5 -0
- modal/{requirements → builder}/2025.06.txt +1 -0
- modal/{requirements → builder}/PREVIEW.txt +1 -0
- modal/cli/_download.py +19 -3
- modal/cli/_traceback.py +3 -2
- modal/cli/app.py +4 -4
- modal/cli/cluster.py +15 -7
- modal/cli/config.py +5 -3
- modal/cli/container.py +7 -6
- modal/cli/dict.py +22 -16
- modal/cli/entry_point.py +12 -5
- modal/cli/environment.py +5 -4
- modal/cli/import_refs.py +3 -3
- modal/cli/launch.py +102 -5
- modal/cli/network_file_system.py +9 -13
- modal/cli/profile.py +3 -2
- modal/cli/programs/launch_instance_ssh.py +94 -0
- modal/cli/programs/run_jupyter.py +1 -1
- modal/cli/programs/run_marimo.py +95 -0
- modal/cli/programs/vscode.py +1 -1
- modal/cli/queues.py +57 -26
- modal/cli/run.py +58 -16
- modal/cli/secret.py +48 -22
- modal/cli/utils.py +3 -4
- modal/cli/volume.py +28 -25
- modal/client.py +13 -116
- modal/client.pyi +9 -91
- modal/cloud_bucket_mount.py +5 -3
- modal/cloud_bucket_mount.pyi +5 -1
- modal/cls.py +130 -102
- modal/cls.pyi +45 -85
- modal/config.py +29 -10
- modal/container_process.py +291 -13
- modal/container_process.pyi +95 -32
- modal/dict.py +282 -63
- modal/dict.pyi +423 -73
- modal/environments.py +15 -27
- modal/environments.pyi +5 -15
- modal/exception.py +8 -0
- modal/experimental/__init__.py +143 -38
- modal/experimental/flash.py +247 -78
- modal/experimental/flash.pyi +137 -9
- modal/file_io.py +14 -28
- modal/file_io.pyi +2 -2
- modal/file_pattern_matcher.py +25 -16
- modal/functions.pyi +134 -61
- modal/image.py +255 -86
- modal/image.pyi +300 -62
- modal/io_streams.py +436 -126
- modal/io_streams.pyi +236 -171
- modal/mount.py +62 -157
- modal/mount.pyi +45 -172
- modal/network_file_system.py +30 -53
- modal/network_file_system.pyi +16 -76
- modal/object.pyi +42 -8
- modal/parallel_map.py +821 -113
- modal/parallel_map.pyi +134 -0
- modal/partial_function.pyi +4 -1
- modal/proxy.py +16 -7
- modal/proxy.pyi +10 -2
- modal/queue.py +263 -61
- modal/queue.pyi +409 -66
- modal/runner.py +112 -92
- modal/runner.pyi +45 -27
- modal/sandbox.py +451 -124
- modal/sandbox.pyi +513 -67
- modal/secret.py +291 -67
- modal/secret.pyi +425 -19
- modal/serving.py +7 -11
- modal/serving.pyi +7 -8
- modal/snapshot.py +11 -8
- modal/token_flow.py +4 -4
- modal/volume.py +344 -98
- modal/volume.pyi +464 -68
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/METADATA +9 -8
- modal-1.2.3.dev7.dist-info/RECORD +195 -0
- modal_docs/mdmd/mdmd.py +11 -1
- modal_proto/api.proto +399 -67
- modal_proto/api_grpc.py +241 -1
- modal_proto/api_pb2.py +1395 -1000
- modal_proto/api_pb2.pyi +1239 -79
- modal_proto/api_pb2_grpc.py +499 -4
- modal_proto/api_pb2_grpc.pyi +162 -14
- modal_proto/modal_api_grpc.py +175 -160
- modal_proto/sandbox_router.proto +145 -0
- modal_proto/sandbox_router_grpc.py +105 -0
- modal_proto/sandbox_router_pb2.py +149 -0
- modal_proto/sandbox_router_pb2.pyi +333 -0
- modal_proto/sandbox_router_pb2_grpc.py +203 -0
- modal_proto/sandbox_router_pb2_grpc.pyi +75 -0
- modal_proto/task_command_router.proto +144 -0
- modal_proto/task_command_router_grpc.py +105 -0
- modal_proto/task_command_router_pb2.py +149 -0
- modal_proto/task_command_router_pb2.pyi +333 -0
- modal_proto/task_command_router_pb2_grpc.py +203 -0
- modal_proto/task_command_router_pb2_grpc.pyi +75 -0
- modal_version/__init__.py +1 -1
- modal-1.0.6.dev58.dist-info/RECORD +0 -183
- modal_proto/modal_options_grpc.py +0 -3
- modal_proto/options.proto +0 -19
- modal_proto/options_grpc.py +0 -3
- modal_proto/options_pb2.py +0 -35
- modal_proto/options_pb2.pyi +0 -20
- modal_proto/options_pb2_grpc.py +0 -4
- modal_proto/options_pb2_grpc.pyi +0 -7
- /modal/{requirements → builder}/2023.12.312.txt +0 -0
- /modal/{requirements → builder}/2023.12.txt +0 -0
- /modal/{requirements → builder}/2024.04.txt +0 -0
- /modal/{requirements → builder}/2024.10.txt +0 -0
- /modal/{requirements → builder}/README.md +0 -0
- /modal/{requirements → builder}/base-images.json +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/WHEEL +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/entry_points.txt +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/licenses/LICENSE +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/top_level.txt +0 -0
modal/dict.pyi
CHANGED
|
@@ -1,13 +1,365 @@
|
|
|
1
1
|
import collections.abc
|
|
2
|
+
import datetime
|
|
3
|
+
import google.protobuf.message
|
|
2
4
|
import modal._object
|
|
3
5
|
import modal.client
|
|
4
6
|
import modal.object
|
|
7
|
+
import modal_proto.api_pb2
|
|
8
|
+
import synchronicity
|
|
5
9
|
import synchronicity.combined_types
|
|
6
10
|
import typing
|
|
7
11
|
import typing_extensions
|
|
8
12
|
|
|
13
|
+
class _NoDefaultSentinel:
|
|
14
|
+
def __repr__(self) -> str:
|
|
15
|
+
"""Return repr(self)."""
|
|
16
|
+
...
|
|
17
|
+
|
|
18
|
+
_NO_DEFAULT: _NoDefaultSentinel
|
|
19
|
+
|
|
9
20
|
def _serialize_dict(data): ...
|
|
10
21
|
|
|
22
|
+
class DictInfo:
|
|
23
|
+
"""Information about a Dict object."""
|
|
24
|
+
|
|
25
|
+
name: typing.Optional[str]
|
|
26
|
+
created_at: datetime.datetime
|
|
27
|
+
created_by: typing.Optional[str]
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self, name: typing.Optional[str], created_at: datetime.datetime, created_by: typing.Optional[str]
|
|
31
|
+
) -> None:
|
|
32
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
def __repr__(self):
|
|
36
|
+
"""Return repr(self)."""
|
|
37
|
+
...
|
|
38
|
+
|
|
39
|
+
def __eq__(self, other):
|
|
40
|
+
"""Return self==value."""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
class _DictManager:
|
|
44
|
+
"""Namespace with methods for managing named Dict objects."""
|
|
45
|
+
@staticmethod
|
|
46
|
+
async def create(
|
|
47
|
+
name: str,
|
|
48
|
+
*,
|
|
49
|
+
allow_existing: bool = False,
|
|
50
|
+
environment_name: typing.Optional[str] = None,
|
|
51
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
52
|
+
) -> None:
|
|
53
|
+
"""Create a new Dict object.
|
|
54
|
+
|
|
55
|
+
**Examples:**
|
|
56
|
+
|
|
57
|
+
```python notest
|
|
58
|
+
modal.Dict.objects.create("my-dict")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Dicts will be created in the active environment, or another one can be specified:
|
|
62
|
+
|
|
63
|
+
```python notest
|
|
64
|
+
modal.Dict.objects.create("my-dict", environment_name="dev")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
By default, an error will be raised if the Dict already exists, but passing
|
|
68
|
+
`allow_existing=True` will make the creation attempt a no-op in this case.
|
|
69
|
+
|
|
70
|
+
```python notest
|
|
71
|
+
modal.Dict.objects.create("my-dict", allow_existing=True)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Note that this method does not return a local instance of the Dict. You can use
|
|
75
|
+
`modal.Dict.from_name` to perform a lookup after creation.
|
|
76
|
+
|
|
77
|
+
Added in v1.1.2.
|
|
78
|
+
"""
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
async def list(
|
|
83
|
+
*,
|
|
84
|
+
max_objects: typing.Optional[int] = None,
|
|
85
|
+
created_before: typing.Union[datetime.datetime, str, None] = None,
|
|
86
|
+
environment_name: str = "",
|
|
87
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
88
|
+
) -> list[_Dict]:
|
|
89
|
+
"""Return a list of hydrated Dict objects.
|
|
90
|
+
|
|
91
|
+
**Examples:**
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
dicts = modal.Dict.objects.list()
|
|
95
|
+
print([d.name for d in dicts])
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Dicts will be retreived from the active environment, or another one can be specified:
|
|
99
|
+
|
|
100
|
+
```python notest
|
|
101
|
+
dev_dicts = modal.Dict.objects.list(environment_name="dev")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
By default, all named Dict are returned, newest to oldest. It's also possible to limit the
|
|
105
|
+
number of results and to filter by creation date:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
dicts = modal.Dict.objects.list(max_objects=10, created_before="2025-01-01")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Added in v1.1.2.
|
|
112
|
+
"""
|
|
113
|
+
...
|
|
114
|
+
|
|
115
|
+
@staticmethod
|
|
116
|
+
async def delete(
|
|
117
|
+
name: str,
|
|
118
|
+
*,
|
|
119
|
+
allow_missing: bool = False,
|
|
120
|
+
environment_name: typing.Optional[str] = None,
|
|
121
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
122
|
+
):
|
|
123
|
+
"""Delete a named Dict.
|
|
124
|
+
|
|
125
|
+
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
126
|
+
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
127
|
+
|
|
128
|
+
**Examples:**
|
|
129
|
+
|
|
130
|
+
```python notest
|
|
131
|
+
await modal.Dict.objects.delete("my-dict")
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Dicts will be deleted from the active environment, or another one can be specified:
|
|
135
|
+
|
|
136
|
+
```python notest
|
|
137
|
+
await modal.Dict.objects.delete("my-dict", environment_name="dev")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Added in v1.1.2.
|
|
141
|
+
"""
|
|
142
|
+
...
|
|
143
|
+
|
|
144
|
+
class DictManager:
|
|
145
|
+
"""Namespace with methods for managing named Dict objects."""
|
|
146
|
+
def __init__(self, /, *args, **kwargs):
|
|
147
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
148
|
+
...
|
|
149
|
+
|
|
150
|
+
class __create_spec(typing_extensions.Protocol):
|
|
151
|
+
def __call__(
|
|
152
|
+
self,
|
|
153
|
+
/,
|
|
154
|
+
name: str,
|
|
155
|
+
*,
|
|
156
|
+
allow_existing: bool = False,
|
|
157
|
+
environment_name: typing.Optional[str] = None,
|
|
158
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
159
|
+
) -> None:
|
|
160
|
+
"""Create a new Dict object.
|
|
161
|
+
|
|
162
|
+
**Examples:**
|
|
163
|
+
|
|
164
|
+
```python notest
|
|
165
|
+
modal.Dict.objects.create("my-dict")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Dicts will be created in the active environment, or another one can be specified:
|
|
169
|
+
|
|
170
|
+
```python notest
|
|
171
|
+
modal.Dict.objects.create("my-dict", environment_name="dev")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
By default, an error will be raised if the Dict already exists, but passing
|
|
175
|
+
`allow_existing=True` will make the creation attempt a no-op in this case.
|
|
176
|
+
|
|
177
|
+
```python notest
|
|
178
|
+
modal.Dict.objects.create("my-dict", allow_existing=True)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Note that this method does not return a local instance of the Dict. You can use
|
|
182
|
+
`modal.Dict.from_name` to perform a lookup after creation.
|
|
183
|
+
|
|
184
|
+
Added in v1.1.2.
|
|
185
|
+
"""
|
|
186
|
+
...
|
|
187
|
+
|
|
188
|
+
async def aio(
|
|
189
|
+
self,
|
|
190
|
+
/,
|
|
191
|
+
name: str,
|
|
192
|
+
*,
|
|
193
|
+
allow_existing: bool = False,
|
|
194
|
+
environment_name: typing.Optional[str] = None,
|
|
195
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
196
|
+
) -> None:
|
|
197
|
+
"""Create a new Dict object.
|
|
198
|
+
|
|
199
|
+
**Examples:**
|
|
200
|
+
|
|
201
|
+
```python notest
|
|
202
|
+
modal.Dict.objects.create("my-dict")
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Dicts will be created in the active environment, or another one can be specified:
|
|
206
|
+
|
|
207
|
+
```python notest
|
|
208
|
+
modal.Dict.objects.create("my-dict", environment_name="dev")
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
By default, an error will be raised if the Dict already exists, but passing
|
|
212
|
+
`allow_existing=True` will make the creation attempt a no-op in this case.
|
|
213
|
+
|
|
214
|
+
```python notest
|
|
215
|
+
modal.Dict.objects.create("my-dict", allow_existing=True)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Note that this method does not return a local instance of the Dict. You can use
|
|
219
|
+
`modal.Dict.from_name` to perform a lookup after creation.
|
|
220
|
+
|
|
221
|
+
Added in v1.1.2.
|
|
222
|
+
"""
|
|
223
|
+
...
|
|
224
|
+
|
|
225
|
+
create: __create_spec
|
|
226
|
+
|
|
227
|
+
class __list_spec(typing_extensions.Protocol):
|
|
228
|
+
def __call__(
|
|
229
|
+
self,
|
|
230
|
+
/,
|
|
231
|
+
*,
|
|
232
|
+
max_objects: typing.Optional[int] = None,
|
|
233
|
+
created_before: typing.Union[datetime.datetime, str, None] = None,
|
|
234
|
+
environment_name: str = "",
|
|
235
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
236
|
+
) -> list[Dict]:
|
|
237
|
+
"""Return a list of hydrated Dict objects.
|
|
238
|
+
|
|
239
|
+
**Examples:**
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
dicts = modal.Dict.objects.list()
|
|
243
|
+
print([d.name for d in dicts])
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Dicts will be retreived from the active environment, or another one can be specified:
|
|
247
|
+
|
|
248
|
+
```python notest
|
|
249
|
+
dev_dicts = modal.Dict.objects.list(environment_name="dev")
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
By default, all named Dict are returned, newest to oldest. It's also possible to limit the
|
|
253
|
+
number of results and to filter by creation date:
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
dicts = modal.Dict.objects.list(max_objects=10, created_before="2025-01-01")
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Added in v1.1.2.
|
|
260
|
+
"""
|
|
261
|
+
...
|
|
262
|
+
|
|
263
|
+
async def aio(
|
|
264
|
+
self,
|
|
265
|
+
/,
|
|
266
|
+
*,
|
|
267
|
+
max_objects: typing.Optional[int] = None,
|
|
268
|
+
created_before: typing.Union[datetime.datetime, str, None] = None,
|
|
269
|
+
environment_name: str = "",
|
|
270
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
271
|
+
) -> list[Dict]:
|
|
272
|
+
"""Return a list of hydrated Dict objects.
|
|
273
|
+
|
|
274
|
+
**Examples:**
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
dicts = modal.Dict.objects.list()
|
|
278
|
+
print([d.name for d in dicts])
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Dicts will be retreived from the active environment, or another one can be specified:
|
|
282
|
+
|
|
283
|
+
```python notest
|
|
284
|
+
dev_dicts = modal.Dict.objects.list(environment_name="dev")
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
By default, all named Dict are returned, newest to oldest. It's also possible to limit the
|
|
288
|
+
number of results and to filter by creation date:
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
dicts = modal.Dict.objects.list(max_objects=10, created_before="2025-01-01")
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Added in v1.1.2.
|
|
295
|
+
"""
|
|
296
|
+
...
|
|
297
|
+
|
|
298
|
+
list: __list_spec
|
|
299
|
+
|
|
300
|
+
class __delete_spec(typing_extensions.Protocol):
|
|
301
|
+
def __call__(
|
|
302
|
+
self,
|
|
303
|
+
/,
|
|
304
|
+
name: str,
|
|
305
|
+
*,
|
|
306
|
+
allow_missing: bool = False,
|
|
307
|
+
environment_name: typing.Optional[str] = None,
|
|
308
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
309
|
+
):
|
|
310
|
+
"""Delete a named Dict.
|
|
311
|
+
|
|
312
|
+
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
313
|
+
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
314
|
+
|
|
315
|
+
**Examples:**
|
|
316
|
+
|
|
317
|
+
```python notest
|
|
318
|
+
await modal.Dict.objects.delete("my-dict")
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Dicts will be deleted from the active environment, or another one can be specified:
|
|
322
|
+
|
|
323
|
+
```python notest
|
|
324
|
+
await modal.Dict.objects.delete("my-dict", environment_name="dev")
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Added in v1.1.2.
|
|
328
|
+
"""
|
|
329
|
+
...
|
|
330
|
+
|
|
331
|
+
async def aio(
|
|
332
|
+
self,
|
|
333
|
+
/,
|
|
334
|
+
name: str,
|
|
335
|
+
*,
|
|
336
|
+
allow_missing: bool = False,
|
|
337
|
+
environment_name: typing.Optional[str] = None,
|
|
338
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
339
|
+
):
|
|
340
|
+
"""Delete a named Dict.
|
|
341
|
+
|
|
342
|
+
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
343
|
+
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
344
|
+
|
|
345
|
+
**Examples:**
|
|
346
|
+
|
|
347
|
+
```python notest
|
|
348
|
+
await modal.Dict.objects.delete("my-dict")
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Dicts will be deleted from the active environment, or another one can be specified:
|
|
352
|
+
|
|
353
|
+
```python notest
|
|
354
|
+
await modal.Dict.objects.delete("my-dict", environment_name="dev")
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Added in v1.1.2.
|
|
358
|
+
"""
|
|
359
|
+
...
|
|
360
|
+
|
|
361
|
+
delete: __delete_spec
|
|
362
|
+
|
|
11
363
|
class _Dict(modal._object._Object):
|
|
12
364
|
"""Distributed dictionary for storage in Modal apps.
|
|
13
365
|
|
|
@@ -49,10 +401,20 @@ class _Dict(modal._object._Object):
|
|
|
49
401
|
|
|
50
402
|
For more examples, see the [guide](https://modal.com/docs/guide/dicts-and-queues#modal-dicts).
|
|
51
403
|
"""
|
|
404
|
+
|
|
405
|
+
_name: typing.Optional[str]
|
|
406
|
+
_metadata: typing.Optional[modal_proto.api_pb2.DictMetadata]
|
|
407
|
+
|
|
52
408
|
def __init__(self, data={}):
|
|
53
409
|
"""mdmd:hidden"""
|
|
54
410
|
...
|
|
55
411
|
|
|
412
|
+
@synchronicity.classproperty
|
|
413
|
+
def objects(cls) -> _DictManager: ...
|
|
414
|
+
@property
|
|
415
|
+
def name(self) -> typing.Optional[str]: ...
|
|
416
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
417
|
+
def _get_metadata(self) -> modal_proto.api_pb2.DictMetadata: ...
|
|
56
418
|
@classmethod
|
|
57
419
|
def ephemeral(
|
|
58
420
|
cls: type[_Dict],
|
|
@@ -86,6 +448,7 @@ class _Dict(modal._object._Object):
|
|
|
86
448
|
namespace=None,
|
|
87
449
|
environment_name: typing.Optional[str] = None,
|
|
88
450
|
create_if_missing: bool = False,
|
|
451
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
89
452
|
) -> _Dict:
|
|
90
453
|
"""Reference a named Dict, creating if necessary.
|
|
91
454
|
|
|
@@ -101,36 +464,26 @@ class _Dict(modal._object._Object):
|
|
|
101
464
|
...
|
|
102
465
|
|
|
103
466
|
@staticmethod
|
|
104
|
-
async def
|
|
467
|
+
async def delete(
|
|
105
468
|
name: str,
|
|
106
|
-
|
|
107
|
-
namespace=None,
|
|
469
|
+
*,
|
|
108
470
|
client: typing.Optional[modal.client._Client] = None,
|
|
109
471
|
environment_name: typing.Optional[str] = None,
|
|
110
|
-
|
|
111
|
-
) -> _Dict:
|
|
472
|
+
):
|
|
112
473
|
"""mdmd:hidden
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
DEPRECATED: This method is deprecated in favor of `modal.Dict.from_name`.
|
|
474
|
+
Delete a named Dict object.
|
|
116
475
|
|
|
117
|
-
|
|
118
|
-
|
|
476
|
+
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
477
|
+
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
119
478
|
|
|
120
|
-
|
|
121
|
-
d = modal.Dict.from_name("my-dict")
|
|
122
|
-
d["xyz"] = 123
|
|
123
|
-
```
|
|
479
|
+
DEPRECATED: This method is deprecated; we recommend using `modal.Dict.objects.delete` instead.
|
|
124
480
|
"""
|
|
125
481
|
...
|
|
126
482
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
client: typing.Optional[modal.client._Client] = None,
|
|
132
|
-
environment_name: typing.Optional[str] = None,
|
|
133
|
-
): ...
|
|
483
|
+
async def info(self) -> DictInfo:
|
|
484
|
+
"""Return information about the Dict object."""
|
|
485
|
+
...
|
|
486
|
+
|
|
134
487
|
async def clear(self) -> None:
|
|
135
488
|
"""Remove all items from the Dict."""
|
|
136
489
|
...
|
|
@@ -179,8 +532,11 @@ class _Dict(modal._object._Object):
|
|
|
179
532
|
"""
|
|
180
533
|
...
|
|
181
534
|
|
|
182
|
-
async def pop(self, key: typing.Any) -> typing.Any:
|
|
183
|
-
"""Remove a key from the Dict, returning the value if it exists.
|
|
535
|
+
async def pop(self, key: typing.Any, default: typing.Any = ...) -> typing.Any:
|
|
536
|
+
"""Remove a key from the Dict, returning the value if it exists.
|
|
537
|
+
|
|
538
|
+
If key is not found, return default if provided, otherwise raise KeyError.
|
|
539
|
+
"""
|
|
184
540
|
...
|
|
185
541
|
|
|
186
542
|
async def __delitem__(self, key: typing.Any) -> typing.Any:
|
|
@@ -264,10 +620,20 @@ class Dict(modal.object.Object):
|
|
|
264
620
|
|
|
265
621
|
For more examples, see the [guide](https://modal.com/docs/guide/dicts-and-queues#modal-dicts).
|
|
266
622
|
"""
|
|
623
|
+
|
|
624
|
+
_name: typing.Optional[str]
|
|
625
|
+
_metadata: typing.Optional[modal_proto.api_pb2.DictMetadata]
|
|
626
|
+
|
|
267
627
|
def __init__(self, data={}):
|
|
268
628
|
"""mdmd:hidden"""
|
|
269
629
|
...
|
|
270
630
|
|
|
631
|
+
@synchronicity.classproperty
|
|
632
|
+
def objects(cls) -> DictManager: ...
|
|
633
|
+
@property
|
|
634
|
+
def name(self) -> typing.Optional[str]: ...
|
|
635
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
636
|
+
def _get_metadata(self) -> modal_proto.api_pb2.DictMetadata: ...
|
|
271
637
|
@classmethod
|
|
272
638
|
def ephemeral(
|
|
273
639
|
cls: type[Dict],
|
|
@@ -301,6 +667,7 @@ class Dict(modal.object.Object):
|
|
|
301
667
|
namespace=None,
|
|
302
668
|
environment_name: typing.Optional[str] = None,
|
|
303
669
|
create_if_missing: bool = False,
|
|
670
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
304
671
|
) -> Dict:
|
|
305
672
|
"""Reference a named Dict, creating if necessary.
|
|
306
673
|
|
|
@@ -315,29 +682,22 @@ class Dict(modal.object.Object):
|
|
|
315
682
|
"""
|
|
316
683
|
...
|
|
317
684
|
|
|
318
|
-
class
|
|
685
|
+
class __delete_spec(typing_extensions.Protocol):
|
|
319
686
|
def __call__(
|
|
320
687
|
self,
|
|
321
688
|
/,
|
|
322
689
|
name: str,
|
|
323
|
-
|
|
324
|
-
namespace=None,
|
|
690
|
+
*,
|
|
325
691
|
client: typing.Optional[modal.client.Client] = None,
|
|
326
692
|
environment_name: typing.Optional[str] = None,
|
|
327
|
-
|
|
328
|
-
) -> Dict:
|
|
693
|
+
):
|
|
329
694
|
"""mdmd:hidden
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
DEPRECATED: This method is deprecated in favor of `modal.Dict.from_name`.
|
|
695
|
+
Delete a named Dict object.
|
|
333
696
|
|
|
334
|
-
|
|
335
|
-
|
|
697
|
+
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
698
|
+
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
336
699
|
|
|
337
|
-
|
|
338
|
-
d = modal.Dict.from_name("my-dict")
|
|
339
|
-
d["xyz"] = 123
|
|
340
|
-
```
|
|
700
|
+
DEPRECATED: This method is deprecated; we recommend using `modal.Dict.objects.delete` instead.
|
|
341
701
|
"""
|
|
342
702
|
...
|
|
343
703
|
|
|
@@ -345,48 +705,32 @@ class Dict(modal.object.Object):
|
|
|
345
705
|
self,
|
|
346
706
|
/,
|
|
347
707
|
name: str,
|
|
348
|
-
|
|
349
|
-
namespace=None,
|
|
708
|
+
*,
|
|
350
709
|
client: typing.Optional[modal.client.Client] = None,
|
|
351
710
|
environment_name: typing.Optional[str] = None,
|
|
352
|
-
|
|
353
|
-
) -> Dict:
|
|
711
|
+
):
|
|
354
712
|
"""mdmd:hidden
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
DEPRECATED: This method is deprecated in favor of `modal.Dict.from_name`.
|
|
713
|
+
Delete a named Dict object.
|
|
358
714
|
|
|
359
|
-
|
|
360
|
-
|
|
715
|
+
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
716
|
+
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
361
717
|
|
|
362
|
-
|
|
363
|
-
d = modal.Dict.from_name("my-dict")
|
|
364
|
-
d["xyz"] = 123
|
|
365
|
-
```
|
|
718
|
+
DEPRECATED: This method is deprecated; we recommend using `modal.Dict.objects.delete` instead.
|
|
366
719
|
"""
|
|
367
720
|
...
|
|
368
721
|
|
|
369
|
-
|
|
722
|
+
delete: __delete_spec
|
|
370
723
|
|
|
371
|
-
class
|
|
372
|
-
def __call__(
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
name: str,
|
|
376
|
-
*,
|
|
377
|
-
client: typing.Optional[modal.client.Client] = None,
|
|
378
|
-
environment_name: typing.Optional[str] = None,
|
|
379
|
-
): ...
|
|
380
|
-
async def aio(
|
|
381
|
-
self,
|
|
382
|
-
/,
|
|
383
|
-
name: str,
|
|
384
|
-
*,
|
|
385
|
-
client: typing.Optional[modal.client.Client] = None,
|
|
386
|
-
environment_name: typing.Optional[str] = None,
|
|
387
|
-
): ...
|
|
724
|
+
class __info_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
725
|
+
def __call__(self, /) -> DictInfo:
|
|
726
|
+
"""Return information about the Dict object."""
|
|
727
|
+
...
|
|
388
728
|
|
|
389
|
-
|
|
729
|
+
async def aio(self, /) -> DictInfo:
|
|
730
|
+
"""Return information about the Dict object."""
|
|
731
|
+
...
|
|
732
|
+
|
|
733
|
+
info: __info_spec[typing_extensions.Self]
|
|
390
734
|
|
|
391
735
|
class __clear_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
392
736
|
def __call__(self, /) -> None:
|
|
@@ -509,12 +853,18 @@ class Dict(modal.object.Object):
|
|
|
509
853
|
__setitem__: ____setitem___spec[typing_extensions.Self]
|
|
510
854
|
|
|
511
855
|
class __pop_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
512
|
-
def __call__(self, /, key: typing.Any) -> typing.Any:
|
|
513
|
-
"""Remove a key from the Dict, returning the value if it exists.
|
|
856
|
+
def __call__(self, /, key: typing.Any, default: typing.Any = ...) -> typing.Any:
|
|
857
|
+
"""Remove a key from the Dict, returning the value if it exists.
|
|
858
|
+
|
|
859
|
+
If key is not found, return default if provided, otherwise raise KeyError.
|
|
860
|
+
"""
|
|
514
861
|
...
|
|
515
862
|
|
|
516
|
-
async def aio(self, /, key: typing.Any) -> typing.Any:
|
|
517
|
-
"""Remove a key from the Dict, returning the value if it exists.
|
|
863
|
+
async def aio(self, /, key: typing.Any, default: typing.Any = ...) -> typing.Any:
|
|
864
|
+
"""Remove a key from the Dict, returning the value if it exists.
|
|
865
|
+
|
|
866
|
+
If key is not found, return default if provided, otherwise raise KeyError.
|
|
867
|
+
"""
|
|
518
868
|
...
|
|
519
869
|
|
|
520
870
|
pop: __pop_spec[typing_extensions.Self]
|
modal/environments.py
CHANGED
|
@@ -8,11 +8,10 @@ from google.protobuf.wrappers_pb2 import StringValue
|
|
|
8
8
|
|
|
9
9
|
from modal_proto import api_pb2
|
|
10
10
|
|
|
11
|
+
from ._load_context import LoadContext
|
|
11
12
|
from ._object import _Object
|
|
12
13
|
from ._resolver import Resolver
|
|
13
14
|
from ._utils.async_utils import synchronize_api, synchronizer
|
|
14
|
-
from ._utils.deprecation import deprecation_warning
|
|
15
|
-
from ._utils.grpc_utils import retry_transient_errors
|
|
16
15
|
from ._utils.name_utils import check_object_name
|
|
17
16
|
from .client import _Client
|
|
18
17
|
from .config import config, logger
|
|
@@ -54,6 +53,7 @@ class _Environment(_Object, type_prefix="en"):
|
|
|
54
53
|
name: str,
|
|
55
54
|
*,
|
|
56
55
|
create_if_missing: bool = False,
|
|
56
|
+
client: Optional[_Client] = None,
|
|
57
57
|
):
|
|
58
58
|
if name:
|
|
59
59
|
# Allow null names for the case where we want to look up the "default" environment,
|
|
@@ -63,7 +63,9 @@ class _Environment(_Object, type_prefix="en"):
|
|
|
63
63
|
# environments as part of public API when we make this class more useful.
|
|
64
64
|
check_object_name(name, "Environment")
|
|
65
65
|
|
|
66
|
-
async def _load(
|
|
66
|
+
async def _load(
|
|
67
|
+
self: _Environment, resolver: Resolver, load_context: LoadContext, existing_object_id: Optional[str]
|
|
68
|
+
):
|
|
67
69
|
request = api_pb2.EnvironmentGetOrCreateRequest(
|
|
68
70
|
deployment_name=name,
|
|
69
71
|
object_creation_type=(
|
|
@@ -72,31 +74,17 @@ class _Environment(_Object, type_prefix="en"):
|
|
|
72
74
|
else api_pb2.OBJECT_CREATION_TYPE_UNSPECIFIED
|
|
73
75
|
),
|
|
74
76
|
)
|
|
75
|
-
response = await
|
|
77
|
+
response = await load_context.client.stub.EnvironmentGetOrCreate(request)
|
|
76
78
|
logger.debug(f"Created environment with id {response.environment_id}")
|
|
77
|
-
self._hydrate(response.environment_id,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
client: Optional[_Client] = None,
|
|
86
|
-
create_if_missing: bool = False,
|
|
87
|
-
):
|
|
88
|
-
deprecation_warning(
|
|
89
|
-
(2025, 1, 27),
|
|
90
|
-
"`modal.Environment.lookup` is deprecated and will be removed in a future release."
|
|
91
|
-
" It can be replaced with `modal.Environment.from_name`."
|
|
92
|
-
"\n\nSee https://modal.com/docs/guide/modal-1-0-migration for more information.",
|
|
79
|
+
self._hydrate(response.environment_id, load_context.client, response.metadata)
|
|
80
|
+
|
|
81
|
+
return _Environment._from_loader(
|
|
82
|
+
_load,
|
|
83
|
+
f"Environment.from_name({name!r})",
|
|
84
|
+
is_another_app=True,
|
|
85
|
+
hydrate_lazily=True,
|
|
86
|
+
load_context_overrides=LoadContext(client=client),
|
|
93
87
|
)
|
|
94
|
-
obj = _Environment.from_name(name, create_if_missing=create_if_missing)
|
|
95
|
-
if client is None:
|
|
96
|
-
client = await _Client.from_env()
|
|
97
|
-
resolver = Resolver(client=client)
|
|
98
|
-
await resolver.load(obj)
|
|
99
|
-
return obj
|
|
100
88
|
|
|
101
89
|
|
|
102
90
|
Environment = synchronize_api(_Environment)
|
|
@@ -109,7 +97,7 @@ ENVIRONMENT_CACHE: dict[str, _Environment] = {}
|
|
|
109
97
|
async def _get_environment_cached(name: str, client: _Client) -> _Environment:
|
|
110
98
|
if name in ENVIRONMENT_CACHE:
|
|
111
99
|
return ENVIRONMENT_CACHE[name]
|
|
112
|
-
environment = await _Environment.from_name(name).hydrate(
|
|
100
|
+
environment = await _Environment.from_name(name, client=client).hydrate()
|
|
113
101
|
ENVIRONMENT_CACHE[name] = environment
|
|
114
102
|
return environment
|
|
115
103
|
|