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.

Files changed (160) hide show
  1. modal/__init__.py +0 -2
  2. modal/__main__.py +3 -4
  3. modal/_billing.py +80 -0
  4. modal/_clustered_functions.py +7 -3
  5. modal/_clustered_functions.pyi +15 -3
  6. modal/_container_entrypoint.py +51 -69
  7. modal/_functions.py +508 -240
  8. modal/_grpc_client.py +171 -0
  9. modal/_load_context.py +105 -0
  10. modal/_object.py +81 -21
  11. modal/_output.py +58 -45
  12. modal/_partial_function.py +48 -73
  13. modal/_pty.py +7 -3
  14. modal/_resolver.py +26 -46
  15. modal/_runtime/asgi.py +4 -3
  16. modal/_runtime/container_io_manager.py +358 -220
  17. modal/_runtime/container_io_manager.pyi +296 -101
  18. modal/_runtime/execution_context.py +18 -2
  19. modal/_runtime/execution_context.pyi +64 -7
  20. modal/_runtime/gpu_memory_snapshot.py +262 -57
  21. modal/_runtime/user_code_imports.py +28 -58
  22. modal/_serialization.py +90 -6
  23. modal/_traceback.py +42 -1
  24. modal/_tunnel.pyi +380 -12
  25. modal/_utils/async_utils.py +84 -29
  26. modal/_utils/auth_token_manager.py +111 -0
  27. modal/_utils/blob_utils.py +181 -58
  28. modal/_utils/deprecation.py +19 -0
  29. modal/_utils/function_utils.py +91 -47
  30. modal/_utils/grpc_utils.py +89 -66
  31. modal/_utils/mount_utils.py +26 -1
  32. modal/_utils/name_utils.py +17 -3
  33. modal/_utils/task_command_router_client.py +536 -0
  34. modal/_utils/time_utils.py +34 -6
  35. modal/app.py +256 -88
  36. modal/app.pyi +909 -92
  37. modal/billing.py +5 -0
  38. modal/builder/2025.06.txt +18 -0
  39. modal/builder/PREVIEW.txt +18 -0
  40. modal/builder/base-images.json +58 -0
  41. modal/cli/_download.py +19 -3
  42. modal/cli/_traceback.py +3 -2
  43. modal/cli/app.py +4 -4
  44. modal/cli/cluster.py +15 -7
  45. modal/cli/config.py +5 -3
  46. modal/cli/container.py +7 -6
  47. modal/cli/dict.py +22 -16
  48. modal/cli/entry_point.py +12 -5
  49. modal/cli/environment.py +5 -4
  50. modal/cli/import_refs.py +3 -3
  51. modal/cli/launch.py +102 -5
  52. modal/cli/network_file_system.py +11 -12
  53. modal/cli/profile.py +3 -2
  54. modal/cli/programs/launch_instance_ssh.py +94 -0
  55. modal/cli/programs/run_jupyter.py +1 -1
  56. modal/cli/programs/run_marimo.py +95 -0
  57. modal/cli/programs/vscode.py +1 -1
  58. modal/cli/queues.py +57 -26
  59. modal/cli/run.py +91 -23
  60. modal/cli/secret.py +48 -22
  61. modal/cli/token.py +7 -8
  62. modal/cli/utils.py +4 -7
  63. modal/cli/volume.py +31 -25
  64. modal/client.py +15 -85
  65. modal/client.pyi +183 -62
  66. modal/cloud_bucket_mount.py +5 -3
  67. modal/cloud_bucket_mount.pyi +197 -5
  68. modal/cls.py +200 -126
  69. modal/cls.pyi +446 -68
  70. modal/config.py +29 -11
  71. modal/container_process.py +319 -19
  72. modal/container_process.pyi +190 -20
  73. modal/dict.py +290 -71
  74. modal/dict.pyi +835 -83
  75. modal/environments.py +15 -27
  76. modal/environments.pyi +46 -24
  77. modal/exception.py +14 -2
  78. modal/experimental/__init__.py +194 -40
  79. modal/experimental/flash.py +618 -0
  80. modal/experimental/flash.pyi +380 -0
  81. modal/experimental/ipython.py +11 -7
  82. modal/file_io.py +29 -36
  83. modal/file_io.pyi +251 -53
  84. modal/file_pattern_matcher.py +56 -16
  85. modal/functions.pyi +673 -92
  86. modal/gpu.py +1 -1
  87. modal/image.py +528 -176
  88. modal/image.pyi +1572 -145
  89. modal/io_streams.py +458 -128
  90. modal/io_streams.pyi +433 -52
  91. modal/mount.py +216 -151
  92. modal/mount.pyi +225 -78
  93. modal/network_file_system.py +45 -62
  94. modal/network_file_system.pyi +277 -56
  95. modal/object.pyi +93 -17
  96. modal/parallel_map.py +942 -129
  97. modal/parallel_map.pyi +294 -15
  98. modal/partial_function.py +0 -2
  99. modal/partial_function.pyi +234 -19
  100. modal/proxy.py +17 -8
  101. modal/proxy.pyi +36 -3
  102. modal/queue.py +270 -65
  103. modal/queue.pyi +817 -57
  104. modal/runner.py +115 -101
  105. modal/runner.pyi +205 -49
  106. modal/sandbox.py +512 -136
  107. modal/sandbox.pyi +845 -111
  108. modal/schedule.py +1 -1
  109. modal/secret.py +300 -70
  110. modal/secret.pyi +589 -34
  111. modal/serving.py +7 -11
  112. modal/serving.pyi +7 -8
  113. modal/snapshot.py +11 -8
  114. modal/snapshot.pyi +25 -4
  115. modal/token_flow.py +4 -4
  116. modal/token_flow.pyi +28 -8
  117. modal/volume.py +416 -158
  118. modal/volume.pyi +1117 -121
  119. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/METADATA +10 -9
  120. modal-1.2.3.dev7.dist-info/RECORD +195 -0
  121. modal_docs/mdmd/mdmd.py +17 -4
  122. modal_proto/api.proto +534 -79
  123. modal_proto/api_grpc.py +337 -1
  124. modal_proto/api_pb2.py +1522 -968
  125. modal_proto/api_pb2.pyi +1619 -134
  126. modal_proto/api_pb2_grpc.py +699 -4
  127. modal_proto/api_pb2_grpc.pyi +226 -14
  128. modal_proto/modal_api_grpc.py +175 -154
  129. modal_proto/sandbox_router.proto +145 -0
  130. modal_proto/sandbox_router_grpc.py +105 -0
  131. modal_proto/sandbox_router_pb2.py +149 -0
  132. modal_proto/sandbox_router_pb2.pyi +333 -0
  133. modal_proto/sandbox_router_pb2_grpc.py +203 -0
  134. modal_proto/sandbox_router_pb2_grpc.pyi +75 -0
  135. modal_proto/task_command_router.proto +144 -0
  136. modal_proto/task_command_router_grpc.py +105 -0
  137. modal_proto/task_command_router_pb2.py +149 -0
  138. modal_proto/task_command_router_pb2.pyi +333 -0
  139. modal_proto/task_command_router_pb2_grpc.py +203 -0
  140. modal_proto/task_command_router_pb2_grpc.pyi +75 -0
  141. modal_version/__init__.py +1 -1
  142. modal/requirements/PREVIEW.txt +0 -16
  143. modal/requirements/base-images.json +0 -26
  144. modal-1.0.3.dev10.dist-info/RECORD +0 -179
  145. modal_proto/modal_options_grpc.py +0 -3
  146. modal_proto/options.proto +0 -19
  147. modal_proto/options_grpc.py +0 -3
  148. modal_proto/options_pb2.py +0 -35
  149. modal_proto/options_pb2.pyi +0 -20
  150. modal_proto/options_pb2_grpc.py +0 -4
  151. modal_proto/options_pb2_grpc.pyi +0 -7
  152. /modal/{requirements → builder}/2023.12.312.txt +0 -0
  153. /modal/{requirements → builder}/2023.12.txt +0 -0
  154. /modal/{requirements → builder}/2024.04.txt +0 -0
  155. /modal/{requirements → builder}/2024.10.txt +0 -0
  156. /modal/{requirements → builder}/README.md +0 -0
  157. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/WHEEL +0 -0
  158. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/entry_points.txt +0 -0
  159. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/licenses/LICENSE +0 -0
  160. {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
- namespace=1,
22
- client: typing.Optional[modal.client._Client] = None,
434
+ *,
435
+ namespace=None,
23
436
  environment_name: typing.Optional[str] = None,
24
437
  required_keys: list[str] = [],
25
- ) -> _Secret: ...
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=1,
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
- def __init__(self, *args, **kwargs): ...
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, *, namespace=1, environment_name: typing.Optional[str] = None, required_keys: list[str] = []
47
- ) -> Secret: ...
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
- class __lookup_spec(typing_extensions.Protocol):
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
- name: str,
54
- namespace=1,
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
- required_keys: list[str] = [],
58
- ) -> Secret: ...
590
+ overwrite: bool = False,
591
+ ) -> str:
592
+ """mdmd:hidden"""
593
+ ...
594
+
59
595
  async def aio(
60
596
  self,
61
597
  /,
62
- name: str,
63
- namespace=1,
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
- required_keys: list[str] = [],
67
- ) -> Secret: ...
603
+ overwrite: bool = False,
604
+ ) -> str:
605
+ """mdmd:hidden"""
606
+ ...
68
607
 
69
- lookup: __lookup_spec
608
+ create_deployed: __create_deployed_spec
70
609
 
71
- class __create_deployed_spec(typing_extensions.Protocol):
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=1,
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=1,
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
- create_deployed: __create_deployed_spec
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]