modal 1.1.5.dev44__tar.gz → 1.1.5.dev45__tar.gz
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-1.1.5.dev44 → modal-1.1.5.dev45}/PKG-INFO +2 -1
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_container_entrypoint.py +19 -41
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_functions.py +21 -14
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/container_io_manager.py +252 -150
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/container_io_manager.pyi +32 -48
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/user_code_imports.py +15 -5
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_serialization.py +57 -1
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/blob_utils.py +4 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/function_utils.py +22 -8
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/app.py +4 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/app.pyi +4 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/client.pyi +2 -2
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/config.py +5 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/functions.pyi +1 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/image.py +10 -3
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/parallel_map.py +2 -4
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal.egg-info/PKG-INFO +2 -1
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal.egg-info/requires.txt +1 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_version/__init__.py +1 -1
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/pyproject.toml +2 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/LICENSE +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/README.md +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/__main__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_clustered_functions.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_clustered_functions.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_ipython.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_location.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_object.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_output.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_partial_function.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_pty.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_resolver.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_resources.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/asgi.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/execution_context.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_runtime/telemetry.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_traceback.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_tunnel.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_tunnel.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_type_manager.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/app_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/async_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/deprecation.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/docker_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/git_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/hash_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/http_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/logger.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/mount_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/name_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/package_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/shell_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_utils/time_utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_vendor/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_vendor/tblib.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/_watcher.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/builder/2023.12.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/builder/2024.04.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/builder/2024.10.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/builder/2025.06.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/builder/README.md +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/builder/base-images.json +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/call_graph.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/_download.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/_traceback.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/app.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/cluster.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/config.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/container.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/dict.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/entry_point.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/environment.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/import_refs.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/launch.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/network_file_system.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/profile.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/programs/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/programs/launch_instance_ssh.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/programs/run_marimo.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/programs/vscode.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/queues.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/run.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/secret.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/token.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/utils.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cli/volume.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/client.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cls.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/cls.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/container_process.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/container_process.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/dict.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/dict.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/environments.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/environments.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/exception.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/experimental/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/experimental/flash.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/experimental/flash.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/experimental/ipython.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/file_io.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/file_io.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/file_pattern_matcher.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/functions.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/gpu.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/image.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/io_streams.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/io_streams.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/mount.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/mount.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/network_file_system.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/network_file_system.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/object.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/object.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/output.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/parallel_map.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/partial_function.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/partial_function.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/proxy.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/proxy.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/py.typed +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/queue.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/queue.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/retries.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/runner.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/runner.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/running_app.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/sandbox.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/sandbox.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/schedule.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/scheduler_placement.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/secret.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/secret.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/serving.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/serving.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/snapshot.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/snapshot.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/stream_type.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/token_flow.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/token_flow.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/volume.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal/volume.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal.egg-info/top_level.txt +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_docs/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/__init__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/api.proto +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/api_grpc.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/api_pb2.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/modal_options_grpc.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/options.proto +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/options_grpc.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/options_pb2.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/options_pb2.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/options_pb2_grpc.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/options_pb2_grpc.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/py.typed +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/sandbox_router.proto +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/sandbox_router_grpc.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/sandbox_router_pb2.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/sandbox_router_pb2.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/sandbox_router_pb2_grpc.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_proto/sandbox_router_pb2_grpc.pyi +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/modal_version/__main__.py +0 -0
- {modal-1.1.5.dev44 → modal-1.1.5.dev45}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modal
|
|
3
|
-
Version: 1.1.5.
|
|
3
|
+
Version: 1.1.5.dev45
|
|
4
4
|
Summary: Python client library for Modal
|
|
5
5
|
Author-email: Modal Labs <support@modal.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -17,6 +17,7 @@ Requires-Python: >=3.9
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: aiohttp
|
|
20
|
+
Requires-Dist: cbor2
|
|
20
21
|
Requires-Dist: certifi
|
|
21
22
|
Requires-Dist: click~=8.1
|
|
22
23
|
Requires-Dist: grpclib<0.4.9,>=0.4.7
|
|
@@ -32,14 +32,14 @@ from modal._partial_function import (
|
|
|
32
32
|
_PartialFunctionFlags,
|
|
33
33
|
)
|
|
34
34
|
from modal._serialization import deserialize, deserialize_params
|
|
35
|
-
from modal._utils.async_utils import TaskContext, synchronizer
|
|
35
|
+
from modal._utils.async_utils import TaskContext, aclosing, synchronizer
|
|
36
36
|
from modal._utils.function_utils import (
|
|
37
37
|
callable_has_non_self_params,
|
|
38
38
|
)
|
|
39
39
|
from modal.app import App, _App
|
|
40
40
|
from modal.client import Client, _Client
|
|
41
41
|
from modal.config import logger
|
|
42
|
-
from modal.exception import ExecutionError, InputCancellation
|
|
42
|
+
from modal.exception import ExecutionError, InputCancellation
|
|
43
43
|
from modal.running_app import RunningApp, running_app_from_layout
|
|
44
44
|
from modal_proto import api_pb2
|
|
45
45
|
|
|
@@ -184,17 +184,13 @@ def call_function(
|
|
|
184
184
|
batch_wait_ms: int,
|
|
185
185
|
):
|
|
186
186
|
async def run_input_async(io_context: IOContext) -> None:
|
|
187
|
-
started_at = time.time()
|
|
188
187
|
reset_context = execution_context._set_current_context_ids(
|
|
189
188
|
io_context.input_ids, io_context.function_call_ids, io_context.attempt_tokens
|
|
190
189
|
)
|
|
190
|
+
started_at = time.time()
|
|
191
191
|
async with container_io_manager.handle_input_exception.aio(io_context, started_at):
|
|
192
|
-
res = io_context.call_finalized_function()
|
|
193
192
|
# TODO(erikbern): any exception below shouldn't be considered a user exception
|
|
194
193
|
if io_context.finalized_function.is_generator:
|
|
195
|
-
if not inspect.isasyncgen(res):
|
|
196
|
-
raise InvalidError(f"Async generator function returned value of type {type(res)}")
|
|
197
|
-
|
|
198
194
|
# Send up to this many outputs at a time.
|
|
199
195
|
current_function_call_id = execution_context.current_function_call_id()
|
|
200
196
|
assert current_function_call_id is not None # Set above.
|
|
@@ -204,33 +200,24 @@ def call_function(
|
|
|
204
200
|
async with container_io_manager.generator_output_sender(
|
|
205
201
|
current_function_call_id,
|
|
206
202
|
current_attempt_token,
|
|
207
|
-
io_context.
|
|
203
|
+
io_context._generator_output_format(),
|
|
208
204
|
generator_queue,
|
|
209
205
|
):
|
|
210
206
|
item_count = 0
|
|
211
|
-
async
|
|
212
|
-
|
|
213
|
-
|
|
207
|
+
async with aclosing(io_context.call_generator_async()) as gen:
|
|
208
|
+
async for value in gen:
|
|
209
|
+
await container_io_manager._queue_put.aio(generator_queue, value)
|
|
210
|
+
item_count += 1
|
|
214
211
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
io_context,
|
|
218
|
-
started_at,
|
|
219
|
-
message,
|
|
220
|
-
api_pb2.DATA_FORMAT_GENERATOR_DONE,
|
|
212
|
+
await container_io_manager._send_outputs.aio(
|
|
213
|
+
started_at, io_context.output_items_generator_done(started_at, item_count)
|
|
221
214
|
)
|
|
222
215
|
else:
|
|
223
|
-
|
|
224
|
-
raise InvalidError(
|
|
225
|
-
f"Async (non-generator) function returned value of type {type(res)}"
|
|
226
|
-
" You might need to use @app.function(..., is_generator=True)."
|
|
227
|
-
)
|
|
228
|
-
value = await res
|
|
216
|
+
value = await io_context.call_function_async()
|
|
229
217
|
await container_io_manager.push_outputs.aio(
|
|
230
218
|
io_context,
|
|
231
219
|
started_at,
|
|
232
220
|
value,
|
|
233
|
-
io_context.finalized_function.data_format,
|
|
234
221
|
)
|
|
235
222
|
reset_context()
|
|
236
223
|
|
|
@@ -240,13 +227,9 @@ def call_function(
|
|
|
240
227
|
io_context.input_ids, io_context.function_call_ids, io_context.attempt_tokens
|
|
241
228
|
)
|
|
242
229
|
with container_io_manager.handle_input_exception(io_context, started_at):
|
|
243
|
-
res = io_context.call_finalized_function()
|
|
244
|
-
|
|
245
230
|
# TODO(erikbern): any exception below shouldn't be considered a user exception
|
|
246
231
|
if io_context.finalized_function.is_generator:
|
|
247
|
-
|
|
248
|
-
raise InvalidError(f"Generator function returned value of type {type(res)}")
|
|
249
|
-
|
|
232
|
+
gen = io_context.call_generator_sync()
|
|
250
233
|
# Send up to this many outputs at a time.
|
|
251
234
|
current_function_call_id = execution_context.current_function_call_id()
|
|
252
235
|
assert current_function_call_id is not None # Set above.
|
|
@@ -256,25 +239,20 @@ def call_function(
|
|
|
256
239
|
with container_io_manager.generator_output_sender(
|
|
257
240
|
current_function_call_id,
|
|
258
241
|
current_attempt_token,
|
|
259
|
-
io_context.
|
|
242
|
+
io_context._generator_output_format(),
|
|
260
243
|
generator_queue,
|
|
261
244
|
):
|
|
262
245
|
item_count = 0
|
|
263
|
-
for value in
|
|
246
|
+
for value in gen:
|
|
264
247
|
container_io_manager._queue_put(generator_queue, value)
|
|
265
248
|
item_count += 1
|
|
266
249
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
else:
|
|
270
|
-
if inspect.iscoroutine(res) or inspect.isgenerator(res) or inspect.isasyncgen(res):
|
|
271
|
-
raise InvalidError(
|
|
272
|
-
f"Sync (non-generator) function return value of type {type(res)}."
|
|
273
|
-
" You might need to use @app.function(..., is_generator=True)."
|
|
274
|
-
)
|
|
275
|
-
container_io_manager.push_outputs(
|
|
276
|
-
io_context, started_at, res, io_context.finalized_function.data_format
|
|
250
|
+
container_io_manager._send_outputs(
|
|
251
|
+
started_at, io_context.output_items_generator_done(started_at, item_count)
|
|
277
252
|
)
|
|
253
|
+
else:
|
|
254
|
+
values = io_context.call_function_sync()
|
|
255
|
+
container_io_manager.push_outputs(io_context, started_at, values)
|
|
278
256
|
reset_context()
|
|
279
257
|
|
|
280
258
|
if container_io_manager.input_concurrency_enabled:
|
|
@@ -150,8 +150,7 @@ class _Invocation:
|
|
|
150
150
|
args,
|
|
151
151
|
kwargs,
|
|
152
152
|
stub,
|
|
153
|
-
|
|
154
|
-
method_name=function._use_method_name,
|
|
153
|
+
function=function,
|
|
155
154
|
function_call_invocation_type=function_call_invocation_type,
|
|
156
155
|
)
|
|
157
156
|
|
|
@@ -439,8 +438,7 @@ class _InputPlaneInvocation:
|
|
|
439
438
|
args,
|
|
440
439
|
kwargs,
|
|
441
440
|
control_plane_stub,
|
|
442
|
-
|
|
443
|
-
method_name=function._use_method_name,
|
|
441
|
+
function=function,
|
|
444
442
|
)
|
|
445
443
|
|
|
446
444
|
request = api_pb2.AttemptStartRequest(
|
|
@@ -698,6 +696,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
698
696
|
experimental_options: Optional[dict[str, str]] = None,
|
|
699
697
|
_experimental_proxy_ip: Optional[str] = None,
|
|
700
698
|
_experimental_custom_scaling_factor: Optional[float] = None,
|
|
699
|
+
restrict_output: bool = False,
|
|
701
700
|
) -> "_Function":
|
|
702
701
|
"""mdmd:hidden
|
|
703
702
|
|
|
@@ -834,17 +833,23 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
834
833
|
is_web_endpoint=is_web_endpoint,
|
|
835
834
|
ignore_first_argument=True,
|
|
836
835
|
)
|
|
836
|
+
if is_web_endpoint:
|
|
837
|
+
method_input_formats = [api_pb2.DATA_FORMAT_ASGI]
|
|
838
|
+
method_output_formats = [api_pb2.DATA_FORMAT_ASGI]
|
|
839
|
+
else:
|
|
840
|
+
method_input_formats = [api_pb2.DATA_FORMAT_PICKLE, api_pb2.DATA_FORMAT_CBOR]
|
|
841
|
+
if restrict_output:
|
|
842
|
+
method_output_formats = [api_pb2.DATA_FORMAT_CBOR]
|
|
843
|
+
else:
|
|
844
|
+
method_output_formats = [api_pb2.DATA_FORMAT_PICKLE, api_pb2.DATA_FORMAT_CBOR]
|
|
845
|
+
|
|
837
846
|
method_definition = api_pb2.MethodDefinition(
|
|
838
847
|
webhook_config=partial_function.params.webhook_config,
|
|
839
848
|
function_type=function_type,
|
|
840
849
|
function_name=function_name,
|
|
841
850
|
function_schema=method_schema,
|
|
842
|
-
supported_input_formats=
|
|
843
|
-
|
|
844
|
-
else [api_pb2.DATA_FORMAT_PICKLE],
|
|
845
|
-
supported_output_formats=[api_pb2.DATA_FORMAT_ASGI]
|
|
846
|
-
if is_web_endpoint
|
|
847
|
-
else [api_pb2.DATA_FORMAT_PICKLE],
|
|
851
|
+
supported_input_formats=method_input_formats,
|
|
852
|
+
supported_output_formats=method_output_formats,
|
|
848
853
|
)
|
|
849
854
|
method_definitions[method_name] = method_definition
|
|
850
855
|
|
|
@@ -869,16 +874,18 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
869
874
|
return deps
|
|
870
875
|
|
|
871
876
|
if info.is_service_class():
|
|
872
|
-
# classes don't have data formats themselves -
|
|
877
|
+
# classes don't have data formats themselves - input/output formats are set per method above
|
|
873
878
|
supported_input_formats = []
|
|
874
879
|
supported_output_formats = []
|
|
875
880
|
elif webhook_config is not None:
|
|
876
881
|
supported_input_formats = [api_pb2.DATA_FORMAT_ASGI]
|
|
877
882
|
supported_output_formats = [api_pb2.DATA_FORMAT_ASGI]
|
|
878
883
|
else:
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
884
|
+
supported_input_formats = [api_pb2.DATA_FORMAT_PICKLE, api_pb2.DATA_FORMAT_CBOR]
|
|
885
|
+
if restrict_output:
|
|
886
|
+
supported_output_formats = [api_pb2.DATA_FORMAT_CBOR]
|
|
887
|
+
else:
|
|
888
|
+
supported_output_formats = [api_pb2.DATA_FORMAT_PICKLE, api_pb2.DATA_FORMAT_CBOR]
|
|
882
889
|
|
|
883
890
|
async def _preload(self: _Function, resolver: Resolver, existing_object_id: Optional[str]):
|
|
884
891
|
assert resolver.client and resolver.client.stub
|