modal 1.0.6.dev58__py3-none-any.whl → 1.2.3.dev7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of modal might be problematic. Click here for more details.
- modal/__main__.py +3 -4
- modal/_billing.py +80 -0
- modal/_clustered_functions.py +7 -3
- modal/_clustered_functions.pyi +4 -2
- modal/_container_entrypoint.py +41 -49
- modal/_functions.py +424 -195
- modal/_grpc_client.py +171 -0
- modal/_load_context.py +105 -0
- modal/_object.py +68 -20
- modal/_output.py +58 -45
- modal/_partial_function.py +36 -11
- modal/_pty.py +7 -3
- modal/_resolver.py +21 -35
- modal/_runtime/asgi.py +4 -3
- modal/_runtime/container_io_manager.py +301 -186
- modal/_runtime/container_io_manager.pyi +70 -61
- modal/_runtime/execution_context.py +18 -2
- modal/_runtime/execution_context.pyi +4 -1
- modal/_runtime/gpu_memory_snapshot.py +170 -63
- modal/_runtime/user_code_imports.py +28 -58
- modal/_serialization.py +57 -1
- modal/_utils/async_utils.py +33 -12
- modal/_utils/auth_token_manager.py +2 -5
- modal/_utils/blob_utils.py +110 -53
- modal/_utils/function_utils.py +49 -42
- modal/_utils/grpc_utils.py +80 -50
- modal/_utils/mount_utils.py +26 -1
- modal/_utils/name_utils.py +17 -3
- modal/_utils/task_command_router_client.py +536 -0
- modal/_utils/time_utils.py +34 -6
- modal/app.py +219 -83
- modal/app.pyi +229 -56
- modal/billing.py +5 -0
- modal/{requirements → builder}/2025.06.txt +1 -0
- modal/{requirements → builder}/PREVIEW.txt +1 -0
- modal/cli/_download.py +19 -3
- modal/cli/_traceback.py +3 -2
- modal/cli/app.py +4 -4
- modal/cli/cluster.py +15 -7
- modal/cli/config.py +5 -3
- modal/cli/container.py +7 -6
- modal/cli/dict.py +22 -16
- modal/cli/entry_point.py +12 -5
- modal/cli/environment.py +5 -4
- modal/cli/import_refs.py +3 -3
- modal/cli/launch.py +102 -5
- modal/cli/network_file_system.py +9 -13
- modal/cli/profile.py +3 -2
- modal/cli/programs/launch_instance_ssh.py +94 -0
- modal/cli/programs/run_jupyter.py +1 -1
- modal/cli/programs/run_marimo.py +95 -0
- modal/cli/programs/vscode.py +1 -1
- modal/cli/queues.py +57 -26
- modal/cli/run.py +58 -16
- modal/cli/secret.py +48 -22
- modal/cli/utils.py +3 -4
- modal/cli/volume.py +28 -25
- modal/client.py +13 -116
- modal/client.pyi +9 -91
- modal/cloud_bucket_mount.py +5 -3
- modal/cloud_bucket_mount.pyi +5 -1
- modal/cls.py +130 -102
- modal/cls.pyi +45 -85
- modal/config.py +29 -10
- modal/container_process.py +291 -13
- modal/container_process.pyi +95 -32
- modal/dict.py +282 -63
- modal/dict.pyi +423 -73
- modal/environments.py +15 -27
- modal/environments.pyi +5 -15
- modal/exception.py +8 -0
- modal/experimental/__init__.py +143 -38
- modal/experimental/flash.py +247 -78
- modal/experimental/flash.pyi +137 -9
- modal/file_io.py +14 -28
- modal/file_io.pyi +2 -2
- modal/file_pattern_matcher.py +25 -16
- modal/functions.pyi +134 -61
- modal/image.py +255 -86
- modal/image.pyi +300 -62
- modal/io_streams.py +436 -126
- modal/io_streams.pyi +236 -171
- modal/mount.py +62 -157
- modal/mount.pyi +45 -172
- modal/network_file_system.py +30 -53
- modal/network_file_system.pyi +16 -76
- modal/object.pyi +42 -8
- modal/parallel_map.py +821 -113
- modal/parallel_map.pyi +134 -0
- modal/partial_function.pyi +4 -1
- modal/proxy.py +16 -7
- modal/proxy.pyi +10 -2
- modal/queue.py +263 -61
- modal/queue.pyi +409 -66
- modal/runner.py +112 -92
- modal/runner.pyi +45 -27
- modal/sandbox.py +451 -124
- modal/sandbox.pyi +513 -67
- modal/secret.py +291 -67
- modal/secret.pyi +425 -19
- modal/serving.py +7 -11
- modal/serving.pyi +7 -8
- modal/snapshot.py +11 -8
- modal/token_flow.py +4 -4
- modal/volume.py +344 -98
- modal/volume.pyi +464 -68
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/METADATA +9 -8
- modal-1.2.3.dev7.dist-info/RECORD +195 -0
- modal_docs/mdmd/mdmd.py +11 -1
- modal_proto/api.proto +399 -67
- modal_proto/api_grpc.py +241 -1
- modal_proto/api_pb2.py +1395 -1000
- modal_proto/api_pb2.pyi +1239 -79
- modal_proto/api_pb2_grpc.py +499 -4
- modal_proto/api_pb2_grpc.pyi +162 -14
- modal_proto/modal_api_grpc.py +175 -160
- modal_proto/sandbox_router.proto +145 -0
- modal_proto/sandbox_router_grpc.py +105 -0
- modal_proto/sandbox_router_pb2.py +149 -0
- modal_proto/sandbox_router_pb2.pyi +333 -0
- modal_proto/sandbox_router_pb2_grpc.py +203 -0
- modal_proto/sandbox_router_pb2_grpc.pyi +75 -0
- modal_proto/task_command_router.proto +144 -0
- modal_proto/task_command_router_grpc.py +105 -0
- modal_proto/task_command_router_pb2.py +149 -0
- modal_proto/task_command_router_pb2.pyi +333 -0
- modal_proto/task_command_router_pb2_grpc.py +203 -0
- modal_proto/task_command_router_pb2_grpc.pyi +75 -0
- modal_version/__init__.py +1 -1
- modal-1.0.6.dev58.dist-info/RECORD +0 -183
- modal_proto/modal_options_grpc.py +0 -3
- modal_proto/options.proto +0 -19
- modal_proto/options_grpc.py +0 -3
- modal_proto/options_pb2.py +0 -35
- modal_proto/options_pb2.pyi +0 -20
- modal_proto/options_pb2_grpc.py +0 -4
- modal_proto/options_pb2_grpc.pyi +0 -7
- /modal/{requirements → builder}/2023.12.312.txt +0 -0
- /modal/{requirements → builder}/2023.12.txt +0 -0
- /modal/{requirements → builder}/2024.04.txt +0 -0
- /modal/{requirements → builder}/2024.10.txt +0 -0
- /modal/{requirements → builder}/README.md +0 -0
- /modal/{requirements → builder}/base-images.json +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/WHEEL +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/entry_points.txt +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/licenses/LICENSE +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/top_level.txt +0 -0
modal/functions.pyi
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import collections.abc
|
|
2
2
|
import google.protobuf.message
|
|
3
3
|
import modal._functions
|
|
4
|
+
import modal._load_context
|
|
4
5
|
import modal._utils.async_utils
|
|
5
6
|
import modal._utils.function_utils
|
|
6
7
|
import modal.app
|
|
@@ -66,9 +67,10 @@ class Function(
|
|
|
66
67
|
@staticmethod
|
|
67
68
|
def from_local(
|
|
68
69
|
info: modal._utils.function_utils.FunctionInfo,
|
|
69
|
-
app,
|
|
70
|
+
app: typing.Optional[modal.app.App],
|
|
70
71
|
image: modal.image.Image,
|
|
71
|
-
|
|
72
|
+
env: typing.Optional[dict[str, typing.Optional[str]]] = None,
|
|
73
|
+
secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
|
|
72
74
|
schedule: typing.Optional[modal.schedule.Schedule] = None,
|
|
73
75
|
is_generator: bool = False,
|
|
74
76
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
|
|
@@ -84,7 +86,8 @@ class Function(
|
|
|
84
86
|
memory: typing.Union[int, tuple[int, int], None] = None,
|
|
85
87
|
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
|
86
88
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
|
87
|
-
timeout:
|
|
89
|
+
timeout: int = 300,
|
|
90
|
+
startup_timeout: typing.Optional[int] = None,
|
|
88
91
|
min_containers: typing.Optional[int] = None,
|
|
89
92
|
max_containers: typing.Optional[int] = None,
|
|
90
93
|
buffer_containers: typing.Optional[int] = None,
|
|
@@ -105,13 +108,16 @@ class Function(
|
|
|
105
108
|
rdma: typing.Optional[bool] = None,
|
|
106
109
|
max_inputs: typing.Optional[int] = None,
|
|
107
110
|
ephemeral_disk: typing.Optional[int] = None,
|
|
108
|
-
include_source:
|
|
111
|
+
include_source: bool = True,
|
|
109
112
|
experimental_options: typing.Optional[dict[str, str]] = None,
|
|
110
113
|
_experimental_proxy_ip: typing.Optional[str] = None,
|
|
111
114
|
_experimental_custom_scaling_factor: typing.Optional[float] = None,
|
|
112
|
-
|
|
115
|
+
restrict_output: bool = False,
|
|
113
116
|
) -> Function:
|
|
114
|
-
"""mdmd:hidden
|
|
117
|
+
"""mdmd:hidden
|
|
118
|
+
|
|
119
|
+
Note: This is not intended to be public API.
|
|
120
|
+
"""
|
|
115
121
|
...
|
|
116
122
|
|
|
117
123
|
def _bind_parameters(
|
|
@@ -240,10 +246,16 @@ class Function(
|
|
|
240
246
|
keep_warm: __keep_warm_spec[typing_extensions.Self]
|
|
241
247
|
|
|
242
248
|
@classmethod
|
|
243
|
-
def _from_name(cls, app_name: str, name: str,
|
|
249
|
+
def _from_name(cls, app_name: str, name: str, *, load_context_overrides: modal._load_context.LoadContext): ...
|
|
244
250
|
@classmethod
|
|
245
251
|
def from_name(
|
|
246
|
-
cls: type[Function],
|
|
252
|
+
cls: type[Function],
|
|
253
|
+
app_name: str,
|
|
254
|
+
name: str,
|
|
255
|
+
*,
|
|
256
|
+
namespace=None,
|
|
257
|
+
environment_name: typing.Optional[str] = None,
|
|
258
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
247
259
|
) -> Function:
|
|
248
260
|
"""Reference a Function from a deployed App by its name.
|
|
249
261
|
|
|
@@ -257,55 +269,6 @@ class Function(
|
|
|
257
269
|
"""
|
|
258
270
|
...
|
|
259
271
|
|
|
260
|
-
class __lookup_spec(typing_extensions.Protocol):
|
|
261
|
-
def __call__(
|
|
262
|
-
self,
|
|
263
|
-
/,
|
|
264
|
-
app_name: str,
|
|
265
|
-
name: str,
|
|
266
|
-
namespace=None,
|
|
267
|
-
client: typing.Optional[modal.client.Client] = None,
|
|
268
|
-
environment_name: typing.Optional[str] = None,
|
|
269
|
-
) -> Function:
|
|
270
|
-
"""mdmd:hidden
|
|
271
|
-
Lookup a Function from a deployed App by its name.
|
|
272
|
-
|
|
273
|
-
DEPRECATED: This method is deprecated in favor of `modal.Function.from_name`.
|
|
274
|
-
|
|
275
|
-
In contrast to `modal.Function.from_name`, this is an eager method
|
|
276
|
-
that will hydrate the local object with metadata from Modal servers.
|
|
277
|
-
|
|
278
|
-
```python notest
|
|
279
|
-
f = modal.Function.lookup("other-app", "function")
|
|
280
|
-
```
|
|
281
|
-
"""
|
|
282
|
-
...
|
|
283
|
-
|
|
284
|
-
async def aio(
|
|
285
|
-
self,
|
|
286
|
-
/,
|
|
287
|
-
app_name: str,
|
|
288
|
-
name: str,
|
|
289
|
-
namespace=None,
|
|
290
|
-
client: typing.Optional[modal.client.Client] = None,
|
|
291
|
-
environment_name: typing.Optional[str] = None,
|
|
292
|
-
) -> Function:
|
|
293
|
-
"""mdmd:hidden
|
|
294
|
-
Lookup a Function from a deployed App by its name.
|
|
295
|
-
|
|
296
|
-
DEPRECATED: This method is deprecated in favor of `modal.Function.from_name`.
|
|
297
|
-
|
|
298
|
-
In contrast to `modal.Function.from_name`, this is an eager method
|
|
299
|
-
that will hydrate the local object with metadata from Modal servers.
|
|
300
|
-
|
|
301
|
-
```python notest
|
|
302
|
-
f = modal.Function.lookup("other-app", "function")
|
|
303
|
-
```
|
|
304
|
-
"""
|
|
305
|
-
...
|
|
306
|
-
|
|
307
|
-
lookup: __lookup_spec
|
|
308
|
-
|
|
309
272
|
@property
|
|
310
273
|
def tag(self) -> str:
|
|
311
274
|
"""mdmd:hidden"""
|
|
@@ -360,6 +323,17 @@ class Function(
|
|
|
360
323
|
|
|
361
324
|
get_web_url: __get_web_url_spec[typing_extensions.Self]
|
|
362
325
|
|
|
326
|
+
class ___experimental_get_flash_urls_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
327
|
+
def __call__(self, /) -> typing.Optional[list[str]]:
|
|
328
|
+
"""URL of the flash service for the function."""
|
|
329
|
+
...
|
|
330
|
+
|
|
331
|
+
async def aio(self, /) -> typing.Optional[list[str]]:
|
|
332
|
+
"""URL of the flash service for the function."""
|
|
333
|
+
...
|
|
334
|
+
|
|
335
|
+
_experimental_get_flash_urls: ___experimental_get_flash_urls_spec[typing_extensions.Self]
|
|
336
|
+
|
|
363
337
|
@property
|
|
364
338
|
def is_generator(self) -> bool:
|
|
365
339
|
"""mdmd:hidden"""
|
|
@@ -406,6 +380,12 @@ class Function(
|
|
|
406
380
|
|
|
407
381
|
_map: ___map_spec[typing_extensions.Self]
|
|
408
382
|
|
|
383
|
+
class ___spawn_map_spec(typing_extensions.Protocol[ReturnType_INNER, SUPERSELF]):
|
|
384
|
+
def __call__(self, /, input_queue: modal.parallel_map.SynchronizedQueue) -> FunctionCall[ReturnType_INNER]: ...
|
|
385
|
+
async def aio(self, /, input_queue: modal.parallel_map.SynchronizedQueue) -> FunctionCall[ReturnType_INNER]: ...
|
|
386
|
+
|
|
387
|
+
_spawn_map: ___spawn_map_spec[modal._functions.ReturnType, typing_extensions.Self]
|
|
388
|
+
|
|
409
389
|
class ___call_function_spec(typing_extensions.Protocol[ReturnType_INNER, SUPERSELF]):
|
|
410
390
|
def __call__(self, /, args, kwargs) -> ReturnType_INNER: ...
|
|
411
391
|
async def aio(self, /, args, kwargs) -> ReturnType_INNER: ...
|
|
@@ -694,6 +674,34 @@ class Function(
|
|
|
694
674
|
|
|
695
675
|
spawn_map: __spawn_map_spec[typing_extensions.Self]
|
|
696
676
|
|
|
677
|
+
class __experimental_spawn_map_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
678
|
+
def __call__(self, /, *input_iterators, kwargs={}) -> modal._functions._FunctionCall:
|
|
679
|
+
"""mdmd:hidden
|
|
680
|
+
Spawn parallel execution over a set of inputs, returning as soon as the inputs are created.
|
|
681
|
+
|
|
682
|
+
Unlike `modal.Function.map`, this method does not block on completion of the remote execution but
|
|
683
|
+
returns a `modal.FunctionCall` object that can be used to poll status and retrieve results later.
|
|
684
|
+
|
|
685
|
+
Takes one iterator argument per argument in the function being mapped over.
|
|
686
|
+
|
|
687
|
+
Example:
|
|
688
|
+
```python
|
|
689
|
+
@app.function()
|
|
690
|
+
def my_func(a, b):
|
|
691
|
+
return a ** b
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
@app.local_entrypoint()
|
|
695
|
+
def main():
|
|
696
|
+
fc = my_func.spawn_map([1, 2], [3, 4])
|
|
697
|
+
```
|
|
698
|
+
"""
|
|
699
|
+
...
|
|
700
|
+
|
|
701
|
+
async def aio(self, /, *input_iterators, kwargs={}) -> modal._functions._FunctionCall: ...
|
|
702
|
+
|
|
703
|
+
experimental_spawn_map: __experimental_spawn_map_spec[typing_extensions.Self]
|
|
704
|
+
|
|
697
705
|
class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Object):
|
|
698
706
|
"""A reference to an executed function call.
|
|
699
707
|
|
|
@@ -706,6 +714,7 @@ class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Obj
|
|
|
706
714
|
"""
|
|
707
715
|
|
|
708
716
|
_is_generator: bool
|
|
717
|
+
_num_inputs: typing.Optional[int]
|
|
709
718
|
|
|
710
719
|
def __init__(self, *args, **kwargs):
|
|
711
720
|
"""mdmd:hidden"""
|
|
@@ -713,9 +722,22 @@ class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Obj
|
|
|
713
722
|
|
|
714
723
|
def _invocation(self): ...
|
|
715
724
|
|
|
725
|
+
class __num_inputs_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
726
|
+
def __call__(self, /) -> int:
|
|
727
|
+
"""Get the number of inputs in the function call."""
|
|
728
|
+
...
|
|
729
|
+
|
|
730
|
+
async def aio(self, /) -> int:
|
|
731
|
+
"""Get the number of inputs in the function call."""
|
|
732
|
+
...
|
|
733
|
+
|
|
734
|
+
num_inputs: __num_inputs_spec[typing_extensions.Self]
|
|
735
|
+
|
|
716
736
|
class __get_spec(typing_extensions.Protocol[ReturnType_INNER, SUPERSELF]):
|
|
717
|
-
def __call__(self, /, timeout: typing.Optional[float] = None) -> ReturnType_INNER:
|
|
718
|
-
"""Get the result of the function call.
|
|
737
|
+
def __call__(self, /, timeout: typing.Optional[float] = None, *, index: int = 0) -> ReturnType_INNER:
|
|
738
|
+
"""Get the result of the index-th input of the function call.
|
|
739
|
+
`.spawn()` calls have a single output, so only specifying `index=0` is valid.
|
|
740
|
+
A non-zero index is useful when your function has multiple outputs, like via `.spawn_map()`.
|
|
719
741
|
|
|
720
742
|
This function waits indefinitely by default. It takes an optional
|
|
721
743
|
`timeout` argument that specifies the maximum number of seconds to wait,
|
|
@@ -725,8 +747,10 @@ class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Obj
|
|
|
725
747
|
"""
|
|
726
748
|
...
|
|
727
749
|
|
|
728
|
-
async def aio(self, /, timeout: typing.Optional[float] = None) -> ReturnType_INNER:
|
|
729
|
-
"""Get the result of the function call.
|
|
750
|
+
async def aio(self, /, timeout: typing.Optional[float] = None, *, index: int = 0) -> ReturnType_INNER:
|
|
751
|
+
"""Get the result of the index-th input of the function call.
|
|
752
|
+
`.spawn()` calls have a single output, so only specifying `index=0` is valid.
|
|
753
|
+
A non-zero index is useful when your function has multiple outputs, like via `.spawn_map()`.
|
|
730
754
|
|
|
731
755
|
This function waits indefinitely by default. It takes an optional
|
|
732
756
|
`timeout` argument that specifies the maximum number of seconds to wait,
|
|
@@ -738,6 +762,55 @@ class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Obj
|
|
|
738
762
|
|
|
739
763
|
get: __get_spec[modal._functions.ReturnType, typing_extensions.Self]
|
|
740
764
|
|
|
765
|
+
class __iter_spec(typing_extensions.Protocol[ReturnType_INNER, SUPERSELF]):
|
|
766
|
+
def __call__(self, /, *, start: int = 0, end: typing.Optional[int] = None) -> typing.Iterator[ReturnType_INNER]:
|
|
767
|
+
"""Iterate in-order over the results of the function call.
|
|
768
|
+
|
|
769
|
+
Optionally, specify a range [start, end) to iterate over.
|
|
770
|
+
|
|
771
|
+
Example:
|
|
772
|
+
```python
|
|
773
|
+
@app.function()
|
|
774
|
+
def my_func(a):
|
|
775
|
+
return a ** 2
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
@app.local_entrypoint()
|
|
779
|
+
def main():
|
|
780
|
+
fc = my_func.spawn_map([1, 2, 3, 4])
|
|
781
|
+
assert list(fc.iter()) == [1, 4, 9, 16]
|
|
782
|
+
assert list(fc.iter(start=1, end=3)) == [4, 9]
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
If `end` is not provided, it will iterate over all results.
|
|
786
|
+
"""
|
|
787
|
+
...
|
|
788
|
+
|
|
789
|
+
def aio(self, /, *, start: int = 0, end: typing.Optional[int] = None) -> typing.AsyncIterator[ReturnType_INNER]:
|
|
790
|
+
"""Iterate in-order over the results of the function call.
|
|
791
|
+
|
|
792
|
+
Optionally, specify a range [start, end) to iterate over.
|
|
793
|
+
|
|
794
|
+
Example:
|
|
795
|
+
```python
|
|
796
|
+
@app.function()
|
|
797
|
+
def my_func(a):
|
|
798
|
+
return a ** 2
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
@app.local_entrypoint()
|
|
802
|
+
def main():
|
|
803
|
+
fc = my_func.spawn_map([1, 2, 3, 4])
|
|
804
|
+
assert list(fc.iter()) == [1, 4, 9, 16]
|
|
805
|
+
assert list(fc.iter(start=1, end=3)) == [4, 9]
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
If `end` is not provided, it will iterate over all results.
|
|
809
|
+
"""
|
|
810
|
+
...
|
|
811
|
+
|
|
812
|
+
iter: __iter_spec[modal._functions.ReturnType, typing_extensions.Self]
|
|
813
|
+
|
|
741
814
|
class __get_call_graph_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
742
815
|
def __call__(self, /) -> list[modal.call_graph.InputInfo]:
|
|
743
816
|
"""Returns a structure representing the call graph from a given root
|