modAL 1.2.7.dev6__tar.gz → 1.2.7.dev7__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.
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/PKG-INFO +1 -1
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_functions.py +3 -10
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/container_io_manager.py +3 -2
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/app.py +34 -8
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/app.pyi +8 -4
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/client.pyi +2 -2
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/functions.pyi +1 -1
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/api.proto +5 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/api_pb2.py +656 -656
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/api_pb2.pyi +8 -1
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_version/__init__.py +1 -1
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/LICENSE +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/README.md +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/__main__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_billing.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_clustered_functions.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_clustered_functions.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_container_entrypoint.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_grpc_client.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_ipython.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_load_context.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_location.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_object.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_output.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_partial_function.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_pty.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_resolver.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_resources.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/asgi.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/execution_context.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/telemetry.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_serialization.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_traceback.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_tunnel.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_tunnel.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_type_manager.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/app_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/async_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/blob_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/deprecation.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/docker_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/function_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/git_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/hash_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/http_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/logger.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/mount_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/name_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/package_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/shell_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_utils/time_utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_vendor/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_vendor/tblib.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/_watcher.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/billing.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/builder/2023.12.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/builder/2024.04.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/builder/2024.10.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/builder/2025.06.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/builder/README.md +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/builder/base-images.json +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/call_graph.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/_download.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/_traceback.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/app.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/cluster.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/config.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/container.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/dict.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/entry_point.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/environment.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/import_refs.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/launch.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/network_file_system.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/profile.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/programs/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/programs/vscode.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/queues.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/run.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/secret.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/shell.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/token.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/utils.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cli/volume.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/client.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cls.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/cls.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/config.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/container_process.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/container_process.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/dict.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/dict.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/environments.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/environments.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/exception.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/experimental/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/experimental/flash.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/experimental/flash.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/experimental/ipython.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/file_io.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/file_io.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/file_pattern_matcher.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/functions.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/gpu.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/image.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/image.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/io_streams.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/io_streams.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/mount.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/mount.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/network_file_system.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/network_file_system.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/object.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/object.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/output.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/parallel_map.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/parallel_map.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/partial_function.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/partial_function.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/proxy.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/proxy.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/py.typed +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/queue.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/queue.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/retries.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/runner.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/runner.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/running_app.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/sandbox.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/sandbox.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/schedule.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/scheduler_placement.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/secret.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/secret.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/serving.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/serving.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/snapshot.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/snapshot.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/stream_type.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/token_flow.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/token_flow.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/volume.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal/volume.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal.egg-info/requires.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal.egg-info/top_level.txt +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_docs/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/__init__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/api_grpc.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/py.typed +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/task_command_router.proto +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/modal_version/__main__.py +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/pyproject.toml +0 -0
- {modal-1.2.7.dev6 → modal-1.2.7.dev7}/setup.cfg +0 -0
|
@@ -694,7 +694,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
694
694
|
# Experimental: Clustered functions
|
|
695
695
|
cluster_size: Optional[int] = None,
|
|
696
696
|
rdma: Optional[bool] = None,
|
|
697
|
-
|
|
697
|
+
single_use_containers: bool = False,
|
|
698
698
|
ephemeral_disk: Optional[int] = None,
|
|
699
699
|
include_source: bool = True,
|
|
700
700
|
experimental_options: Optional[dict[str, str]] = None,
|
|
@@ -810,14 +810,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
810
810
|
if arg.default is not inspect.Parameter.empty:
|
|
811
811
|
raise InvalidError(f"Modal batched function {func_name} does not accept default arguments.")
|
|
812
812
|
|
|
813
|
-
if max_inputs is not None:
|
|
814
|
-
if not isinstance(max_inputs, int):
|
|
815
|
-
raise InvalidError(f"`max_inputs` must be an int, not {type(max_inputs).__name__}")
|
|
816
|
-
if max_inputs <= 0:
|
|
817
|
-
raise InvalidError("`max_inputs` must be positive")
|
|
818
|
-
if max_inputs > 1:
|
|
819
|
-
raise InvalidError("Only `max_inputs=1` is currently supported")
|
|
820
|
-
|
|
821
813
|
# Validate volumes
|
|
822
814
|
validated_volumes = validate_volumes(volumes)
|
|
823
815
|
cloud_bucket_mounts = [(k, v) for k, v in validated_volumes if isinstance(v, _CloudBucketMount)]
|
|
@@ -1024,7 +1016,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1024
1016
|
object_dependencies=object_dependencies,
|
|
1025
1017
|
block_network=block_network,
|
|
1026
1018
|
untrusted=restrict_modal_access,
|
|
1027
|
-
|
|
1019
|
+
single_use_containers=single_use_containers,
|
|
1020
|
+
max_inputs=int(single_use_containers), # TODO(michael) remove after worker rollover
|
|
1028
1021
|
cloud_bucket_mounts=cloud_bucket_mounts_to_proto(cloud_bucket_mounts),
|
|
1029
1022
|
scheduler_placement=scheduler_placement,
|
|
1030
1023
|
is_class=info.is_service_class(),
|
|
@@ -845,8 +845,9 @@ class _ContainerIOManager:
|
|
|
845
845
|
yield inputs
|
|
846
846
|
yielded = True
|
|
847
847
|
|
|
848
|
-
#
|
|
849
|
-
|
|
848
|
+
# TODO(michael): Remove use of max_inputs after worker rollover
|
|
849
|
+
single_use_container = self.function_def.single_use_containers or self.function_def.max_inputs == 1
|
|
850
|
+
if final_input_received or single_use_container:
|
|
850
851
|
return
|
|
851
852
|
finally:
|
|
852
853
|
if not yielded:
|
|
@@ -725,9 +725,7 @@ class _App:
|
|
|
725
725
|
enable_memory_snapshot: bool = False, # Enable memory checkpointing for faster cold starts.
|
|
726
726
|
block_network: bool = False, # Whether to block network access
|
|
727
727
|
restrict_modal_access: bool = False, # Whether to allow this function access to other Modal resources
|
|
728
|
-
#
|
|
729
|
-
# With `max_inputs = 1`, containers will be single-use.
|
|
730
|
-
max_inputs: Optional[int] = None,
|
|
728
|
+
single_use_containers: bool = False, # When True, containers will shut down after handling a single input
|
|
731
729
|
i6pn: Optional[bool] = None, # Whether to enable IPv6 container networking within the region.
|
|
732
730
|
# Whether the file or directory containing the Function's source should automatically be included
|
|
733
731
|
# in the container. When unset, falls back to the App-level configuration, or is otherwise True by default.
|
|
@@ -742,6 +740,7 @@ class _App:
|
|
|
742
740
|
concurrency_limit: Optional[int] = None, # Replaced with `max_containers`
|
|
743
741
|
container_idle_timeout: Optional[int] = None, # Replaced with `scaledown_window`
|
|
744
742
|
allow_concurrent_inputs: Optional[int] = None, # Replaced with the `@modal.concurrent` decorator
|
|
743
|
+
max_inputs: Optional[int] = None, # Replaced with `single_use_containers`
|
|
745
744
|
_experimental_buffer_containers: Optional[int] = None, # Now stable API with `buffer_containers`
|
|
746
745
|
_experimental_scheduler_placement: Optional[SchedulerPlacement] = None, # Replaced in favor of
|
|
747
746
|
# using `region` and `nonpreemptible`
|
|
@@ -764,6 +763,20 @@ class _App:
|
|
|
764
763
|
"\n\nSee https://modal.com/docs/guide/modal-1-0-migration for more information.",
|
|
765
764
|
)
|
|
766
765
|
|
|
766
|
+
if max_inputs is not None:
|
|
767
|
+
if not isinstance(max_inputs, int):
|
|
768
|
+
raise InvalidError(f"`max_inputs` must be an int, not {type(max_inputs).__name__}")
|
|
769
|
+
if max_inputs <= 0:
|
|
770
|
+
raise InvalidError("`max_inputs` must be positive")
|
|
771
|
+
if max_inputs > 1:
|
|
772
|
+
raise InvalidError("Only `max_inputs=1` is currently supported")
|
|
773
|
+
deprecation_warning(
|
|
774
|
+
(2025, 12, 16),
|
|
775
|
+
"The `max_inputs` parameter is deprecated. Please set `single_use_containers=True` instead.",
|
|
776
|
+
pending=True,
|
|
777
|
+
)
|
|
778
|
+
single_use_containers = max_inputs == 1
|
|
779
|
+
|
|
767
780
|
if _experimental_scheduler_placement is not None:
|
|
768
781
|
deprecation_warning(
|
|
769
782
|
(2025, 11, 17),
|
|
@@ -912,7 +925,7 @@ class _App:
|
|
|
912
925
|
enable_memory_snapshot=enable_memory_snapshot,
|
|
913
926
|
block_network=block_network,
|
|
914
927
|
restrict_modal_access=restrict_modal_access,
|
|
915
|
-
|
|
928
|
+
single_use_containers=single_use_containers,
|
|
916
929
|
i6pn_enabled=i6pn_enabled,
|
|
917
930
|
cluster_size=cluster_size, # Experimental: Clustered functions
|
|
918
931
|
rdma=rdma,
|
|
@@ -969,9 +982,7 @@ class _App:
|
|
|
969
982
|
enable_memory_snapshot: bool = False, # Enable memory checkpointing for faster cold starts.
|
|
970
983
|
block_network: bool = False, # Whether to block network access
|
|
971
984
|
restrict_modal_access: bool = False, # Whether to allow this class access to other Modal resources
|
|
972
|
-
#
|
|
973
|
-
# Use `max_inputs = 1` for single-use containers.
|
|
974
|
-
max_inputs: Optional[int] = None,
|
|
985
|
+
single_use_containers: bool = False, # When True, containers will shut down after handling a single input
|
|
975
986
|
i6pn: Optional[bool] = None, # Whether to enable IPv6 container networking within the region.
|
|
976
987
|
include_source: Optional[bool] = None, # When `False`, don't automatically add the App source to the container.
|
|
977
988
|
experimental_options: Optional[dict[str, Any]] = None,
|
|
@@ -984,6 +995,7 @@ class _App:
|
|
|
984
995
|
concurrency_limit: Optional[int] = None, # Replaced with `max_containers`
|
|
985
996
|
container_idle_timeout: Optional[int] = None, # Replaced with `scaledown_window`
|
|
986
997
|
allow_concurrent_inputs: Optional[int] = None, # Replaced with the `@modal.concurrent` decorator
|
|
998
|
+
max_inputs: Optional[int] = None, # Replaced with `single_use_containers`
|
|
987
999
|
_experimental_buffer_containers: Optional[int] = None, # Now stable API with `buffer_containers`
|
|
988
1000
|
_experimental_scheduler_placement: Optional[SchedulerPlacement] = None, # Replaced in favor of
|
|
989
1001
|
# using `region` and `nonpreemptible`
|
|
@@ -1002,6 +1014,20 @@ class _App:
|
|
|
1002
1014
|
"\n\nSee https://modal.com/docs/guide/modal-1-0-migration for more information.",
|
|
1003
1015
|
)
|
|
1004
1016
|
|
|
1017
|
+
if max_inputs is not None:
|
|
1018
|
+
if not isinstance(max_inputs, int):
|
|
1019
|
+
raise InvalidError(f"`max_inputs` must be an int, not {type(max_inputs).__name__}")
|
|
1020
|
+
if max_inputs <= 0:
|
|
1021
|
+
raise InvalidError("`max_inputs` must be positive")
|
|
1022
|
+
if max_inputs > 1:
|
|
1023
|
+
raise InvalidError("Only `max_inputs=1` is currently supported")
|
|
1024
|
+
deprecation_warning(
|
|
1025
|
+
(2025, 12, 16),
|
|
1026
|
+
"The `max_inputs` parameter is deprecated. Please set `single_use_containers=True` instead.",
|
|
1027
|
+
pending=True,
|
|
1028
|
+
)
|
|
1029
|
+
single_use_containers = max_inputs == 1
|
|
1030
|
+
|
|
1005
1031
|
if _experimental_scheduler_placement is not None:
|
|
1006
1032
|
deprecation_warning(
|
|
1007
1033
|
(2025, 11, 17),
|
|
@@ -1139,7 +1165,7 @@ class _App:
|
|
|
1139
1165
|
enable_memory_snapshot=enable_memory_snapshot,
|
|
1140
1166
|
block_network=block_network,
|
|
1141
1167
|
restrict_modal_access=restrict_modal_access,
|
|
1142
|
-
|
|
1168
|
+
single_use_containers=single_use_containers,
|
|
1143
1169
|
http_config=http_config,
|
|
1144
1170
|
i6pn_enabled=i6pn_enabled,
|
|
1145
1171
|
cluster_size=cluster_size,
|
|
@@ -491,7 +491,7 @@ class _App:
|
|
|
491
491
|
enable_memory_snapshot: bool = False,
|
|
492
492
|
block_network: bool = False,
|
|
493
493
|
restrict_modal_access: bool = False,
|
|
494
|
-
|
|
494
|
+
single_use_containers: bool = False,
|
|
495
495
|
i6pn: typing.Optional[bool] = None,
|
|
496
496
|
include_source: typing.Optional[bool] = None,
|
|
497
497
|
experimental_options: typing.Optional[dict[str, typing.Any]] = None,
|
|
@@ -502,6 +502,7 @@ class _App:
|
|
|
502
502
|
concurrency_limit: typing.Optional[int] = None,
|
|
503
503
|
container_idle_timeout: typing.Optional[int] = None,
|
|
504
504
|
allow_concurrent_inputs: typing.Optional[int] = None,
|
|
505
|
+
max_inputs: typing.Optional[int] = None,
|
|
505
506
|
_experimental_buffer_containers: typing.Optional[int] = None,
|
|
506
507
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
|
507
508
|
) -> _FunctionDecoratorType:
|
|
@@ -545,7 +546,7 @@ class _App:
|
|
|
545
546
|
enable_memory_snapshot: bool = False,
|
|
546
547
|
block_network: bool = False,
|
|
547
548
|
restrict_modal_access: bool = False,
|
|
548
|
-
|
|
549
|
+
single_use_containers: bool = False,
|
|
549
550
|
i6pn: typing.Optional[bool] = None,
|
|
550
551
|
include_source: typing.Optional[bool] = None,
|
|
551
552
|
experimental_options: typing.Optional[dict[str, typing.Any]] = None,
|
|
@@ -556,6 +557,7 @@ class _App:
|
|
|
556
557
|
concurrency_limit: typing.Optional[int] = None,
|
|
557
558
|
container_idle_timeout: typing.Optional[int] = None,
|
|
558
559
|
allow_concurrent_inputs: typing.Optional[int] = None,
|
|
560
|
+
max_inputs: typing.Optional[int] = None,
|
|
559
561
|
_experimental_buffer_containers: typing.Optional[int] = None,
|
|
560
562
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
|
561
563
|
) -> collections.abc.Callable[[typing.Union[CLS_T, modal._partial_function._PartialFunction]], CLS_T]:
|
|
@@ -1154,7 +1156,7 @@ class App:
|
|
|
1154
1156
|
enable_memory_snapshot: bool = False,
|
|
1155
1157
|
block_network: bool = False,
|
|
1156
1158
|
restrict_modal_access: bool = False,
|
|
1157
|
-
|
|
1159
|
+
single_use_containers: bool = False,
|
|
1158
1160
|
i6pn: typing.Optional[bool] = None,
|
|
1159
1161
|
include_source: typing.Optional[bool] = None,
|
|
1160
1162
|
experimental_options: typing.Optional[dict[str, typing.Any]] = None,
|
|
@@ -1165,6 +1167,7 @@ class App:
|
|
|
1165
1167
|
concurrency_limit: typing.Optional[int] = None,
|
|
1166
1168
|
container_idle_timeout: typing.Optional[int] = None,
|
|
1167
1169
|
allow_concurrent_inputs: typing.Optional[int] = None,
|
|
1170
|
+
max_inputs: typing.Optional[int] = None,
|
|
1168
1171
|
_experimental_buffer_containers: typing.Optional[int] = None,
|
|
1169
1172
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
|
1170
1173
|
) -> _FunctionDecoratorType:
|
|
@@ -1208,7 +1211,7 @@ class App:
|
|
|
1208
1211
|
enable_memory_snapshot: bool = False,
|
|
1209
1212
|
block_network: bool = False,
|
|
1210
1213
|
restrict_modal_access: bool = False,
|
|
1211
|
-
|
|
1214
|
+
single_use_containers: bool = False,
|
|
1212
1215
|
i6pn: typing.Optional[bool] = None,
|
|
1213
1216
|
include_source: typing.Optional[bool] = None,
|
|
1214
1217
|
experimental_options: typing.Optional[dict[str, typing.Any]] = None,
|
|
@@ -1219,6 +1222,7 @@ class App:
|
|
|
1219
1222
|
concurrency_limit: typing.Optional[int] = None,
|
|
1220
1223
|
container_idle_timeout: typing.Optional[int] = None,
|
|
1221
1224
|
allow_concurrent_inputs: typing.Optional[int] = None,
|
|
1225
|
+
max_inputs: typing.Optional[int] = None,
|
|
1222
1226
|
_experimental_buffer_containers: typing.Optional[int] = None,
|
|
1223
1227
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
|
1224
1228
|
) -> collections.abc.Callable[[typing.Union[CLS_T, modal.partial_function.PartialFunction]], CLS_T]:
|
|
@@ -32,7 +32,7 @@ class _Client:
|
|
|
32
32
|
server_url: str,
|
|
33
33
|
client_type: int,
|
|
34
34
|
credentials: typing.Optional[tuple[str, str]],
|
|
35
|
-
version: str = "1.2.7.
|
|
35
|
+
version: str = "1.2.7.dev7",
|
|
36
36
|
):
|
|
37
37
|
"""mdmd:hidden
|
|
38
38
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -163,7 +163,7 @@ class Client:
|
|
|
163
163
|
server_url: str,
|
|
164
164
|
client_type: int,
|
|
165
165
|
credentials: typing.Optional[tuple[str, str]],
|
|
166
|
-
version: str = "1.2.7.
|
|
166
|
+
version: str = "1.2.7.dev7",
|
|
167
167
|
):
|
|
168
168
|
"""mdmd:hidden
|
|
169
169
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -106,7 +106,7 @@ class Function(
|
|
|
106
106
|
i6pn_enabled: bool = False,
|
|
107
107
|
cluster_size: typing.Optional[int] = None,
|
|
108
108
|
rdma: typing.Optional[bool] = None,
|
|
109
|
-
|
|
109
|
+
single_use_containers: bool = False,
|
|
110
110
|
ephemeral_disk: typing.Optional[int] = None,
|
|
111
111
|
include_source: bool = True,
|
|
112
112
|
experimental_options: typing.Optional[dict[str, str]] = None,
|
|
@@ -1469,6 +1469,8 @@ message Function {
|
|
|
1469
1469
|
|
|
1470
1470
|
bool block_network = 44;
|
|
1471
1471
|
|
|
1472
|
+
// In the SDK, we've deprecated `max_inputs` (which only every implemented `max_inputs=1`)
|
|
1473
|
+
// in favor of a boolean `single_use_containers` parameter.
|
|
1472
1474
|
uint32 max_inputs = 46;
|
|
1473
1475
|
|
|
1474
1476
|
repeated S3Mount s3_mounts = 47;
|
|
@@ -1556,6 +1558,9 @@ message Function {
|
|
|
1556
1558
|
// Attribute on the module with the implementation, which may differ from function_name
|
|
1557
1559
|
// when the user provided a custom name= for the Function inside the Application namespace
|
|
1558
1560
|
string implementation_name = 90;
|
|
1561
|
+
|
|
1562
|
+
bool single_use_containers = 91; // When True, containers will shut down after handling a single input
|
|
1563
|
+
|
|
1559
1564
|
}
|
|
1560
1565
|
|
|
1561
1566
|
message FunctionAsyncInvokeRequest {
|