modal 0.67.6__py3-none-any.whl → 0.67.11__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.
- modal/_clustered_functions.py +2 -2
- modal/_clustered_functions.pyi +2 -2
- modal/_container_entrypoint.py +5 -4
- modal/_output.py +29 -28
- modal/_pty.py +2 -2
- modal/_resolver.py +6 -5
- modal/_resources.py +3 -3
- modal/_runtime/asgi.py +7 -6
- modal/_runtime/container_io_manager.py +22 -26
- modal/_runtime/execution_context.py +2 -2
- modal/_runtime/telemetry.py +1 -2
- modal/_runtime/user_code_imports.py +12 -14
- modal/_serialization.py +3 -7
- modal/_traceback.py +5 -5
- modal/_tunnel.py +4 -3
- modal/_tunnel.pyi +2 -2
- modal/_utils/async_utils.py +8 -15
- modal/_utils/blob_utils.py +4 -3
- modal/_utils/function_utils.py +14 -10
- modal/_utils/grpc_testing.py +7 -6
- modal/_utils/grpc_utils.py +2 -3
- modal/_utils/hash_utils.py +2 -2
- modal/_utils/mount_utils.py +5 -4
- modal/_utils/package_utils.py +2 -3
- modal/_utils/pattern_matcher.py +6 -6
- modal/_utils/rand_pb_testing.py +3 -3
- modal/_utils/shell_utils.py +2 -1
- modal/_vendor/a2wsgi_wsgi.py +62 -72
- modal/_vendor/cloudpickle.py +1 -1
- modal/_watcher.py +8 -7
- modal/app.py +29 -34
- modal/app.pyi +102 -97
- modal/call_graph.py +6 -6
- modal/cli/_download.py +3 -2
- modal/cli/_traceback.py +4 -4
- modal/cli/app.py +4 -4
- modal/cli/container.py +4 -4
- modal/cli/dict.py +1 -1
- modal/cli/environment.py +2 -3
- modal/cli/launch.py +2 -2
- modal/cli/network_file_system.py +1 -1
- modal/cli/profile.py +1 -1
- modal/cli/programs/run_jupyter.py +2 -2
- modal/cli/programs/vscode.py +3 -3
- modal/cli/queues.py +1 -1
- modal/cli/run.py +6 -6
- modal/cli/secret.py +3 -3
- modal/cli/utils.py +2 -1
- modal/cli/volume.py +3 -3
- modal/client.py +6 -11
- modal/client.pyi +18 -27
- modal/cloud_bucket_mount.py +3 -3
- modal/cloud_bucket_mount.pyi +2 -2
- modal/cls.py +30 -30
- modal/cls.pyi +35 -34
- modal/config.py +3 -2
- modal/dict.py +4 -3
- modal/dict.pyi +10 -9
- modal/environments.py +3 -3
- modal/environments.pyi +3 -3
- modal/exception.py +2 -3
- modal/functions.py +105 -35
- modal/functions.pyi +71 -48
- modal/image.py +45 -48
- modal/image.pyi +102 -101
- modal/io_streams.py +4 -7
- modal/io_streams.pyi +14 -13
- modal/mount.py +23 -22
- modal/mount.pyi +28 -29
- modal/network_file_system.py +7 -6
- modal/network_file_system.pyi +12 -11
- modal/object.py +9 -8
- modal/object.pyi +47 -34
- modal/output.py +2 -1
- modal/parallel_map.py +4 -4
- modal/partial_function.py +9 -13
- modal/partial_function.pyi +17 -18
- modal/queue.py +9 -8
- modal/queue.pyi +23 -22
- modal/retries.py +38 -0
- modal/runner.py +8 -7
- modal/runner.pyi +8 -14
- modal/running_app.py +3 -3
- modal/sandbox.py +14 -13
- modal/sandbox.pyi +67 -72
- modal/scheduler_placement.py +2 -1
- modal/secret.py +7 -7
- modal/secret.pyi +12 -12
- modal/serving.py +4 -3
- modal/serving.pyi +5 -4
- modal/token_flow.py +3 -2
- modal/token_flow.pyi +3 -3
- modal/volume.py +7 -12
- modal/volume.pyi +17 -16
- {modal-0.67.6.dist-info → modal-0.67.11.dist-info}/METADATA +1 -1
- modal-0.67.11.dist-info/RECORD +168 -0
- modal_docs/mdmd/signatures.py +1 -2
- modal_version/_version_generated.py +1 -1
- modal-0.67.6.dist-info/RECORD +0 -168
- {modal-0.67.6.dist-info → modal-0.67.11.dist-info}/LICENSE +0 -0
- {modal-0.67.6.dist-info → modal-0.67.11.dist-info}/WHEEL +0 -0
- {modal-0.67.6.dist-info → modal-0.67.11.dist-info}/entry_points.txt +0 -0
- {modal-0.67.6.dist-info → modal-0.67.11.dist-info}/top_level.txt +0 -0
modal/app.pyi
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import collections.abc
|
1
2
|
import modal._utils.function_utils
|
2
3
|
import modal.client
|
3
4
|
import modal.cloud_bucket_mount
|
@@ -49,9 +50,9 @@ class LocalEntrypoint:
|
|
49
50
|
@property
|
50
51
|
def stub(self) -> App: ...
|
51
52
|
|
52
|
-
def check_sequence(items: typing.Sequence[typing.Any], item_type:
|
53
|
+
def check_sequence(items: typing.Sequence[typing.Any], item_type: type[typing.Any], error_msg: str) -> None: ...
|
53
54
|
|
54
|
-
CLS_T = typing.TypeVar("CLS_T", bound="
|
55
|
+
CLS_T = typing.TypeVar("CLS_T", bound="type[typing.Any]")
|
55
56
|
|
56
57
|
P = typing_extensions.ParamSpec("P")
|
57
58
|
|
@@ -66,24 +67,24 @@ class _FunctionDecoratorType:
|
|
66
67
|
) -> modal.functions.Function[P, ReturnType, OriginalReturnType]: ...
|
67
68
|
@typing.overload
|
68
69
|
def __call__(
|
69
|
-
self, func: typing.Callable[P,
|
70
|
-
) -> modal.functions.Function[P, ReturnType,
|
70
|
+
self, func: typing.Callable[P, collections.abc.Coroutine[typing.Any, typing.Any, ReturnType]]
|
71
|
+
) -> modal.functions.Function[P, ReturnType, collections.abc.Coroutine[typing.Any, typing.Any, ReturnType]]: ...
|
71
72
|
@typing.overload
|
72
73
|
def __call__(self, func: typing.Callable[P, ReturnType]) -> modal.functions.Function[P, ReturnType, ReturnType]: ...
|
73
74
|
|
74
75
|
class _App:
|
75
|
-
_all_apps: typing.ClassVar[
|
76
|
+
_all_apps: typing.ClassVar[dict[typing.Optional[str], list[_App]]]
|
76
77
|
_container_app: typing.ClassVar[typing.Optional[modal.running_app.RunningApp]]
|
77
78
|
_name: typing.Optional[str]
|
78
79
|
_description: typing.Optional[str]
|
79
|
-
_functions:
|
80
|
-
_classes:
|
80
|
+
_functions: dict[str, modal.functions._Function]
|
81
|
+
_classes: dict[str, modal.cls._Cls]
|
81
82
|
_image: typing.Optional[modal.image._Image]
|
82
|
-
_mounts:
|
83
|
-
_secrets:
|
84
|
-
_volumes:
|
85
|
-
_web_endpoints:
|
86
|
-
_local_entrypoints:
|
83
|
+
_mounts: collections.abc.Sequence[modal.mount._Mount]
|
84
|
+
_secrets: collections.abc.Sequence[modal.secret._Secret]
|
85
|
+
_volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume._Volume]
|
86
|
+
_web_endpoints: list[str]
|
87
|
+
_local_entrypoints: dict[str, _LocalEntrypoint]
|
87
88
|
_app_id: typing.Optional[str]
|
88
89
|
_running_app: typing.Optional[modal.running_app.RunningApp]
|
89
90
|
_client: typing.Optional[modal.client._Client]
|
@@ -93,9 +94,9 @@ class _App:
|
|
93
94
|
name: typing.Optional[str] = None,
|
94
95
|
*,
|
95
96
|
image: typing.Optional[modal.image._Image] = None,
|
96
|
-
mounts:
|
97
|
-
secrets:
|
98
|
-
volumes:
|
97
|
+
mounts: collections.abc.Sequence[modal.mount._Mount] = [],
|
98
|
+
secrets: collections.abc.Sequence[modal.secret._Secret] = [],
|
99
|
+
volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume._Volume] = {},
|
99
100
|
) -> None: ...
|
100
101
|
@property
|
101
102
|
def name(self) -> typing.Optional[str]: ...
|
@@ -139,15 +140,15 @@ class _App:
|
|
139
140
|
def _add_class(self, tag: str, cls: modal.cls._Cls): ...
|
140
141
|
def _init_container(self, client: modal.client._Client, running_app: modal.running_app.RunningApp): ...
|
141
142
|
@property
|
142
|
-
def registered_functions(self) ->
|
143
|
+
def registered_functions(self) -> dict[str, modal.functions._Function]: ...
|
143
144
|
@property
|
144
|
-
def registered_classes(self) ->
|
145
|
+
def registered_classes(self) -> dict[str, modal.functions._Function]: ...
|
145
146
|
@property
|
146
|
-
def registered_entrypoints(self) ->
|
147
|
+
def registered_entrypoints(self) -> dict[str, _LocalEntrypoint]: ...
|
147
148
|
@property
|
148
|
-
def indexed_objects(self) ->
|
149
|
+
def indexed_objects(self) -> dict[str, modal.object._Object]: ...
|
149
150
|
@property
|
150
|
-
def registered_web_endpoints(self) ->
|
151
|
+
def registered_web_endpoints(self) -> list[str]: ...
|
151
152
|
def local_entrypoint(
|
152
153
|
self, _warn_parentheses_missing: typing.Any = None, *, name: typing.Optional[str] = None
|
153
154
|
) -> typing.Callable[[typing.Callable[..., typing.Any]], _LocalEntrypoint]: ...
|
@@ -157,22 +158,22 @@ class _App:
|
|
157
158
|
*,
|
158
159
|
image: typing.Optional[modal.image._Image] = None,
|
159
160
|
schedule: typing.Optional[modal.schedule.Schedule] = None,
|
160
|
-
secrets:
|
161
|
+
secrets: collections.abc.Sequence[modal.secret._Secret] = (),
|
161
162
|
gpu: typing.Union[
|
162
|
-
None, bool, str, modal.gpu._GPUConfig,
|
163
|
+
None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
|
163
164
|
] = None,
|
164
165
|
serialized: bool = False,
|
165
|
-
mounts:
|
166
|
-
network_file_systems:
|
166
|
+
mounts: collections.abc.Sequence[modal.mount._Mount] = (),
|
167
|
+
network_file_systems: dict[
|
167
168
|
typing.Union[str, pathlib.PurePosixPath], modal.network_file_system._NetworkFileSystem
|
168
169
|
] = {},
|
169
|
-
volumes:
|
170
|
+
volumes: dict[
|
170
171
|
typing.Union[str, pathlib.PurePosixPath],
|
171
172
|
typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
|
172
173
|
] = {},
|
173
174
|
allow_cross_region_volumes: bool = False,
|
174
|
-
cpu: typing.Union[float,
|
175
|
-
memory: typing.Union[int,
|
175
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
176
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
176
177
|
ephemeral_disk: typing.Optional[int] = None,
|
177
178
|
proxy: typing.Optional[modal.proxy._Proxy] = None,
|
178
179
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
@@ -184,7 +185,7 @@ class _App:
|
|
184
185
|
name: typing.Optional[str] = None,
|
185
186
|
is_generator: typing.Optional[bool] = None,
|
186
187
|
cloud: typing.Optional[str] = None,
|
187
|
-
region: typing.Union[str,
|
188
|
+
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
188
189
|
enable_memory_snapshot: bool = False,
|
189
190
|
block_network: bool = False,
|
190
191
|
max_inputs: typing.Optional[int] = None,
|
@@ -203,22 +204,22 @@ class _App:
|
|
203
204
|
_warn_parentheses_missing: typing.Optional[bool] = None,
|
204
205
|
*,
|
205
206
|
image: typing.Optional[modal.image._Image] = None,
|
206
|
-
secrets:
|
207
|
+
secrets: collections.abc.Sequence[modal.secret._Secret] = (),
|
207
208
|
gpu: typing.Union[
|
208
|
-
None, bool, str, modal.gpu._GPUConfig,
|
209
|
+
None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
|
209
210
|
] = None,
|
210
211
|
serialized: bool = False,
|
211
|
-
mounts:
|
212
|
-
network_file_systems:
|
212
|
+
mounts: collections.abc.Sequence[modal.mount._Mount] = (),
|
213
|
+
network_file_systems: dict[
|
213
214
|
typing.Union[str, pathlib.PurePosixPath], modal.network_file_system._NetworkFileSystem
|
214
215
|
] = {},
|
215
|
-
volumes:
|
216
|
+
volumes: dict[
|
216
217
|
typing.Union[str, pathlib.PurePosixPath],
|
217
218
|
typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
|
218
219
|
] = {},
|
219
220
|
allow_cross_region_volumes: bool = False,
|
220
|
-
cpu: typing.Union[float,
|
221
|
-
memory: typing.Union[int,
|
221
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
222
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
222
223
|
ephemeral_disk: typing.Optional[int] = None,
|
223
224
|
proxy: typing.Optional[modal.proxy._Proxy] = None,
|
224
225
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
@@ -228,7 +229,7 @@ class _App:
|
|
228
229
|
timeout: typing.Optional[int] = None,
|
229
230
|
keep_warm: typing.Optional[int] = None,
|
230
231
|
cloud: typing.Optional[str] = None,
|
231
|
-
region: typing.Union[str,
|
232
|
+
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
232
233
|
enable_memory_snapshot: bool = False,
|
233
234
|
block_network: bool = False,
|
234
235
|
max_inputs: typing.Optional[int] = None,
|
@@ -241,20 +242,20 @@ class _App:
|
|
241
242
|
self,
|
242
243
|
*entrypoint_args: str,
|
243
244
|
image: typing.Optional[modal.image._Image] = None,
|
244
|
-
mounts:
|
245
|
-
secrets:
|
246
|
-
network_file_systems:
|
245
|
+
mounts: collections.abc.Sequence[modal.mount._Mount] = (),
|
246
|
+
secrets: collections.abc.Sequence[modal.secret._Secret] = (),
|
247
|
+
network_file_systems: dict[
|
247
248
|
typing.Union[str, pathlib.PurePosixPath], modal.network_file_system._NetworkFileSystem
|
248
249
|
] = {},
|
249
250
|
timeout: typing.Optional[int] = None,
|
250
251
|
workdir: typing.Optional[str] = None,
|
251
252
|
gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
|
252
253
|
cloud: typing.Optional[str] = None,
|
253
|
-
region: typing.Union[str,
|
254
|
-
cpu: typing.Union[float,
|
255
|
-
memory: typing.Union[int,
|
254
|
+
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
255
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
256
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
256
257
|
block_network: bool = False,
|
257
|
-
volumes:
|
258
|
+
volumes: dict[
|
258
259
|
typing.Union[str, pathlib.PurePosixPath],
|
259
260
|
typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
|
260
261
|
] = {},
|
@@ -262,23 +263,25 @@ class _App:
|
|
262
263
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
263
264
|
) -> modal.sandbox._Sandbox: ...
|
264
265
|
def include(self, /, other_app: _App): ...
|
265
|
-
def _logs(
|
266
|
+
def _logs(
|
267
|
+
self, client: typing.Optional[modal.client._Client] = None
|
268
|
+
) -> collections.abc.AsyncGenerator[str, None]: ...
|
266
269
|
@classmethod
|
267
270
|
def _reset_container_app(cls): ...
|
268
271
|
|
269
272
|
class App:
|
270
|
-
_all_apps: typing.ClassVar[
|
273
|
+
_all_apps: typing.ClassVar[dict[typing.Optional[str], list[App]]]
|
271
274
|
_container_app: typing.ClassVar[typing.Optional[modal.running_app.RunningApp]]
|
272
275
|
_name: typing.Optional[str]
|
273
276
|
_description: typing.Optional[str]
|
274
|
-
_functions:
|
275
|
-
_classes:
|
277
|
+
_functions: dict[str, modal.functions.Function]
|
278
|
+
_classes: dict[str, modal.cls.Cls]
|
276
279
|
_image: typing.Optional[modal.image.Image]
|
277
|
-
_mounts:
|
278
|
-
_secrets:
|
279
|
-
_volumes:
|
280
|
-
_web_endpoints:
|
281
|
-
_local_entrypoints:
|
280
|
+
_mounts: collections.abc.Sequence[modal.mount.Mount]
|
281
|
+
_secrets: collections.abc.Sequence[modal.secret.Secret]
|
282
|
+
_volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume.Volume]
|
283
|
+
_web_endpoints: list[str]
|
284
|
+
_local_entrypoints: dict[str, LocalEntrypoint]
|
282
285
|
_app_id: typing.Optional[str]
|
283
286
|
_running_app: typing.Optional[modal.running_app.RunningApp]
|
284
287
|
_client: typing.Optional[modal.client.Client]
|
@@ -288,9 +291,9 @@ class App:
|
|
288
291
|
name: typing.Optional[str] = None,
|
289
292
|
*,
|
290
293
|
image: typing.Optional[modal.image.Image] = None,
|
291
|
-
mounts:
|
292
|
-
secrets:
|
293
|
-
volumes:
|
294
|
+
mounts: collections.abc.Sequence[modal.mount.Mount] = [],
|
295
|
+
secrets: collections.abc.Sequence[modal.secret.Secret] = [],
|
296
|
+
volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume.Volume] = {},
|
294
297
|
) -> None: ...
|
295
298
|
@property
|
296
299
|
def name(self) -> typing.Optional[str]: ...
|
@@ -365,15 +368,15 @@ class App:
|
|
365
368
|
def _add_class(self, tag: str, cls: modal.cls.Cls): ...
|
366
369
|
def _init_container(self, client: modal.client.Client, running_app: modal.running_app.RunningApp): ...
|
367
370
|
@property
|
368
|
-
def registered_functions(self) ->
|
371
|
+
def registered_functions(self) -> dict[str, modal.functions.Function]: ...
|
369
372
|
@property
|
370
|
-
def registered_classes(self) ->
|
373
|
+
def registered_classes(self) -> dict[str, modal.functions.Function]: ...
|
371
374
|
@property
|
372
|
-
def registered_entrypoints(self) ->
|
375
|
+
def registered_entrypoints(self) -> dict[str, LocalEntrypoint]: ...
|
373
376
|
@property
|
374
|
-
def indexed_objects(self) ->
|
377
|
+
def indexed_objects(self) -> dict[str, modal.object.Object]: ...
|
375
378
|
@property
|
376
|
-
def registered_web_endpoints(self) ->
|
379
|
+
def registered_web_endpoints(self) -> list[str]: ...
|
377
380
|
def local_entrypoint(
|
378
381
|
self, _warn_parentheses_missing: typing.Any = None, *, name: typing.Optional[str] = None
|
379
382
|
) -> typing.Callable[[typing.Callable[..., typing.Any]], LocalEntrypoint]: ...
|
@@ -383,22 +386,22 @@ class App:
|
|
383
386
|
*,
|
384
387
|
image: typing.Optional[modal.image.Image] = None,
|
385
388
|
schedule: typing.Optional[modal.schedule.Schedule] = None,
|
386
|
-
secrets:
|
389
|
+
secrets: collections.abc.Sequence[modal.secret.Secret] = (),
|
387
390
|
gpu: typing.Union[
|
388
|
-
None, bool, str, modal.gpu._GPUConfig,
|
391
|
+
None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
|
389
392
|
] = None,
|
390
393
|
serialized: bool = False,
|
391
|
-
mounts:
|
392
|
-
network_file_systems:
|
394
|
+
mounts: collections.abc.Sequence[modal.mount.Mount] = (),
|
395
|
+
network_file_systems: dict[
|
393
396
|
typing.Union[str, pathlib.PurePosixPath], modal.network_file_system.NetworkFileSystem
|
394
397
|
] = {},
|
395
|
-
volumes:
|
398
|
+
volumes: dict[
|
396
399
|
typing.Union[str, pathlib.PurePosixPath],
|
397
400
|
typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
|
398
401
|
] = {},
|
399
402
|
allow_cross_region_volumes: bool = False,
|
400
|
-
cpu: typing.Union[float,
|
401
|
-
memory: typing.Union[int,
|
403
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
404
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
402
405
|
ephemeral_disk: typing.Optional[int] = None,
|
403
406
|
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
404
407
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
@@ -410,7 +413,7 @@ class App:
|
|
410
413
|
name: typing.Optional[str] = None,
|
411
414
|
is_generator: typing.Optional[bool] = None,
|
412
415
|
cloud: typing.Optional[str] = None,
|
413
|
-
region: typing.Union[str,
|
416
|
+
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
414
417
|
enable_memory_snapshot: bool = False,
|
415
418
|
block_network: bool = False,
|
416
419
|
max_inputs: typing.Optional[int] = None,
|
@@ -429,22 +432,22 @@ class App:
|
|
429
432
|
_warn_parentheses_missing: typing.Optional[bool] = None,
|
430
433
|
*,
|
431
434
|
image: typing.Optional[modal.image.Image] = None,
|
432
|
-
secrets:
|
435
|
+
secrets: collections.abc.Sequence[modal.secret.Secret] = (),
|
433
436
|
gpu: typing.Union[
|
434
|
-
None, bool, str, modal.gpu._GPUConfig,
|
437
|
+
None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
|
435
438
|
] = None,
|
436
439
|
serialized: bool = False,
|
437
|
-
mounts:
|
438
|
-
network_file_systems:
|
440
|
+
mounts: collections.abc.Sequence[modal.mount.Mount] = (),
|
441
|
+
network_file_systems: dict[
|
439
442
|
typing.Union[str, pathlib.PurePosixPath], modal.network_file_system.NetworkFileSystem
|
440
443
|
] = {},
|
441
|
-
volumes:
|
444
|
+
volumes: dict[
|
442
445
|
typing.Union[str, pathlib.PurePosixPath],
|
443
446
|
typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
|
444
447
|
] = {},
|
445
448
|
allow_cross_region_volumes: bool = False,
|
446
|
-
cpu: typing.Union[float,
|
447
|
-
memory: typing.Union[int,
|
449
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
450
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
448
451
|
ephemeral_disk: typing.Optional[int] = None,
|
449
452
|
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
450
453
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
@@ -454,7 +457,7 @@ class App:
|
|
454
457
|
timeout: typing.Optional[int] = None,
|
455
458
|
keep_warm: typing.Optional[int] = None,
|
456
459
|
cloud: typing.Optional[str] = None,
|
457
|
-
region: typing.Union[str,
|
460
|
+
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
458
461
|
enable_memory_snapshot: bool = False,
|
459
462
|
block_network: bool = False,
|
460
463
|
max_inputs: typing.Optional[int] = None,
|
@@ -469,20 +472,20 @@ class App:
|
|
469
472
|
self,
|
470
473
|
*entrypoint_args: str,
|
471
474
|
image: typing.Optional[modal.image.Image] = None,
|
472
|
-
mounts:
|
473
|
-
secrets:
|
474
|
-
network_file_systems:
|
475
|
+
mounts: collections.abc.Sequence[modal.mount.Mount] = (),
|
476
|
+
secrets: collections.abc.Sequence[modal.secret.Secret] = (),
|
477
|
+
network_file_systems: dict[
|
475
478
|
typing.Union[str, pathlib.PurePosixPath], modal.network_file_system.NetworkFileSystem
|
476
479
|
] = {},
|
477
480
|
timeout: typing.Optional[int] = None,
|
478
481
|
workdir: typing.Optional[str] = None,
|
479
482
|
gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
|
480
483
|
cloud: typing.Optional[str] = None,
|
481
|
-
region: typing.Union[str,
|
482
|
-
cpu: typing.Union[float,
|
483
|
-
memory: typing.Union[int,
|
484
|
+
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
485
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
486
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
484
487
|
block_network: bool = False,
|
485
|
-
volumes:
|
488
|
+
volumes: dict[
|
486
489
|
typing.Union[str, pathlib.PurePosixPath],
|
487
490
|
typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
|
488
491
|
] = {},
|
@@ -493,20 +496,20 @@ class App:
|
|
493
496
|
self,
|
494
497
|
*entrypoint_args: str,
|
495
498
|
image: typing.Optional[modal.image.Image] = None,
|
496
|
-
mounts:
|
497
|
-
secrets:
|
498
|
-
network_file_systems:
|
499
|
+
mounts: collections.abc.Sequence[modal.mount.Mount] = (),
|
500
|
+
secrets: collections.abc.Sequence[modal.secret.Secret] = (),
|
501
|
+
network_file_systems: dict[
|
499
502
|
typing.Union[str, pathlib.PurePosixPath], modal.network_file_system.NetworkFileSystem
|
500
503
|
] = {},
|
501
504
|
timeout: typing.Optional[int] = None,
|
502
505
|
workdir: typing.Optional[str] = None,
|
503
506
|
gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
|
504
507
|
cloud: typing.Optional[str] = None,
|
505
|
-
region: typing.Union[str,
|
506
|
-
cpu: typing.Union[float,
|
507
|
-
memory: typing.Union[int,
|
508
|
+
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
509
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
510
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
508
511
|
block_network: bool = False,
|
509
|
-
volumes:
|
512
|
+
volumes: dict[
|
510
513
|
typing.Union[str, pathlib.PurePosixPath],
|
511
514
|
typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
|
512
515
|
] = {},
|
@@ -522,7 +525,9 @@ class App:
|
|
522
525
|
def __call__(
|
523
526
|
self, client: typing.Optional[modal.client.Client] = None
|
524
527
|
) -> typing.Generator[str, None, None]: ...
|
525
|
-
def aio(
|
528
|
+
def aio(
|
529
|
+
self, client: typing.Optional[modal.client.Client] = None
|
530
|
+
) -> collections.abc.AsyncGenerator[str, None]: ...
|
526
531
|
|
527
532
|
_logs: ___logs_spec
|
528
533
|
|
@@ -536,9 +541,9 @@ class _Stub(_App):
|
|
536
541
|
name: typing.Optional[str] = None,
|
537
542
|
*,
|
538
543
|
image: typing.Optional[modal.image._Image] = None,
|
539
|
-
mounts:
|
540
|
-
secrets:
|
541
|
-
volumes:
|
544
|
+
mounts: collections.abc.Sequence[modal.mount._Mount] = [],
|
545
|
+
secrets: collections.abc.Sequence[modal.secret._Secret] = [],
|
546
|
+
volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume._Volume] = {},
|
542
547
|
): ...
|
543
548
|
|
544
549
|
class Stub(App):
|
@@ -547,9 +552,9 @@ class Stub(App):
|
|
547
552
|
name: typing.Optional[str] = None,
|
548
553
|
*,
|
549
554
|
image: typing.Optional[modal.image.Image] = None,
|
550
|
-
mounts:
|
551
|
-
secrets:
|
552
|
-
volumes:
|
555
|
+
mounts: collections.abc.Sequence[modal.mount.Mount] = [],
|
556
|
+
secrets: collections.abc.Sequence[modal.secret.Secret] = [],
|
557
|
+
volumes: dict[typing.Union[str, pathlib.PurePosixPath], modal.volume.Volume] = {},
|
553
558
|
) -> None: ...
|
554
559
|
|
555
560
|
_default_image: modal.image._Image
|
modal/call_graph.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright Modal Labs 2022
|
2
2
|
from dataclasses import dataclass
|
3
3
|
from enum import IntEnum
|
4
|
-
from typing import
|
4
|
+
from typing import Optional
|
5
5
|
|
6
6
|
from modal_proto import api_pb2
|
7
7
|
|
@@ -31,12 +31,12 @@ class InputInfo:
|
|
31
31
|
status: InputStatus
|
32
32
|
function_name: str
|
33
33
|
module_name: str
|
34
|
-
children:
|
34
|
+
children: list["InputInfo"]
|
35
35
|
|
36
36
|
|
37
|
-
def _reconstruct_call_graph(ser_graph: api_pb2.FunctionGetCallGraphResponse) ->
|
38
|
-
function_calls_by_id:
|
39
|
-
inputs_by_id:
|
37
|
+
def _reconstruct_call_graph(ser_graph: api_pb2.FunctionGetCallGraphResponse) -> list[InputInfo]:
|
38
|
+
function_calls_by_id: dict[str, api_pb2.FunctionCallCallGraphInfo] = {}
|
39
|
+
inputs_by_id: dict[str, api_pb2.InputCallGraphInfo] = {}
|
40
40
|
|
41
41
|
for function_call in ser_graph.function_calls:
|
42
42
|
function_calls_by_id[function_call.function_call_id] = function_call
|
@@ -44,7 +44,7 @@ def _reconstruct_call_graph(ser_graph: api_pb2.FunctionGetCallGraphResponse) ->
|
|
44
44
|
for input in ser_graph.inputs:
|
45
45
|
inputs_by_id[input.input_id] = input
|
46
46
|
|
47
|
-
input_info_by_id:
|
47
|
+
input_info_by_id: dict[str, InputInfo] = {}
|
48
48
|
result = []
|
49
49
|
|
50
50
|
def _reconstruct(input_id: str) -> Optional[InputInfo]:
|
modal/cli/_download.py
CHANGED
@@ -3,8 +3,9 @@ import asyncio
|
|
3
3
|
import os
|
4
4
|
import shutil
|
5
5
|
import sys
|
6
|
+
from collections.abc import AsyncIterator
|
6
7
|
from pathlib import Path, PurePosixPath
|
7
|
-
from typing import
|
8
|
+
from typing import Callable, Optional, Union
|
8
9
|
|
9
10
|
from click import UsageError
|
10
11
|
|
@@ -25,7 +26,7 @@ async def _volume_download(
|
|
25
26
|
):
|
26
27
|
is_pipe = local_destination == PIPE_PATH
|
27
28
|
|
28
|
-
q: asyncio.Queue[
|
29
|
+
q: asyncio.Queue[tuple[Optional[Path], Optional[FileEntry]]] = asyncio.Queue()
|
29
30
|
num_consumers = 1 if is_pipe else 10 # concurrency limit for downloading files
|
30
31
|
|
31
32
|
async def producer():
|
modal/cli/_traceback.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"""Helper functions related to displaying tracebacks in the CLI."""
|
3
3
|
import functools
|
4
4
|
import warnings
|
5
|
-
from typing import
|
5
|
+
from typing import Optional
|
6
6
|
|
7
7
|
from rich.console import Console, RenderResult, group
|
8
8
|
from rich.panel import Panel
|
@@ -20,14 +20,14 @@ def _render_stack(self, stack: Stack) -> RenderResult:
|
|
20
20
|
|
21
21
|
path_highlighter = PathHighlighter()
|
22
22
|
theme = self.theme
|
23
|
-
code_cache:
|
23
|
+
code_cache: dict[str, str] = {}
|
24
24
|
line_cache = getattr(stack, "line_cache", {})
|
25
25
|
task_id = None
|
26
26
|
|
27
27
|
def read_code(filename: str) -> str:
|
28
28
|
code = code_cache.get(filename)
|
29
29
|
if code is None:
|
30
|
-
with open(filename,
|
30
|
+
with open(filename, encoding="utf-8", errors="replace") as code_file:
|
31
31
|
code = code_file.read()
|
32
32
|
code_cache[filename] = code
|
33
33
|
return code
|
@@ -169,7 +169,7 @@ def highlight_modal_deprecation_warnings() -> None:
|
|
169
169
|
date = content[:10]
|
170
170
|
message = content[11:].strip()
|
171
171
|
try:
|
172
|
-
with open(filename,
|
172
|
+
with open(filename, encoding="utf-8", errors="replace") as code_file:
|
173
173
|
source = code_file.readlines()[lineno - 1].strip()
|
174
174
|
message = f"{message}\n\nSource: {filename}:{lineno}\n {source}"
|
175
175
|
except OSError:
|
modal/cli/app.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Copyright Modal Labs 2022
|
2
2
|
import re
|
3
|
-
from typing import
|
3
|
+
from typing import Optional, Union
|
4
4
|
|
5
5
|
import rich
|
6
6
|
import typer
|
@@ -56,7 +56,7 @@ def warn_on_name_option(command: str, app_identifier: str, name: str) -> str:
|
|
56
56
|
|
57
57
|
@app_cli.command("list")
|
58
58
|
@synchronizer.create_blocking
|
59
|
-
async def
|
59
|
+
async def list_(env: Optional[str] = ENV_OPTION, json: bool = False):
|
60
60
|
"""List Modal apps that are currently deployed/running or recently stopped."""
|
61
61
|
env = ensure_env(env)
|
62
62
|
client = await _Client.from_env()
|
@@ -65,7 +65,7 @@ async def list(env: Optional[str] = ENV_OPTION, json: bool = False):
|
|
65
65
|
api_pb2.AppListRequest(environment_name=_get_environment_name(env))
|
66
66
|
)
|
67
67
|
|
68
|
-
columns:
|
68
|
+
columns: list[Union[Column, str]] = [
|
69
69
|
Column("App ID", min_width=25), # Ensure that App ID is not truncated in slim terminals
|
70
70
|
"Description",
|
71
71
|
"State",
|
@@ -73,7 +73,7 @@ async def list(env: Optional[str] = ENV_OPTION, json: bool = False):
|
|
73
73
|
"Created at",
|
74
74
|
"Stopped at",
|
75
75
|
]
|
76
|
-
rows:
|
76
|
+
rows: list[list[Union[Text, str]]] = []
|
77
77
|
for app_stats in resp.apps:
|
78
78
|
state = APP_STATE_TO_MESSAGE.get(app_stats.state, Text("unknown", style="gray"))
|
79
79
|
rows.append(
|
modal/cli/container.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Copyright Modal Labs 2022
|
2
2
|
|
3
|
-
from typing import
|
3
|
+
from typing import Optional, Union
|
4
4
|
|
5
5
|
import typer
|
6
6
|
from rich.text import Text
|
@@ -21,7 +21,7 @@ container_cli = typer.Typer(name="container", help="Manage and connect to runnin
|
|
21
21
|
|
22
22
|
@container_cli.command("list")
|
23
23
|
@synchronizer.create_blocking
|
24
|
-
async def
|
24
|
+
async def list_(env: Optional[str] = ENV_OPTION, json: bool = False):
|
25
25
|
"""List all containers that are currently running."""
|
26
26
|
env = ensure_env(env)
|
27
27
|
client = await _Client.from_env()
|
@@ -31,7 +31,7 @@ async def list(env: Optional[str] = ENV_OPTION, json: bool = False):
|
|
31
31
|
)
|
32
32
|
|
33
33
|
column_names = ["Container ID", "App ID", "App Name", "Start Time"]
|
34
|
-
rows:
|
34
|
+
rows: list[list[Union[Text, str]]] = []
|
35
35
|
res.tasks.sort(key=lambda task: task.started_at, reverse=True)
|
36
36
|
for task_stats in res.tasks:
|
37
37
|
rows.append(
|
@@ -56,7 +56,7 @@ def logs(container_id: str = typer.Argument(help="Container ID")):
|
|
56
56
|
@synchronizer.create_blocking
|
57
57
|
async def exec(
|
58
58
|
container_id: str = typer.Argument(help="Container ID"),
|
59
|
-
command:
|
59
|
+
command: list[str] = typer.Argument(help="A command to run inside the container."),
|
60
60
|
pty: bool = typer.Option(default=True, help="Run the command using a PTY."),
|
61
61
|
):
|
62
62
|
"""Execute a command in a container."""
|
modal/cli/dict.py
CHANGED
@@ -36,7 +36,7 @@ async def create(name: str, *, env: Optional[str] = ENV_OPTION):
|
|
36
36
|
|
37
37
|
@dict_cli.command(name="list", rich_help_panel="Management")
|
38
38
|
@synchronizer.create_blocking
|
39
|
-
async def
|
39
|
+
async def list_(*, json: bool = False, env: Optional[str] = ENV_OPTION):
|
40
40
|
"""List all named Dicts."""
|
41
41
|
env = ensure_env(env)
|
42
42
|
client = await _Client.from_env()
|
modal/cli/environment.py
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
# Copyright Modal Labs 2023
|
2
|
-
from typing import Optional, Union
|
2
|
+
from typing import Annotated, Optional, Union
|
3
3
|
|
4
4
|
import typer
|
5
5
|
from click import UsageError
|
6
6
|
from grpclib import GRPCError, Status
|
7
7
|
from rich.text import Text
|
8
|
-
from typing_extensions import Annotated
|
9
8
|
|
10
9
|
from modal import environments
|
11
10
|
from modal._utils.name_utils import check_environment_name
|
@@ -37,7 +36,7 @@ class RenderableBool(Text):
|
|
37
36
|
|
38
37
|
|
39
38
|
@environment_cli.command(name="list", help="List all environments in the current workspace")
|
40
|
-
def
|
39
|
+
def list_(json: Optional[bool] = False):
|
41
40
|
envs = environments.list_environments()
|
42
41
|
|
43
42
|
# determine which environment is currently active, prioritizing the local default
|
modal/cli/launch.py
CHANGED
@@ -4,7 +4,7 @@ import inspect
|
|
4
4
|
import json
|
5
5
|
import os
|
6
6
|
from pathlib import Path
|
7
|
-
from typing import Any,
|
7
|
+
from typing import Any, Optional
|
8
8
|
|
9
9
|
from typer import Typer
|
10
10
|
|
@@ -25,7 +25,7 @@ launch_cli = Typer(
|
|
25
25
|
)
|
26
26
|
|
27
27
|
|
28
|
-
def _launch_program(name: str, filename: str, detach: bool, args:
|
28
|
+
def _launch_program(name: str, filename: str, detach: bool, args: dict[str, Any]) -> None:
|
29
29
|
os.environ["MODAL_LAUNCH_ARGS"] = json.dumps(args)
|
30
30
|
|
31
31
|
program_path = str(Path(__file__).parent / "programs" / filename)
|
modal/cli/network_file_system.py
CHANGED
@@ -29,7 +29,7 @@ nfs_cli = Typer(name="nfs", help="Read and edit `modal.NetworkFileSystem` file s
|
|
29
29
|
|
30
30
|
@nfs_cli.command(name="list", help="List the names of all network file systems.", rich_help_panel="Management")
|
31
31
|
@synchronizer.create_blocking
|
32
|
-
async def
|
32
|
+
async def list_(env: Optional[str] = ENV_OPTION, json: Optional[bool] = False):
|
33
33
|
env = ensure_env(env)
|
34
34
|
|
35
35
|
client = await _Client.from_env()
|