modal 1.0.3.dev10__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/__init__.py +0 -2
- modal/__main__.py +3 -4
- modal/_billing.py +80 -0
- modal/_clustered_functions.py +7 -3
- modal/_clustered_functions.pyi +15 -3
- modal/_container_entrypoint.py +51 -69
- modal/_functions.py +508 -240
- modal/_grpc_client.py +171 -0
- modal/_load_context.py +105 -0
- modal/_object.py +81 -21
- modal/_output.py +58 -45
- modal/_partial_function.py +48 -73
- modal/_pty.py +7 -3
- modal/_resolver.py +26 -46
- modal/_runtime/asgi.py +4 -3
- modal/_runtime/container_io_manager.py +358 -220
- modal/_runtime/container_io_manager.pyi +296 -101
- modal/_runtime/execution_context.py +18 -2
- modal/_runtime/execution_context.pyi +64 -7
- modal/_runtime/gpu_memory_snapshot.py +262 -57
- modal/_runtime/user_code_imports.py +28 -58
- modal/_serialization.py +90 -6
- modal/_traceback.py +42 -1
- modal/_tunnel.pyi +380 -12
- modal/_utils/async_utils.py +84 -29
- modal/_utils/auth_token_manager.py +111 -0
- modal/_utils/blob_utils.py +181 -58
- modal/_utils/deprecation.py +19 -0
- modal/_utils/function_utils.py +91 -47
- modal/_utils/grpc_utils.py +89 -66
- 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 +256 -88
- modal/app.pyi +909 -92
- modal/billing.py +5 -0
- modal/builder/2025.06.txt +18 -0
- modal/builder/PREVIEW.txt +18 -0
- modal/builder/base-images.json +58 -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 +11 -12
- 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 +91 -23
- modal/cli/secret.py +48 -22
- modal/cli/token.py +7 -8
- modal/cli/utils.py +4 -7
- modal/cli/volume.py +31 -25
- modal/client.py +15 -85
- modal/client.pyi +183 -62
- modal/cloud_bucket_mount.py +5 -3
- modal/cloud_bucket_mount.pyi +197 -5
- modal/cls.py +200 -126
- modal/cls.pyi +446 -68
- modal/config.py +29 -11
- modal/container_process.py +319 -19
- modal/container_process.pyi +190 -20
- modal/dict.py +290 -71
- modal/dict.pyi +835 -83
- modal/environments.py +15 -27
- modal/environments.pyi +46 -24
- modal/exception.py +14 -2
- modal/experimental/__init__.py +194 -40
- modal/experimental/flash.py +618 -0
- modal/experimental/flash.pyi +380 -0
- modal/experimental/ipython.py +11 -7
- modal/file_io.py +29 -36
- modal/file_io.pyi +251 -53
- modal/file_pattern_matcher.py +56 -16
- modal/functions.pyi +673 -92
- modal/gpu.py +1 -1
- modal/image.py +528 -176
- modal/image.pyi +1572 -145
- modal/io_streams.py +458 -128
- modal/io_streams.pyi +433 -52
- modal/mount.py +216 -151
- modal/mount.pyi +225 -78
- modal/network_file_system.py +45 -62
- modal/network_file_system.pyi +277 -56
- modal/object.pyi +93 -17
- modal/parallel_map.py +942 -129
- modal/parallel_map.pyi +294 -15
- modal/partial_function.py +0 -2
- modal/partial_function.pyi +234 -19
- modal/proxy.py +17 -8
- modal/proxy.pyi +36 -3
- modal/queue.py +270 -65
- modal/queue.pyi +817 -57
- modal/runner.py +115 -101
- modal/runner.pyi +205 -49
- modal/sandbox.py +512 -136
- modal/sandbox.pyi +845 -111
- modal/schedule.py +1 -1
- modal/secret.py +300 -70
- modal/secret.pyi +589 -34
- modal/serving.py +7 -11
- modal/serving.pyi +7 -8
- modal/snapshot.py +11 -8
- modal/snapshot.pyi +25 -4
- modal/token_flow.py +4 -4
- modal/token_flow.pyi +28 -8
- modal/volume.py +416 -158
- modal/volume.pyi +1117 -121
- {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/METADATA +10 -9
- modal-1.2.3.dev7.dist-info/RECORD +195 -0
- modal_docs/mdmd/mdmd.py +17 -4
- modal_proto/api.proto +534 -79
- modal_proto/api_grpc.py +337 -1
- modal_proto/api_pb2.py +1522 -968
- modal_proto/api_pb2.pyi +1619 -134
- modal_proto/api_pb2_grpc.py +699 -4
- modal_proto/api_pb2_grpc.pyi +226 -14
- modal_proto/modal_api_grpc.py +175 -154
- 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/requirements/PREVIEW.txt +0 -16
- modal/requirements/base-images.json +0 -26
- modal-1.0.3.dev10.dist-info/RECORD +0 -179
- 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-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/WHEEL +0 -0
- {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/entry_points.txt +0 -0
- {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/licenses/LICENSE +0 -0
- {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/top_level.txt +0 -0
modal/secret.pyi
CHANGED
|
@@ -1,93 +1,648 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import google.protobuf.message
|
|
3
|
+
import modal._load_context
|
|
1
4
|
import modal._object
|
|
2
5
|
import modal.client
|
|
3
6
|
import modal.object
|
|
7
|
+
import modal_proto.api_pb2
|
|
8
|
+
import synchronicity
|
|
4
9
|
import typing
|
|
5
10
|
import typing_extensions
|
|
6
11
|
|
|
12
|
+
class SecretInfo:
|
|
13
|
+
"""Information about the Secret object."""
|
|
14
|
+
|
|
15
|
+
name: typing.Optional[str]
|
|
16
|
+
created_at: datetime.datetime
|
|
17
|
+
created_by: typing.Optional[str]
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self, name: typing.Optional[str], created_at: datetime.datetime, created_by: typing.Optional[str]
|
|
21
|
+
) -> None:
|
|
22
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
def __repr__(self):
|
|
26
|
+
"""Return repr(self)."""
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
def __eq__(self, other):
|
|
30
|
+
"""Return self==value."""
|
|
31
|
+
...
|
|
32
|
+
|
|
33
|
+
class _SecretManager:
|
|
34
|
+
"""Namespace with methods for managing named Secret objects."""
|
|
35
|
+
@staticmethod
|
|
36
|
+
async def create(
|
|
37
|
+
name: str,
|
|
38
|
+
env_dict: dict[str, 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 Secret object.
|
|
45
|
+
|
|
46
|
+
**Examples:**
|
|
47
|
+
|
|
48
|
+
```python notest
|
|
49
|
+
contents = {"MY_KEY": "my-value", "MY_OTHER_KEY": "my-other-value"}
|
|
50
|
+
modal.Secret.objects.create("my-secret", contents)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Secrets will be created in the active environment, or another one can be specified:
|
|
54
|
+
|
|
55
|
+
```python notest
|
|
56
|
+
modal.Secret.objects.create("my-secret", contents, environment_name="dev")
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
By default, an error will be raised if the Secret already exists, but passing
|
|
60
|
+
`allow_existing=True` will make the creation attempt a no-op in this case.
|
|
61
|
+
If the `env_dict` data differs from the existing Secret, it will be ignored.
|
|
62
|
+
|
|
63
|
+
```python notest
|
|
64
|
+
modal.Secret.objects.create("my-secret", contents, allow_existing=True)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Note that this method does not return a local instance of the Secret. You can use
|
|
68
|
+
`modal.Secret.from_name` to perform a lookup after creation.
|
|
69
|
+
|
|
70
|
+
Added in v1.1.2.
|
|
71
|
+
"""
|
|
72
|
+
...
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
async def list(
|
|
76
|
+
*,
|
|
77
|
+
max_objects: typing.Optional[int] = None,
|
|
78
|
+
created_before: typing.Union[datetime.datetime, str, None] = None,
|
|
79
|
+
environment_name: str = "",
|
|
80
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
81
|
+
) -> list[_Secret]:
|
|
82
|
+
"""Return a list of hydrated Secret objects.
|
|
83
|
+
|
|
84
|
+
**Examples:**
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
secrets = modal.Secret.objects.list()
|
|
88
|
+
print([s.name for s in secrets])
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Secrets will be retreived from the active environment, or another one can be specified:
|
|
92
|
+
|
|
93
|
+
```python notest
|
|
94
|
+
dev_secrets = modal.Secret.objects.list(environment_name="dev")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
By default, all named Secrets are returned, newest to oldest. It's also possible to limit the
|
|
98
|
+
number of results and to filter by creation date:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
secrets = modal.Secret.objects.list(max_objects=10, created_before="2025-01-01")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Added in v1.1.2.
|
|
105
|
+
"""
|
|
106
|
+
...
|
|
107
|
+
|
|
108
|
+
@staticmethod
|
|
109
|
+
async def delete(
|
|
110
|
+
name: str,
|
|
111
|
+
*,
|
|
112
|
+
allow_missing: bool = False,
|
|
113
|
+
environment_name: typing.Optional[str] = None,
|
|
114
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
115
|
+
):
|
|
116
|
+
"""Delete a named Secret.
|
|
117
|
+
|
|
118
|
+
Warning: Deletion is irreversible and will affect any Apps currently using the Secret.
|
|
119
|
+
|
|
120
|
+
**Examples:**
|
|
121
|
+
|
|
122
|
+
```python notest
|
|
123
|
+
await modal.Secret.objects.delete("my-secret")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Secrets will be deleted from the active environment, or another one can be specified:
|
|
127
|
+
|
|
128
|
+
```python notest
|
|
129
|
+
await modal.Secret.objects.delete("my-secret", environment_name="dev")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Added in v1.1.2.
|
|
133
|
+
"""
|
|
134
|
+
...
|
|
135
|
+
|
|
136
|
+
class SecretManager:
|
|
137
|
+
"""Namespace with methods for managing named Secret objects."""
|
|
138
|
+
def __init__(self, /, *args, **kwargs):
|
|
139
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
140
|
+
...
|
|
141
|
+
|
|
142
|
+
class __create_spec(typing_extensions.Protocol):
|
|
143
|
+
def __call__(
|
|
144
|
+
self,
|
|
145
|
+
/,
|
|
146
|
+
name: str,
|
|
147
|
+
env_dict: dict[str, str],
|
|
148
|
+
*,
|
|
149
|
+
allow_existing: bool = False,
|
|
150
|
+
environment_name: typing.Optional[str] = None,
|
|
151
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
152
|
+
) -> None:
|
|
153
|
+
"""Create a new Secret object.
|
|
154
|
+
|
|
155
|
+
**Examples:**
|
|
156
|
+
|
|
157
|
+
```python notest
|
|
158
|
+
contents = {"MY_KEY": "my-value", "MY_OTHER_KEY": "my-other-value"}
|
|
159
|
+
modal.Secret.objects.create("my-secret", contents)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Secrets will be created in the active environment, or another one can be specified:
|
|
163
|
+
|
|
164
|
+
```python notest
|
|
165
|
+
modal.Secret.objects.create("my-secret", contents, environment_name="dev")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
By default, an error will be raised if the Secret already exists, but passing
|
|
169
|
+
`allow_existing=True` will make the creation attempt a no-op in this case.
|
|
170
|
+
If the `env_dict` data differs from the existing Secret, it will be ignored.
|
|
171
|
+
|
|
172
|
+
```python notest
|
|
173
|
+
modal.Secret.objects.create("my-secret", contents, allow_existing=True)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Note that this method does not return a local instance of the Secret. You can use
|
|
177
|
+
`modal.Secret.from_name` to perform a lookup after creation.
|
|
178
|
+
|
|
179
|
+
Added in v1.1.2.
|
|
180
|
+
"""
|
|
181
|
+
...
|
|
182
|
+
|
|
183
|
+
async def aio(
|
|
184
|
+
self,
|
|
185
|
+
/,
|
|
186
|
+
name: str,
|
|
187
|
+
env_dict: dict[str, str],
|
|
188
|
+
*,
|
|
189
|
+
allow_existing: bool = False,
|
|
190
|
+
environment_name: typing.Optional[str] = None,
|
|
191
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
192
|
+
) -> None:
|
|
193
|
+
"""Create a new Secret object.
|
|
194
|
+
|
|
195
|
+
**Examples:**
|
|
196
|
+
|
|
197
|
+
```python notest
|
|
198
|
+
contents = {"MY_KEY": "my-value", "MY_OTHER_KEY": "my-other-value"}
|
|
199
|
+
modal.Secret.objects.create("my-secret", contents)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Secrets will be created in the active environment, or another one can be specified:
|
|
203
|
+
|
|
204
|
+
```python notest
|
|
205
|
+
modal.Secret.objects.create("my-secret", contents, environment_name="dev")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
By default, an error will be raised if the Secret already exists, but passing
|
|
209
|
+
`allow_existing=True` will make the creation attempt a no-op in this case.
|
|
210
|
+
If the `env_dict` data differs from the existing Secret, it will be ignored.
|
|
211
|
+
|
|
212
|
+
```python notest
|
|
213
|
+
modal.Secret.objects.create("my-secret", contents, allow_existing=True)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Note that this method does not return a local instance of the Secret. You can use
|
|
217
|
+
`modal.Secret.from_name` to perform a lookup after creation.
|
|
218
|
+
|
|
219
|
+
Added in v1.1.2.
|
|
220
|
+
"""
|
|
221
|
+
...
|
|
222
|
+
|
|
223
|
+
create: __create_spec
|
|
224
|
+
|
|
225
|
+
class __list_spec(typing_extensions.Protocol):
|
|
226
|
+
def __call__(
|
|
227
|
+
self,
|
|
228
|
+
/,
|
|
229
|
+
*,
|
|
230
|
+
max_objects: typing.Optional[int] = None,
|
|
231
|
+
created_before: typing.Union[datetime.datetime, str, None] = None,
|
|
232
|
+
environment_name: str = "",
|
|
233
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
234
|
+
) -> list[Secret]:
|
|
235
|
+
"""Return a list of hydrated Secret objects.
|
|
236
|
+
|
|
237
|
+
**Examples:**
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
secrets = modal.Secret.objects.list()
|
|
241
|
+
print([s.name for s in secrets])
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Secrets will be retreived from the active environment, or another one can be specified:
|
|
245
|
+
|
|
246
|
+
```python notest
|
|
247
|
+
dev_secrets = modal.Secret.objects.list(environment_name="dev")
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
By default, all named Secrets are returned, newest to oldest. It's also possible to limit the
|
|
251
|
+
number of results and to filter by creation date:
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
secrets = modal.Secret.objects.list(max_objects=10, created_before="2025-01-01")
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Added in v1.1.2.
|
|
258
|
+
"""
|
|
259
|
+
...
|
|
260
|
+
|
|
261
|
+
async def aio(
|
|
262
|
+
self,
|
|
263
|
+
/,
|
|
264
|
+
*,
|
|
265
|
+
max_objects: typing.Optional[int] = None,
|
|
266
|
+
created_before: typing.Union[datetime.datetime, str, None] = None,
|
|
267
|
+
environment_name: str = "",
|
|
268
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
269
|
+
) -> list[Secret]:
|
|
270
|
+
"""Return a list of hydrated Secret objects.
|
|
271
|
+
|
|
272
|
+
**Examples:**
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
secrets = modal.Secret.objects.list()
|
|
276
|
+
print([s.name for s in secrets])
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Secrets will be retreived from the active environment, or another one can be specified:
|
|
280
|
+
|
|
281
|
+
```python notest
|
|
282
|
+
dev_secrets = modal.Secret.objects.list(environment_name="dev")
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
By default, all named Secrets are returned, newest to oldest. It's also possible to limit the
|
|
286
|
+
number of results and to filter by creation date:
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
secrets = modal.Secret.objects.list(max_objects=10, created_before="2025-01-01")
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Added in v1.1.2.
|
|
293
|
+
"""
|
|
294
|
+
...
|
|
295
|
+
|
|
296
|
+
list: __list_spec
|
|
297
|
+
|
|
298
|
+
class __delete_spec(typing_extensions.Protocol):
|
|
299
|
+
def __call__(
|
|
300
|
+
self,
|
|
301
|
+
/,
|
|
302
|
+
name: str,
|
|
303
|
+
*,
|
|
304
|
+
allow_missing: bool = False,
|
|
305
|
+
environment_name: typing.Optional[str] = None,
|
|
306
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
307
|
+
):
|
|
308
|
+
"""Delete a named Secret.
|
|
309
|
+
|
|
310
|
+
Warning: Deletion is irreversible and will affect any Apps currently using the Secret.
|
|
311
|
+
|
|
312
|
+
**Examples:**
|
|
313
|
+
|
|
314
|
+
```python notest
|
|
315
|
+
await modal.Secret.objects.delete("my-secret")
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Secrets will be deleted from the active environment, or another one can be specified:
|
|
319
|
+
|
|
320
|
+
```python notest
|
|
321
|
+
await modal.Secret.objects.delete("my-secret", environment_name="dev")
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Added in v1.1.2.
|
|
325
|
+
"""
|
|
326
|
+
...
|
|
327
|
+
|
|
328
|
+
async def aio(
|
|
329
|
+
self,
|
|
330
|
+
/,
|
|
331
|
+
name: str,
|
|
332
|
+
*,
|
|
333
|
+
allow_missing: bool = False,
|
|
334
|
+
environment_name: typing.Optional[str] = None,
|
|
335
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
336
|
+
):
|
|
337
|
+
"""Delete a named Secret.
|
|
338
|
+
|
|
339
|
+
Warning: Deletion is irreversible and will affect any Apps currently using the Secret.
|
|
340
|
+
|
|
341
|
+
**Examples:**
|
|
342
|
+
|
|
343
|
+
```python notest
|
|
344
|
+
await modal.Secret.objects.delete("my-secret")
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Secrets will be deleted from the active environment, or another one can be specified:
|
|
348
|
+
|
|
349
|
+
```python notest
|
|
350
|
+
await modal.Secret.objects.delete("my-secret", environment_name="dev")
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Added in v1.1.2.
|
|
354
|
+
"""
|
|
355
|
+
...
|
|
356
|
+
|
|
357
|
+
delete: __delete_spec
|
|
358
|
+
|
|
359
|
+
async def _load_from_env_dict(
|
|
360
|
+
instance: _Secret, load_context: modal._load_context.LoadContext, env_dict: dict[str, str]
|
|
361
|
+
):
|
|
362
|
+
"""helper method for loaders .from_dict and .from_dotenv etc."""
|
|
363
|
+
...
|
|
364
|
+
|
|
7
365
|
class _Secret(modal._object._Object):
|
|
366
|
+
"""Secrets provide a dictionary of environment variables for images.
|
|
367
|
+
|
|
368
|
+
Secrets are a secure way to add credentials and other sensitive information
|
|
369
|
+
to the containers your functions run in. You can create and edit secrets on
|
|
370
|
+
[the dashboard](https://modal.com/secrets), or programmatically from Python code.
|
|
371
|
+
|
|
372
|
+
See [the secrets guide page](https://modal.com/docs/guide/secrets) for more information.
|
|
373
|
+
"""
|
|
374
|
+
|
|
375
|
+
_metadata: typing.Optional[modal_proto.api_pb2.SecretMetadata]
|
|
376
|
+
|
|
377
|
+
@synchronicity.classproperty
|
|
378
|
+
def objects(cls) -> _SecretManager: ...
|
|
379
|
+
@property
|
|
380
|
+
def name(self) -> typing.Optional[str]: ...
|
|
381
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
382
|
+
def _get_metadata(self) -> modal_proto.api_pb2.SecretMetadata: ...
|
|
8
383
|
@staticmethod
|
|
9
|
-
def from_dict(env_dict: dict[str, typing.Optional[str]] = {}) -> _Secret:
|
|
384
|
+
def from_dict(env_dict: dict[str, typing.Optional[str]] = {}) -> _Secret:
|
|
385
|
+
"""Create a secret from a str-str dictionary. Values can also be `None`, which is ignored.
|
|
386
|
+
|
|
387
|
+
Usage:
|
|
388
|
+
```python
|
|
389
|
+
@app.function(secrets=[modal.Secret.from_dict({"FOO": "bar"})])
|
|
390
|
+
def run():
|
|
391
|
+
print(os.environ["FOO"])
|
|
392
|
+
```
|
|
393
|
+
"""
|
|
394
|
+
...
|
|
395
|
+
|
|
10
396
|
@staticmethod
|
|
11
|
-
def from_local_environ(env_keys: list[str]) -> _Secret:
|
|
397
|
+
def from_local_environ(env_keys: list[str]) -> _Secret:
|
|
398
|
+
"""Create secrets from local environment variables automatically."""
|
|
399
|
+
...
|
|
400
|
+
|
|
12
401
|
@staticmethod
|
|
13
|
-
def from_dotenv(path=None, *, filename=".env") -> _Secret:
|
|
402
|
+
def from_dotenv(path=None, *, filename=".env", client: typing.Optional[modal.client._Client] = None) -> _Secret:
|
|
403
|
+
"""Create secrets from a .env file automatically.
|
|
404
|
+
|
|
405
|
+
If no argument is provided, it will use the current working directory as the starting
|
|
406
|
+
point for finding a `.env` file. Note that it does not use the location of the module
|
|
407
|
+
calling `Secret.from_dotenv`.
|
|
408
|
+
|
|
409
|
+
If called with an argument, it will use that as a starting point for finding `.env` files.
|
|
410
|
+
In particular, you can call it like this:
|
|
411
|
+
```python
|
|
412
|
+
@app.function(secrets=[modal.Secret.from_dotenv(__file__)])
|
|
413
|
+
def run():
|
|
414
|
+
print(os.environ["USERNAME"]) # Assumes USERNAME is defined in your .env file
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
This will use the location of the script calling `modal.Secret.from_dotenv` as a
|
|
418
|
+
starting point for finding the `.env` file.
|
|
419
|
+
|
|
420
|
+
A file named `.env` is expected by default, but this can be overridden with the `filename`
|
|
421
|
+
keyword argument:
|
|
422
|
+
|
|
423
|
+
```python
|
|
424
|
+
@app.function(secrets=[modal.Secret.from_dotenv(filename=".env-dev")])
|
|
425
|
+
def run():
|
|
426
|
+
...
|
|
427
|
+
```
|
|
428
|
+
"""
|
|
429
|
+
...
|
|
430
|
+
|
|
14
431
|
@staticmethod
|
|
15
432
|
def from_name(
|
|
16
|
-
name: str, *, namespace=1, environment_name: typing.Optional[str] = None, required_keys: list[str] = []
|
|
17
|
-
) -> _Secret: ...
|
|
18
|
-
@staticmethod
|
|
19
|
-
async def lookup(
|
|
20
433
|
name: str,
|
|
21
|
-
|
|
22
|
-
|
|
434
|
+
*,
|
|
435
|
+
namespace=None,
|
|
23
436
|
environment_name: typing.Optional[str] = None,
|
|
24
437
|
required_keys: list[str] = [],
|
|
25
|
-
|
|
438
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
439
|
+
) -> _Secret:
|
|
440
|
+
"""Reference a Secret by its name.
|
|
441
|
+
|
|
442
|
+
In contrast to most other Modal objects, named Secrets must be provisioned
|
|
443
|
+
from the Dashboard. See other methods for alternate ways of creating a new
|
|
444
|
+
Secret from code.
|
|
445
|
+
|
|
446
|
+
```python
|
|
447
|
+
secret = modal.Secret.from_name("my-secret")
|
|
448
|
+
|
|
449
|
+
@app.function(secrets=[secret])
|
|
450
|
+
def run():
|
|
451
|
+
...
|
|
452
|
+
```
|
|
453
|
+
"""
|
|
454
|
+
...
|
|
455
|
+
|
|
26
456
|
@staticmethod
|
|
27
457
|
async def create_deployed(
|
|
28
458
|
deployment_name: str,
|
|
29
459
|
env_dict: dict[str, str],
|
|
30
|
-
namespace=
|
|
460
|
+
namespace=None,
|
|
461
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
462
|
+
environment_name: typing.Optional[str] = None,
|
|
463
|
+
overwrite: bool = False,
|
|
464
|
+
) -> str:
|
|
465
|
+
"""mdmd:hidden"""
|
|
466
|
+
...
|
|
467
|
+
|
|
468
|
+
@staticmethod
|
|
469
|
+
async def _create_deployed(
|
|
470
|
+
deployment_name: str,
|
|
471
|
+
env_dict: dict[str, str],
|
|
472
|
+
namespace=None,
|
|
31
473
|
client: typing.Optional[modal.client._Client] = None,
|
|
32
474
|
environment_name: typing.Optional[str] = None,
|
|
33
475
|
overwrite: bool = False,
|
|
34
|
-
) -> str:
|
|
476
|
+
) -> str:
|
|
477
|
+
"""mdmd:hidden"""
|
|
478
|
+
...
|
|
479
|
+
|
|
480
|
+
async def info(self) -> SecretInfo:
|
|
481
|
+
"""Return information about the Secret object."""
|
|
482
|
+
...
|
|
483
|
+
|
|
484
|
+
SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
|
|
35
485
|
|
|
36
486
|
class Secret(modal.object.Object):
|
|
37
|
-
|
|
487
|
+
"""Secrets provide a dictionary of environment variables for images.
|
|
488
|
+
|
|
489
|
+
Secrets are a secure way to add credentials and other sensitive information
|
|
490
|
+
to the containers your functions run in. You can create and edit secrets on
|
|
491
|
+
[the dashboard](https://modal.com/secrets), or programmatically from Python code.
|
|
492
|
+
|
|
493
|
+
See [the secrets guide page](https://modal.com/docs/guide/secrets) for more information.
|
|
494
|
+
"""
|
|
495
|
+
|
|
496
|
+
_metadata: typing.Optional[modal_proto.api_pb2.SecretMetadata]
|
|
497
|
+
|
|
498
|
+
def __init__(self, *args, **kwargs):
|
|
499
|
+
"""mdmd:hidden"""
|
|
500
|
+
...
|
|
501
|
+
|
|
502
|
+
@synchronicity.classproperty
|
|
503
|
+
def objects(cls) -> SecretManager: ...
|
|
504
|
+
@property
|
|
505
|
+
def name(self) -> typing.Optional[str]: ...
|
|
506
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
507
|
+
def _get_metadata(self) -> modal_proto.api_pb2.SecretMetadata: ...
|
|
38
508
|
@staticmethod
|
|
39
|
-
def from_dict(env_dict: dict[str, typing.Optional[str]] = {}) -> Secret:
|
|
509
|
+
def from_dict(env_dict: dict[str, typing.Optional[str]] = {}) -> Secret:
|
|
510
|
+
"""Create a secret from a str-str dictionary. Values can also be `None`, which is ignored.
|
|
511
|
+
|
|
512
|
+
Usage:
|
|
513
|
+
```python
|
|
514
|
+
@app.function(secrets=[modal.Secret.from_dict({"FOO": "bar"})])
|
|
515
|
+
def run():
|
|
516
|
+
print(os.environ["FOO"])
|
|
517
|
+
```
|
|
518
|
+
"""
|
|
519
|
+
...
|
|
520
|
+
|
|
40
521
|
@staticmethod
|
|
41
|
-
def from_local_environ(env_keys: list[str]) -> Secret:
|
|
522
|
+
def from_local_environ(env_keys: list[str]) -> Secret:
|
|
523
|
+
"""Create secrets from local environment variables automatically."""
|
|
524
|
+
...
|
|
525
|
+
|
|
42
526
|
@staticmethod
|
|
43
|
-
def from_dotenv(path=None, *, filename=".env") -> Secret:
|
|
527
|
+
def from_dotenv(path=None, *, filename=".env", client: typing.Optional[modal.client.Client] = None) -> Secret:
|
|
528
|
+
"""Create secrets from a .env file automatically.
|
|
529
|
+
|
|
530
|
+
If no argument is provided, it will use the current working directory as the starting
|
|
531
|
+
point for finding a `.env` file. Note that it does not use the location of the module
|
|
532
|
+
calling `Secret.from_dotenv`.
|
|
533
|
+
|
|
534
|
+
If called with an argument, it will use that as a starting point for finding `.env` files.
|
|
535
|
+
In particular, you can call it like this:
|
|
536
|
+
```python
|
|
537
|
+
@app.function(secrets=[modal.Secret.from_dotenv(__file__)])
|
|
538
|
+
def run():
|
|
539
|
+
print(os.environ["USERNAME"]) # Assumes USERNAME is defined in your .env file
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
This will use the location of the script calling `modal.Secret.from_dotenv` as a
|
|
543
|
+
starting point for finding the `.env` file.
|
|
544
|
+
|
|
545
|
+
A file named `.env` is expected by default, but this can be overridden with the `filename`
|
|
546
|
+
keyword argument:
|
|
547
|
+
|
|
548
|
+
```python
|
|
549
|
+
@app.function(secrets=[modal.Secret.from_dotenv(filename=".env-dev")])
|
|
550
|
+
def run():
|
|
551
|
+
...
|
|
552
|
+
```
|
|
553
|
+
"""
|
|
554
|
+
...
|
|
555
|
+
|
|
44
556
|
@staticmethod
|
|
45
557
|
def from_name(
|
|
46
|
-
name: str,
|
|
47
|
-
|
|
558
|
+
name: str,
|
|
559
|
+
*,
|
|
560
|
+
namespace=None,
|
|
561
|
+
environment_name: typing.Optional[str] = None,
|
|
562
|
+
required_keys: list[str] = [],
|
|
563
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
564
|
+
) -> Secret:
|
|
565
|
+
"""Reference a Secret by its name.
|
|
566
|
+
|
|
567
|
+
In contrast to most other Modal objects, named Secrets must be provisioned
|
|
568
|
+
from the Dashboard. See other methods for alternate ways of creating a new
|
|
569
|
+
Secret from code.
|
|
570
|
+
|
|
571
|
+
```python
|
|
572
|
+
secret = modal.Secret.from_name("my-secret")
|
|
48
573
|
|
|
49
|
-
|
|
574
|
+
@app.function(secrets=[secret])
|
|
575
|
+
def run():
|
|
576
|
+
...
|
|
577
|
+
```
|
|
578
|
+
"""
|
|
579
|
+
...
|
|
580
|
+
|
|
581
|
+
class __create_deployed_spec(typing_extensions.Protocol):
|
|
50
582
|
def __call__(
|
|
51
583
|
self,
|
|
52
584
|
/,
|
|
53
|
-
|
|
54
|
-
|
|
585
|
+
deployment_name: str,
|
|
586
|
+
env_dict: dict[str, str],
|
|
587
|
+
namespace=None,
|
|
55
588
|
client: typing.Optional[modal.client.Client] = None,
|
|
56
589
|
environment_name: typing.Optional[str] = None,
|
|
57
|
-
|
|
58
|
-
) ->
|
|
590
|
+
overwrite: bool = False,
|
|
591
|
+
) -> str:
|
|
592
|
+
"""mdmd:hidden"""
|
|
593
|
+
...
|
|
594
|
+
|
|
59
595
|
async def aio(
|
|
60
596
|
self,
|
|
61
597
|
/,
|
|
62
|
-
|
|
63
|
-
|
|
598
|
+
deployment_name: str,
|
|
599
|
+
env_dict: dict[str, str],
|
|
600
|
+
namespace=None,
|
|
64
601
|
client: typing.Optional[modal.client.Client] = None,
|
|
65
602
|
environment_name: typing.Optional[str] = None,
|
|
66
|
-
|
|
67
|
-
) ->
|
|
603
|
+
overwrite: bool = False,
|
|
604
|
+
) -> str:
|
|
605
|
+
"""mdmd:hidden"""
|
|
606
|
+
...
|
|
68
607
|
|
|
69
|
-
|
|
608
|
+
create_deployed: __create_deployed_spec
|
|
70
609
|
|
|
71
|
-
class
|
|
610
|
+
class ___create_deployed_spec(typing_extensions.Protocol):
|
|
72
611
|
def __call__(
|
|
73
612
|
self,
|
|
74
613
|
/,
|
|
75
614
|
deployment_name: str,
|
|
76
615
|
env_dict: dict[str, str],
|
|
77
|
-
namespace=
|
|
616
|
+
namespace=None,
|
|
78
617
|
client: typing.Optional[modal.client.Client] = None,
|
|
79
618
|
environment_name: typing.Optional[str] = None,
|
|
80
619
|
overwrite: bool = False,
|
|
81
|
-
) -> str:
|
|
620
|
+
) -> str:
|
|
621
|
+
"""mdmd:hidden"""
|
|
622
|
+
...
|
|
623
|
+
|
|
82
624
|
async def aio(
|
|
83
625
|
self,
|
|
84
626
|
/,
|
|
85
627
|
deployment_name: str,
|
|
86
628
|
env_dict: dict[str, str],
|
|
87
|
-
namespace=
|
|
629
|
+
namespace=None,
|
|
88
630
|
client: typing.Optional[modal.client.Client] = None,
|
|
89
631
|
environment_name: typing.Optional[str] = None,
|
|
90
632
|
overwrite: bool = False,
|
|
91
|
-
) -> str:
|
|
633
|
+
) -> str:
|
|
634
|
+
"""mdmd:hidden"""
|
|
635
|
+
...
|
|
92
636
|
|
|
93
|
-
|
|
637
|
+
_create_deployed: ___create_deployed_spec
|
|
638
|
+
|
|
639
|
+
class __info_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
640
|
+
def __call__(self, /) -> SecretInfo:
|
|
641
|
+
"""Return information about the Secret object."""
|
|
642
|
+
...
|
|
643
|
+
|
|
644
|
+
async def aio(self, /) -> SecretInfo:
|
|
645
|
+
"""Return information about the Secret object."""
|
|
646
|
+
...
|
|
647
|
+
|
|
648
|
+
info: __info_spec[typing_extensions.Self]
|