modal 1.5.3.dev1__tar.gz → 1.5.3.dev3__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.5.3.dev1 → modal-1.5.3.dev3}/PKG-INFO +1 -1
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_functions.py +29 -3
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_partial_function.py +14 -2
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/grpc_utils.py +1 -1
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/app.py +10 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/client.pyi +2 -2
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cls.py +3 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/config.py +2 -1
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/functions.pyi +23 -6
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/sandbox.py +7 -3
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/sandbox.pyi +20 -8
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/api_grpc.py +16 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/api_pb2.py +956 -916
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/api_pb2.pyi +88 -6
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/api_pb2_grpc.py +33 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/api_pb2_grpc.pyi +10 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/modal_api_grpc.py +1 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_version/__init__.py +1 -1
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/LICENSE +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/README.md +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/__main__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_billing.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_clustered_functions.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_environments.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_function_variants.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_grpc_client.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_image.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_ipython.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_load_context.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_location.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_logs.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_object.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_output/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_output/manager.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_output/pty.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_output/rich.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_output/status.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_resolver.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_resources.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_serialization.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_server.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_traceback.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_tunnel.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_tunnel.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_type_manager.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/logger.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_vendor/version.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_watcher.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/_workspace.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/app.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/billing.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/billing.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/builder/README.md +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/builder/base-images.json +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/call_graph.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/_download.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/_help.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/_traceback.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/app.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/billing.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/changelog.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/cluster.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/config.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/container.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/curl.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/dashboard.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/dict.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/endpoint.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/entry_point.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/environment.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/image.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/import_refs.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/launch.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/logo.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/profile.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/queues.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/run.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/secret.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/selector.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/shell.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/skills.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/token.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/utils.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/volume.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cli/workspace.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/client.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/cls.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/container_process.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/container_process.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/dict.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/dict.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/environments.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/environments.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/exception.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/experimental/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/experimental/flash.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/experimental/ipython.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/file_io.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/file_io.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/functions.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/image.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/image.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/io_streams.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/io_streams.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/mount.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/mount.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/network_file_system.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/network_file_system.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/object.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/object.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/output.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/parallel_map.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/parallel_map.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/partial_function.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/partial_function.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/proxy.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/proxy.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/py.typed +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/queue.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/queue.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/retries.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/runner.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/runner.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/running_app.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/sandbox_fs.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/schedule.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/scheduler_placement.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/secret.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/secret.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/server.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/server.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/serving.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/serving.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/snapshot.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/snapshot.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/stream_type.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/token_flow.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/token_flow.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/types.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/volume.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/volume.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/workspace.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal/workspace.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/__init__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/py.typed +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/modal_version/__main__.py +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/pyproject.toml +0 -0
- {modal-1.5.3.dev1 → modal-1.5.3.dev3}/setup.cfg +0 -0
|
@@ -627,6 +627,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
627
627
|
_metadata: api_pb2.FunctionHandleMetadata | None = None
|
|
628
628
|
_options: _FunctionOptions
|
|
629
629
|
_base_function: "_Function | None" = None
|
|
630
|
+
_app_id: str | None = None
|
|
630
631
|
|
|
631
632
|
@staticmethod
|
|
632
633
|
def from_local(
|
|
@@ -671,6 +672,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
671
672
|
# Experimental: Clustered functions
|
|
672
673
|
cluster_size: int | None = None,
|
|
673
674
|
rdma: bool | None = None,
|
|
675
|
+
fabric_size: int | None = None,
|
|
674
676
|
single_use_containers: bool = False,
|
|
675
677
|
ephemeral_disk: int | None = None,
|
|
676
678
|
include_source: bool = True,
|
|
@@ -1009,6 +1011,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1009
1011
|
mount_client_dependencies=mount_client_dependencies,
|
|
1010
1012
|
# ---
|
|
1011
1013
|
_experimental_group_size=cluster_size or 0, # Experimental: Clustered functions
|
|
1014
|
+
_experimental_fabric_size=fabric_size or 0, # Experimental: Clustered functions
|
|
1012
1015
|
_experimental_concurrent_cancellations=True,
|
|
1013
1016
|
# --- These are deprecated in favor of autoscaler_settings
|
|
1014
1017
|
warm_pool_size=min_containers or 0,
|
|
@@ -1051,6 +1054,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1051
1054
|
method_definitions_set=function_definition.method_definitions_set,
|
|
1052
1055
|
experimental_options=experimental_options or {},
|
|
1053
1056
|
_experimental_group_size=function_definition._experimental_group_size,
|
|
1057
|
+
_experimental_fabric_size=function_definition._experimental_fabric_size,
|
|
1054
1058
|
_experimental_buffer_containers=function_definition._experimental_buffer_containers,
|
|
1055
1059
|
_experimental_custom_scaling=function_definition._experimental_custom_scaling,
|
|
1056
1060
|
snapshot_debug=function_definition.snapshot_debug,
|
|
@@ -1400,6 +1404,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1400
1404
|
metadata.max_object_size_bytes if metadata.HasField("max_object_size_bytes") else MAX_OBJECT_SIZE_BYTES
|
|
1401
1405
|
)
|
|
1402
1406
|
self._experimental_flash_urls = metadata._experimental_flash_urls
|
|
1407
|
+
self._app_id = metadata.app_id or None
|
|
1403
1408
|
|
|
1404
1409
|
# Invalidate the Function variant cache when we load new metadata, since the base Function handle
|
|
1405
1410
|
# is now in sync with the server but any previously-cached variants may be stale.
|
|
@@ -1409,6 +1414,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1409
1414
|
# Overridden concrete implementation of base class method
|
|
1410
1415
|
assert self._function_name, f"Function name must be set before metadata can be retrieved for {self}"
|
|
1411
1416
|
return api_pb2.FunctionHandleMetadata(
|
|
1417
|
+
app_id=self._app_id or "",
|
|
1412
1418
|
function_name=self._function_name,
|
|
1413
1419
|
function_type=get_function_type(self._is_generator),
|
|
1414
1420
|
web_url=self._web_url or "",
|
|
@@ -1670,6 +1676,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1670
1676
|
)
|
|
1671
1677
|
fc: _FunctionCall[ReturnType] = _FunctionCall._new_hydrated(function_call_id, self.client, None)
|
|
1672
1678
|
fc._num_inputs = num_inputs # set the cached value of num_inputs
|
|
1679
|
+
fc._app_id = self._app_id
|
|
1680
|
+
fc._function_id = self.object_id
|
|
1673
1681
|
return fc
|
|
1674
1682
|
|
|
1675
1683
|
async def _call_function(self, args, kwargs) -> ReturnType:
|
|
@@ -1881,6 +1889,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1881
1889
|
invocation.function_call_id, invocation.client, None
|
|
1882
1890
|
)
|
|
1883
1891
|
fc._is_generator = self._is_generator if self._is_generator else False
|
|
1892
|
+
fc._app_id = self._app_id
|
|
1893
|
+
fc._function_id = self.object_id
|
|
1884
1894
|
return fc
|
|
1885
1895
|
|
|
1886
1896
|
@synchronizer.no_input_translation
|
|
@@ -1917,6 +1927,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1917
1927
|
fc: _FunctionCall[ReturnType] = _FunctionCall._new_hydrated(
|
|
1918
1928
|
invocation.function_call_id, invocation.client, None
|
|
1919
1929
|
)
|
|
1930
|
+
fc._app_id = self._app_id
|
|
1931
|
+
fc._function_id = self.object_id
|
|
1920
1932
|
return fc
|
|
1921
1933
|
|
|
1922
1934
|
def get_raw_f(self) -> Callable[..., Any]:
|
|
@@ -1976,10 +1988,18 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
|
|
|
1976
1988
|
|
|
1977
1989
|
_is_generator: bool = False
|
|
1978
1990
|
_num_inputs: int | None = None
|
|
1991
|
+
_app_id: str | None = None
|
|
1992
|
+
_function_id: str | None = None
|
|
1979
1993
|
|
|
1980
1994
|
def _invocation(self):
|
|
1981
1995
|
return _Invocation(self.client.stub, self.object_id, self.client)
|
|
1982
1996
|
|
|
1997
|
+
async def _hydrate_from_id_metadata(self) -> None:
|
|
1998
|
+
"""Hydrate metadata only when needed for FunctionCall fields."""
|
|
1999
|
+
request = api_pb2.FunctionCallFromIdRequest(function_call_id=self.object_id)
|
|
2000
|
+
resp = await self.client.stub.FunctionCallFromId(request)
|
|
2001
|
+
self._hydrate_metadata(resp)
|
|
2002
|
+
|
|
1983
2003
|
@live_method
|
|
1984
2004
|
async def num_inputs(self) -> int:
|
|
1985
2005
|
"""Get the number of inputs in the function call.
|
|
@@ -1988,9 +2008,8 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
|
|
|
1988
2008
|
How many inputs this function call includes (e.g. `1` for `.spawn()`, more for `.spawn_map()`).
|
|
1989
2009
|
"""
|
|
1990
2010
|
if self._num_inputs is None:
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
self._num_inputs = resp.num_inputs # cached
|
|
2011
|
+
await self._hydrate_from_id_metadata()
|
|
2012
|
+
assert self._num_inputs is not None
|
|
1994
2013
|
return self._num_inputs
|
|
1995
2014
|
|
|
1996
2015
|
@live_method
|
|
@@ -2132,6 +2151,13 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
|
|
|
2132
2151
|
)
|
|
2133
2152
|
return typing.cast("modal.functions.FunctionCall[Any]", synchronizer._translate_out(impl_instance))
|
|
2134
2153
|
|
|
2154
|
+
def _hydrate_metadata(self, metadata: Message | None):
|
|
2155
|
+
# Overridden concrete implementation of base class method
|
|
2156
|
+
if isinstance(metadata, api_pb2.FunctionCallFromIdResponse):
|
|
2157
|
+
self._num_inputs = metadata.num_inputs
|
|
2158
|
+
self._app_id = metadata.metadata.app_id or None
|
|
2159
|
+
self._function_id = metadata.metadata.function_id or None
|
|
2160
|
+
|
|
2135
2161
|
@staticmethod
|
|
2136
2162
|
async def gather(*function_calls: "_FunctionCall[T]") -> typing.Sequence[T]:
|
|
2137
2163
|
"""Wait until all Modal FunctionCall objects have results before returning.
|
|
@@ -74,6 +74,7 @@ class _PartialFunctionParams:
|
|
|
74
74
|
target_concurrent_inputs: int | None = None
|
|
75
75
|
build_timeout: int | None = None
|
|
76
76
|
rdma: bool | None = None
|
|
77
|
+
fabric_size: int | None = None
|
|
77
78
|
http_config: api_pb2.HTTPConfig | None = None
|
|
78
79
|
|
|
79
80
|
def update(self, other: "_PartialFunctionParams") -> None:
|
|
@@ -777,7 +778,7 @@ def _concurrent(
|
|
|
777
778
|
|
|
778
779
|
# NOTE: clustered is currently exposed through modal.experimental, not the top-level namespace
|
|
779
780
|
def _clustered(
|
|
780
|
-
size: int, broadcast: bool = True, rdma: bool = False
|
|
781
|
+
size: int, broadcast: bool = True, rdma: bool = False, fabric_size: int | None = None
|
|
781
782
|
) -> Callable[
|
|
782
783
|
[Callable[P, ReturnType] | _PartialFunction[P, ReturnType, ReturnType]],
|
|
783
784
|
_PartialFunction[P, ReturnType, ReturnType],
|
|
@@ -791,6 +792,11 @@ def _clustered(
|
|
|
791
792
|
If True, inputs will be sent simultaneously to each container. Otherwise,
|
|
792
793
|
inputs will be sent only to the rank-0 container, which is responsible for
|
|
793
794
|
delegating to the workers.
|
|
795
|
+
fabric_size: int | None = None
|
|
796
|
+
Experimental: constrains placement across GPU-memory fabrics. The cluster
|
|
797
|
+
is placed in co-fabric blocks of `fabric_size` containers, so every block
|
|
798
|
+
of `fabric_size` consecutive ranks shares a fabric (the scale-up domain)
|
|
799
|
+
and communicates over cross-node NVLink. Must evenly divide `size`.
|
|
794
800
|
"""
|
|
795
801
|
|
|
796
802
|
assert broadcast, "broadcast=False has not been implemented yet!"
|
|
@@ -798,8 +804,14 @@ def _clustered(
|
|
|
798
804
|
if size <= 0:
|
|
799
805
|
raise ValueError("cluster size must be greater than 0")
|
|
800
806
|
|
|
807
|
+
if fabric_size is not None:
|
|
808
|
+
if not isinstance(fabric_size, int) or fabric_size <= 0:
|
|
809
|
+
raise ValueError("fabric_size must be a positive integer")
|
|
810
|
+
if size % fabric_size != 0:
|
|
811
|
+
raise ValueError(f"fabric_size must evenly divide the cluster size ({size} % {fabric_size} != 0)")
|
|
812
|
+
|
|
801
813
|
flags = _PartialFunctionFlags.CLUSTERED
|
|
802
|
-
params = _PartialFunctionParams(cluster_size=size, rdma=rdma)
|
|
814
|
+
params = _PartialFunctionParams(cluster_size=size, rdma=rdma, fabric_size=fabric_size)
|
|
803
815
|
|
|
804
816
|
def wrapper(
|
|
805
817
|
obj: _PartialFunction[P, ReturnType, ReturnType] | Callable[P, ReturnType],
|
|
@@ -325,7 +325,7 @@ def create_channel(
|
|
|
325
325
|
async def create_channel_with_fallbacks(
|
|
326
326
|
server_url: str,
|
|
327
327
|
metadata: dict[str, str] = {},
|
|
328
|
-
stagger_delay: float =
|
|
328
|
+
stagger_delay: float = 3.0,
|
|
329
329
|
) -> grpclib.client.Channel:
|
|
330
330
|
"""Create a connected channel, supporting comma-separated fallback URLs.
|
|
331
331
|
|
|
@@ -920,6 +920,7 @@ class _App:
|
|
|
920
920
|
i6pn_enabled = i6pn or (f.flags & _PartialFunctionFlags.CLUSTERED)
|
|
921
921
|
cluster_size = f.params.cluster_size # Experimental: Clustered functions
|
|
922
922
|
rdma = f.params.rdma
|
|
923
|
+
fabric_size = f.params.fabric_size
|
|
923
924
|
|
|
924
925
|
info = FunctionInfo(f.raw_f, serialized=serialized, name_override=name)
|
|
925
926
|
raw_f = f.raw_f
|
|
@@ -974,6 +975,7 @@ class _App:
|
|
|
974
975
|
|
|
975
976
|
cluster_size = None # Experimental: Clustered functions
|
|
976
977
|
rdma = None
|
|
978
|
+
fabric_size = None
|
|
977
979
|
i6pn_enabled = i6pn
|
|
978
980
|
|
|
979
981
|
if is_generator is None:
|
|
@@ -1016,6 +1018,7 @@ class _App:
|
|
|
1016
1018
|
i6pn_enabled=i6pn_enabled,
|
|
1017
1019
|
cluster_size=cluster_size, # Experimental: Clustered functions
|
|
1018
1020
|
rdma=rdma,
|
|
1021
|
+
fabric_size=fabric_size, # Experimental: Clustered functions
|
|
1019
1022
|
include_source=include_source if include_source is not None else local_state.include_source_default,
|
|
1020
1023
|
experimental_options={k: str(v) for k, v in (experimental_options or {}).items()},
|
|
1021
1024
|
restrict_output=_experimental_restrict_output,
|
|
@@ -1151,16 +1154,19 @@ class _App:
|
|
|
1151
1154
|
if wrapped_cls.flags & _PartialFunctionFlags.CLUSTERED:
|
|
1152
1155
|
cluster_size = wrapped_cls.params.cluster_size
|
|
1153
1156
|
rdma = wrapped_cls.params.rdma
|
|
1157
|
+
fabric_size = wrapped_cls.params.fabric_size
|
|
1154
1158
|
|
|
1155
1159
|
else:
|
|
1156
1160
|
cluster_size = None
|
|
1157
1161
|
rdma = None
|
|
1162
|
+
fabric_size = None
|
|
1158
1163
|
else:
|
|
1159
1164
|
user_cls = wrapped_cls
|
|
1160
1165
|
max_concurrent_inputs = None
|
|
1161
1166
|
target_concurrent_inputs = None
|
|
1162
1167
|
cluster_size = None
|
|
1163
1168
|
rdma = None
|
|
1169
|
+
fabric_size = None
|
|
1164
1170
|
if not inspect.isclass(user_cls):
|
|
1165
1171
|
raise TypeError("The @app.cls decorator must be used on a class.")
|
|
1166
1172
|
|
|
@@ -1246,6 +1252,7 @@ class _App:
|
|
|
1246
1252
|
i6pn_enabled=i6pn_enabled,
|
|
1247
1253
|
cluster_size=cluster_size,
|
|
1248
1254
|
rdma=rdma,
|
|
1255
|
+
fabric_size=fabric_size,
|
|
1249
1256
|
include_source=include_source if include_source is not None else local_state.include_source_default,
|
|
1250
1257
|
experimental_options={k: str(v) for k, v in (experimental_options or {}).items()},
|
|
1251
1258
|
restrict_output=_experimental_restrict_output,
|
|
@@ -1403,6 +1410,7 @@ class _App:
|
|
|
1403
1410
|
# Extract the underlying class if wrapped in a _PartialFunction (e.g., from @modal.clustered())
|
|
1404
1411
|
cluster_size = None
|
|
1405
1412
|
rdma = None
|
|
1413
|
+
fabric_size = None
|
|
1406
1414
|
user_cls = wrapped_user_cls
|
|
1407
1415
|
|
|
1408
1416
|
if isinstance(wrapped_user_cls, _PartialFunction):
|
|
@@ -1410,6 +1418,7 @@ class _App:
|
|
|
1410
1418
|
if wrapped_user_cls.flags & _PartialFunctionFlags.CLUSTERED:
|
|
1411
1419
|
cluster_size = wrapped_user_cls.params.cluster_size
|
|
1412
1420
|
rdma = wrapped_user_cls.params.rdma
|
|
1421
|
+
fabric_size = wrapped_user_cls.params.fabric_size
|
|
1413
1422
|
|
|
1414
1423
|
local_state = self._local_state
|
|
1415
1424
|
|
|
@@ -1449,6 +1458,7 @@ class _App:
|
|
|
1449
1458
|
i6pn_enabled=i6pn or (cluster_size is not None),
|
|
1450
1459
|
cluster_size=cluster_size,
|
|
1451
1460
|
rdma=rdma,
|
|
1461
|
+
fabric_size=fabric_size,
|
|
1452
1462
|
include_source=include_source if include_source is not None else local_state.include_source_default,
|
|
1453
1463
|
experimental_options={k: str(v) for k, v in (experimental_options or {}).items()},
|
|
1454
1464
|
restrict_output=False,
|
|
@@ -35,7 +35,7 @@ class _Client:
|
|
|
35
35
|
server_url: str,
|
|
36
36
|
client_type: int,
|
|
37
37
|
credentials: typing.Optional[tuple[str, str]],
|
|
38
|
-
version: str = "1.5.3.
|
|
38
|
+
version: str = "1.5.3.dev3",
|
|
39
39
|
):
|
|
40
40
|
"""mdmd:hidden
|
|
41
41
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -205,7 +205,7 @@ class Client:
|
|
|
205
205
|
server_url: str,
|
|
206
206
|
client_type: int,
|
|
207
207
|
credentials: typing.Optional[tuple[str, str]],
|
|
208
|
-
version: str = "1.5.3.
|
|
208
|
+
version: str = "1.5.3.dev3",
|
|
209
209
|
):
|
|
210
210
|
"""mdmd:hidden
|
|
211
211
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -86,6 +86,8 @@ def _bind_instance_method(cls: "_Cls", service_function: _Function, method_name:
|
|
|
86
86
|
|
|
87
87
|
method_metadata = service_function._method_handle_metadata[method_name]
|
|
88
88
|
new_function._hydrate(service_function.object_id, service_function.client, method_metadata)
|
|
89
|
+
if not new_function._app_id:
|
|
90
|
+
new_function._app_id = service_function._app_id
|
|
89
91
|
|
|
90
92
|
async def _load(fun: "_Function", resolver: Resolver, load_context: LoadContext, existing_object_id: str | None):
|
|
91
93
|
# there is currently no actual loading logic executed to create each method on
|
|
@@ -426,6 +428,7 @@ class _Obj:
|
|
|
426
428
|
)
|
|
427
429
|
await resolver.load(method_function, load_context) # get the appropriate method handle (lazy)
|
|
428
430
|
fun._hydrate_from_other(method_function)
|
|
431
|
+
fun._app_id = method_function._app_id
|
|
429
432
|
|
|
430
433
|
# The reason we don't *always* use this lazy loader is because it precludes attribute access
|
|
431
434
|
# on local classes.
|
|
@@ -106,7 +106,8 @@ from modal_proto import api_pb2
|
|
|
106
106
|
from ._utils.logger import configure_logger
|
|
107
107
|
from .exception import InvalidError, NotFoundError
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
# By default, try api.modal.com and fail over to api.modal2.com
|
|
110
|
+
DEFAULT_SERVER_URL = "https://api.modal.com,https://api.modal2.com"
|
|
110
111
|
|
|
111
112
|
|
|
112
113
|
# Locate config file and read it
|
|
@@ -58,6 +58,7 @@ class Function(
|
|
|
58
58
|
_metadata: typing.Optional[modal_proto.api_pb2.FunctionHandleMetadata]
|
|
59
59
|
_options: modal._function_variants._FunctionOptions
|
|
60
60
|
_base_function: typing.Optional[Function]
|
|
61
|
+
_app_id: typing.Optional[str]
|
|
61
62
|
|
|
62
63
|
def __init__(self, *args, **kwargs):
|
|
63
64
|
"""mdmd:hidden"""
|
|
@@ -109,6 +110,7 @@ class Function(
|
|
|
109
110
|
i6pn_enabled: bool = False,
|
|
110
111
|
cluster_size: typing.Optional[int] = None,
|
|
111
112
|
rdma: typing.Optional[bool] = None,
|
|
113
|
+
fabric_size: typing.Optional[int] = None,
|
|
112
114
|
single_use_containers: bool = False,
|
|
113
115
|
ephemeral_disk: typing.Optional[int] = None,
|
|
114
116
|
include_source: bool = True,
|
|
@@ -491,7 +493,7 @@ class Function(
|
|
|
491
493
|
|
|
492
494
|
_call_generator: ___call_generator_spec
|
|
493
495
|
|
|
494
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
496
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
495
497
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
496
498
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result.
|
|
497
499
|
|
|
@@ -516,7 +518,7 @@ class Function(
|
|
|
516
518
|
"""
|
|
517
519
|
...
|
|
518
520
|
|
|
519
|
-
remote: __remote_spec[modal._functions.
|
|
521
|
+
remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
|
|
520
522
|
|
|
521
523
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
522
524
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -566,7 +568,7 @@ class Function(
|
|
|
566
568
|
"""
|
|
567
569
|
...
|
|
568
570
|
|
|
569
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
571
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
570
572
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
571
573
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
572
574
|
|
|
@@ -599,7 +601,7 @@ class Function(
|
|
|
599
601
|
"""
|
|
600
602
|
...
|
|
601
603
|
|
|
602
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
604
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
603
605
|
|
|
604
606
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
605
607
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -607,7 +609,7 @@ class Function(
|
|
|
607
609
|
|
|
608
610
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
609
611
|
|
|
610
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
612
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
611
613
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
612
614
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
613
615
|
|
|
@@ -640,7 +642,7 @@ class Function(
|
|
|
640
642
|
"""
|
|
641
643
|
...
|
|
642
644
|
|
|
643
|
-
spawn: __spawn_spec[modal._functions.
|
|
645
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
644
646
|
|
|
645
647
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
646
648
|
"""Return the inner Python object wrapped by this Modal Function.
|
|
@@ -891,6 +893,8 @@ class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Obj
|
|
|
891
893
|
|
|
892
894
|
_is_generator: bool
|
|
893
895
|
_num_inputs: typing.Optional[int]
|
|
896
|
+
_app_id: typing.Optional[str]
|
|
897
|
+
_function_id: typing.Optional[str]
|
|
894
898
|
|
|
895
899
|
def __init__(self, *args, **kwargs):
|
|
896
900
|
"""mdmd:hidden"""
|
|
@@ -898,6 +902,17 @@ class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Obj
|
|
|
898
902
|
|
|
899
903
|
def _invocation(self): ...
|
|
900
904
|
|
|
905
|
+
class ___hydrate_from_id_metadata_spec(typing_extensions.Protocol):
|
|
906
|
+
def __call__(self, /) -> None:
|
|
907
|
+
"""Hydrate metadata only when needed for FunctionCall fields."""
|
|
908
|
+
...
|
|
909
|
+
|
|
910
|
+
async def aio(self, /) -> None:
|
|
911
|
+
"""Hydrate metadata only when needed for FunctionCall fields."""
|
|
912
|
+
...
|
|
913
|
+
|
|
914
|
+
_hydrate_from_id_metadata: ___hydrate_from_id_metadata_spec
|
|
915
|
+
|
|
901
916
|
class __num_inputs_spec(typing_extensions.Protocol):
|
|
902
917
|
def __call__(self, /) -> int:
|
|
903
918
|
"""Get the number of inputs in the function call.
|
|
@@ -1114,6 +1129,8 @@ class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Obj
|
|
|
1114
1129
|
|
|
1115
1130
|
from_id: typing.ClassVar[__from_id_spec]
|
|
1116
1131
|
|
|
1132
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
1133
|
+
|
|
1117
1134
|
class __gather_spec(typing_extensions.Protocol):
|
|
1118
1135
|
def __call__(self, /, *function_calls: FunctionCall[modal._functions.T]) -> typing.Sequence[modal._functions.T]:
|
|
1119
1136
|
"""Wait until all Modal FunctionCall objects have results before returning.
|
|
@@ -349,7 +349,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
349
349
|
gpu: str | None = None,
|
|
350
350
|
cloud: str | None = None,
|
|
351
351
|
region: str | Sequence[str] | None = None,
|
|
352
|
-
cpu: float | None = None,
|
|
352
|
+
cpu: float | tuple[float, float] | None = None,
|
|
353
353
|
memory: int | tuple[int, int] | None = None,
|
|
354
354
|
mounts: Sequence[_Mount] = (),
|
|
355
355
|
network_file_systems: dict[str | os.PathLike, _NetworkFileSystem] = {},
|
|
@@ -823,8 +823,8 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
823
823
|
timeout: int = 300,
|
|
824
824
|
idle_timeout: int | None = None,
|
|
825
825
|
workdir: str | None = None,
|
|
826
|
-
cpu: float | None = None,
|
|
827
|
-
memory: int | None = None,
|
|
826
|
+
cpu: float | tuple[float, float] | None = None,
|
|
827
|
+
memory: int | tuple[int, int] | None = None,
|
|
828
828
|
cloud: str | None = None,
|
|
829
829
|
region: str | Sequence[str] | None = None,
|
|
830
830
|
block_network: bool = False,
|
|
@@ -852,6 +852,10 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
852
852
|
`secret=...` or `oidc_auth_role_arn`), OIDC identity tokens, proxies, and
|
|
853
853
|
filesystem snapshots.
|
|
854
854
|
|
|
855
|
+
`cpu` and `memory` accept either a scalar request or a `(request, limit)`
|
|
856
|
+
tuple that additionally sets a hard limit (fractional CPU cores; memory
|
|
857
|
+
in MiB), matching `Sandbox.create()`.
|
|
858
|
+
|
|
855
859
|
Features like memory snapshots, network file systems, GPUs, and custom
|
|
856
860
|
domains are not supported.
|
|
857
861
|
|
|
@@ -165,7 +165,7 @@ class _Sandbox(modal._object._Object):
|
|
|
165
165
|
gpu: typing.Optional[str] = None,
|
|
166
166
|
cloud: typing.Optional[str] = None,
|
|
167
167
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
|
168
|
-
cpu: typing.
|
|
168
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
|
169
169
|
memory: typing.Union[int, tuple[int, int], None] = None,
|
|
170
170
|
mounts: collections.abc.Sequence[modal.mount._Mount] = (),
|
|
171
171
|
network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system._NetworkFileSystem] = {},
|
|
@@ -368,8 +368,8 @@ class _Sandbox(modal._object._Object):
|
|
|
368
368
|
timeout: int = 300,
|
|
369
369
|
idle_timeout: typing.Optional[int] = None,
|
|
370
370
|
workdir: typing.Optional[str] = None,
|
|
371
|
-
cpu: typing.
|
|
372
|
-
memory: typing.
|
|
371
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
|
372
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
|
373
373
|
cloud: typing.Optional[str] = None,
|
|
374
374
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
|
375
375
|
block_network: bool = False,
|
|
@@ -400,6 +400,10 @@ class _Sandbox(modal._object._Object):
|
|
|
400
400
|
`secret=...` or `oidc_auth_role_arn`), OIDC identity tokens, proxies, and
|
|
401
401
|
filesystem snapshots.
|
|
402
402
|
|
|
403
|
+
`cpu` and `memory` accept either a scalar request or a `(request, limit)`
|
|
404
|
+
tuple that additionally sets a hard limit (fractional CPU cores; memory
|
|
405
|
+
in MiB), matching `Sandbox.create()`.
|
|
406
|
+
|
|
403
407
|
Features like memory snapshots, network file systems, GPUs, and custom
|
|
404
408
|
domains are not supported.
|
|
405
409
|
|
|
@@ -1337,7 +1341,7 @@ class Sandbox(modal.object.Object):
|
|
|
1337
1341
|
gpu: typing.Optional[str] = None,
|
|
1338
1342
|
cloud: typing.Optional[str] = None,
|
|
1339
1343
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
|
1340
|
-
cpu: typing.
|
|
1344
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
|
1341
1345
|
memory: typing.Union[int, tuple[int, int], None] = None,
|
|
1342
1346
|
mounts: collections.abc.Sequence[modal.mount.Mount] = (),
|
|
1343
1347
|
network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem] = {},
|
|
@@ -1721,8 +1725,8 @@ class Sandbox(modal.object.Object):
|
|
|
1721
1725
|
timeout: int = 300,
|
|
1722
1726
|
idle_timeout: typing.Optional[int] = None,
|
|
1723
1727
|
workdir: typing.Optional[str] = None,
|
|
1724
|
-
cpu: typing.
|
|
1725
|
-
memory: typing.
|
|
1728
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
|
1729
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
|
1726
1730
|
cloud: typing.Optional[str] = None,
|
|
1727
1731
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
|
1728
1732
|
block_network: bool = False,
|
|
@@ -1753,6 +1757,10 @@ class Sandbox(modal.object.Object):
|
|
|
1753
1757
|
`secret=...` or `oidc_auth_role_arn`), OIDC identity tokens, proxies, and
|
|
1754
1758
|
filesystem snapshots.
|
|
1755
1759
|
|
|
1760
|
+
`cpu` and `memory` accept either a scalar request or a `(request, limit)`
|
|
1761
|
+
tuple that additionally sets a hard limit (fractional CPU cores; memory
|
|
1762
|
+
in MiB), matching `Sandbox.create()`.
|
|
1763
|
+
|
|
1756
1764
|
Features like memory snapshots, network file systems, GPUs, and custom
|
|
1757
1765
|
domains are not supported.
|
|
1758
1766
|
|
|
@@ -1783,8 +1791,8 @@ class Sandbox(modal.object.Object):
|
|
|
1783
1791
|
timeout: int = 300,
|
|
1784
1792
|
idle_timeout: typing.Optional[int] = None,
|
|
1785
1793
|
workdir: typing.Optional[str] = None,
|
|
1786
|
-
cpu: typing.
|
|
1787
|
-
memory: typing.
|
|
1794
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
|
1795
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
|
1788
1796
|
cloud: typing.Optional[str] = None,
|
|
1789
1797
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
|
1790
1798
|
block_network: bool = False,
|
|
@@ -1815,6 +1823,10 @@ class Sandbox(modal.object.Object):
|
|
|
1815
1823
|
`secret=...` or `oidc_auth_role_arn`), OIDC identity tokens, proxies, and
|
|
1816
1824
|
filesystem snapshots.
|
|
1817
1825
|
|
|
1826
|
+
`cpu` and `memory` accept either a scalar request or a `(request, limit)`
|
|
1827
|
+
tuple that additionally sets a hard limit (fractional CPU cores; memory
|
|
1828
|
+
in MiB), matching `Sandbox.create()`.
|
|
1829
|
+
|
|
1818
1830
|
Features like memory snapshots, network file systems, GPUs, and custom
|
|
1819
1831
|
domains are not supported.
|
|
1820
1832
|
|
|
@@ -639,6 +639,10 @@ class ModalClientBase(abc.ABC):
|
|
|
639
639
|
async def SandboxRestore(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxRestoreRequest, modal_proto.api_pb2.SandboxRestoreResponse]') -> None:
|
|
640
640
|
pass
|
|
641
641
|
|
|
642
|
+
@abc.abstractmethod
|
|
643
|
+
async def SandboxSetName(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxSetNameRequest, modal_proto.api_pb2.SandboxSetNameResponse]') -> None:
|
|
644
|
+
pass
|
|
645
|
+
|
|
642
646
|
@abc.abstractmethod
|
|
643
647
|
async def SandboxSnapshot(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxSnapshotRequest, modal_proto.api_pb2.SandboxSnapshotResponse]') -> None:
|
|
644
648
|
pass
|
|
@@ -1871,6 +1875,12 @@ class ModalClientBase(abc.ABC):
|
|
|
1871
1875
|
modal_proto.api_pb2.SandboxRestoreRequest,
|
|
1872
1876
|
modal_proto.api_pb2.SandboxRestoreResponse,
|
|
1873
1877
|
),
|
|
1878
|
+
'/modal.client.ModalClient/SandboxSetName': grpclib.const.Handler(
|
|
1879
|
+
self.SandboxSetName,
|
|
1880
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
|
1881
|
+
modal_proto.api_pb2.SandboxSetNameRequest,
|
|
1882
|
+
modal_proto.api_pb2.SandboxSetNameResponse,
|
|
1883
|
+
),
|
|
1874
1884
|
'/modal.client.ModalClient/SandboxSnapshot': grpclib.const.Handler(
|
|
1875
1885
|
self.SandboxSnapshot,
|
|
1876
1886
|
grpclib.const.Cardinality.UNARY_UNARY,
|
|
@@ -3257,6 +3267,12 @@ class ModalClientStub:
|
|
|
3257
3267
|
modal_proto.api_pb2.SandboxRestoreRequest,
|
|
3258
3268
|
modal_proto.api_pb2.SandboxRestoreResponse,
|
|
3259
3269
|
)
|
|
3270
|
+
self.SandboxSetName = grpclib.client.UnaryUnaryMethod(
|
|
3271
|
+
channel,
|
|
3272
|
+
'/modal.client.ModalClient/SandboxSetName',
|
|
3273
|
+
modal_proto.api_pb2.SandboxSetNameRequest,
|
|
3274
|
+
modal_proto.api_pb2.SandboxSetNameResponse,
|
|
3275
|
+
)
|
|
3260
3276
|
self.SandboxSnapshot = grpclib.client.UnaryUnaryMethod(
|
|
3261
3277
|
channel,
|
|
3262
3278
|
'/modal.client.ModalClient/SandboxSnapshot',
|