modal 1.5.6.dev2__tar.gz → 1.5.6.dev4__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.6.dev2 → modal-1.5.6.dev4}/PKG-INFO +1 -1
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/gpu_memory_snapshot.py +3 -34
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/task_lifecycle_manager.py +28 -16
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/task_lifecycle_manager.pyi +5 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/client.pyi +2 -2
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/config.py +2 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/functions.pyi +6 -6
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/sandbox.py +35 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/sandbox.pyi +66 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/api_grpc.py +32 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/api_pb2.py +865 -805
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/api_pb2.pyi +124 -1
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/api_pb2_grpc.py +67 -1
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/api_pb2_grpc.pyi +23 -3
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/modal_api_grpc.py +2 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_version/__init__.py +1 -1
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/pyproject.toml +4 -8
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/LICENSE +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/README.md +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/__main__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_billing.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_clustered_functions.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_environments.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_function_variants.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_functions.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_grpc_client.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_image.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_ipython.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_load_context.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_location.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_logs.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_logs_manager.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_logs_manager.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_object.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_output/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_output/manager.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_output/pty.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_output/rich.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_output/status.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_partial_function.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_resolver.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_resources.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_serialization.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_server.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_supports_logs.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_traceback.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_tunnel.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_tunnel.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_type_manager.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/display_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/logger.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_vendor/version.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_watcher.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/_workspace.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/app.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/app.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/billing.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/billing.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/builder/README.md +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/builder/base-images.json +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/call_graph.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/_download.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/_help.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/_traceback.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/app.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/billing.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/changelog.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/cluster.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/config.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/container.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/curl.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/dashboard.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/dict.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/endpoint.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/entry_point.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/environment.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/image.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/import_refs.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/launch.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/logo.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/profile.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/queues.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/run.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/secret.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/selector.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/shell.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/skills.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/token.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/utils.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/volume.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cli/workspace.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/client.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cls.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/cls.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/container_process.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/container_process.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/dict.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/dict.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/environments.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/environments.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/exception.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/experimental/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/experimental/flash.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/experimental/ipython.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/file_io.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/file_io.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/functions.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/image.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/image.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/io_streams.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/io_streams.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/mount.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/mount.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/network_file_system.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/network_file_system.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/object.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/object.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/output.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/parallel_map.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/parallel_map.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/partial_function.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/partial_function.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/proxy.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/proxy.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/py.typed +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/queue.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/queue.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/retries.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/runner.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/runner.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/running_app.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/sandbox_fs.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/schedule.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/scheduler_placement.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/secret.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/secret.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/server.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/server.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/serving.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/serving.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/snapshot.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/snapshot.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/stream_type.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/token_flow.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/token_flow.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/types.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/volume.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/volume.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/workspace.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal/workspace.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_docs/reference_intro.md +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/__init__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/py.typed +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/modal_version/__main__.py +0 -0
- {modal-1.5.6.dev2 → modal-1.5.6.dev4}/setup.cfg +0 -0
|
@@ -22,15 +22,9 @@ CUDA_CHECKPOINT_PATH: str = config.get("cuda_checkpoint_path")
|
|
|
22
22
|
# stay in sync with `GPU_SNAPSHOT_RESTORE_FAILED_EXIT_CODE` in runner.rs.
|
|
23
23
|
SNAPSHOT_RESTORE_FAILED_EXIT_CODE: int = 222
|
|
24
24
|
|
|
25
|
-
# Maximum total duration for each individual `cuda-checkpoint` invocation.
|
|
26
|
-
CUDA_CHECKPOINT_TIMEOUT: float = 3 * 60.0
|
|
27
|
-
|
|
28
25
|
# Number of retries for each individual `cuda-checkpoint --toggle` invocation.
|
|
29
26
|
CUDA_CHECKPOINT_TOGGLE_NUM_RETRIES: int = 3
|
|
30
27
|
|
|
31
|
-
# Maximum total duration for an entire toggle operation.
|
|
32
|
-
CUDA_CHECKPOINT_TOGGLE_TIMEOUT: float = CUDA_CHECKPOINT_TOGGLE_NUM_RETRIES * CUDA_CHECKPOINT_TIMEOUT
|
|
33
|
-
|
|
34
28
|
|
|
35
29
|
class CudaCheckpointState(Enum):
|
|
36
30
|
"""State representation from the CUDA API [1].
|
|
@@ -63,14 +57,11 @@ class CudaCheckpointProcess:
|
|
|
63
57
|
"""
|
|
64
58
|
logger.debug(f"PID: {self.pid} Toggling CUDA checkpoint state to {target_state.value}")
|
|
65
59
|
|
|
66
|
-
start_time = time.monotonic()
|
|
67
60
|
retry_count = 0
|
|
68
61
|
max_retries = CUDA_CHECKPOINT_TOGGLE_NUM_RETRIES
|
|
69
62
|
|
|
70
63
|
attempts = 0
|
|
71
|
-
while self._should_continue_toggle(
|
|
72
|
-
target_state, start_time, refresh=not (skip_first_refresh and attempts == 0)
|
|
73
|
-
):
|
|
64
|
+
while self._should_continue_toggle(target_state, refresh=not (skip_first_refresh and attempts == 0)):
|
|
74
65
|
attempts += 1
|
|
75
66
|
try:
|
|
76
67
|
self._execute_toggle_command()
|
|
@@ -89,10 +80,8 @@ class CudaCheckpointProcess:
|
|
|
89
80
|
|
|
90
81
|
logger.debug(f"PID: {self.pid} Target state {target_state.value} reached")
|
|
91
82
|
|
|
92
|
-
def _should_continue_toggle(
|
|
93
|
-
|
|
94
|
-
) -> bool:
|
|
95
|
-
"""Check if toggle operation should continue based on current state and timeout."""
|
|
83
|
+
def _should_continue_toggle(self, target_state: CudaCheckpointState, refresh: bool = True) -> bool:
|
|
84
|
+
"""Check if toggle operation should continue based on current state."""
|
|
96
85
|
if refresh:
|
|
97
86
|
self.refresh_state()
|
|
98
87
|
|
|
@@ -102,13 +91,6 @@ class CudaCheckpointProcess:
|
|
|
102
91
|
if self.state == CudaCheckpointState.FAILED:
|
|
103
92
|
raise CudaCheckpointException(f"PID: {self.pid} CUDA process state is {self.state}")
|
|
104
93
|
|
|
105
|
-
elapsed = time.monotonic() - start_time
|
|
106
|
-
if elapsed >= CUDA_CHECKPOINT_TOGGLE_TIMEOUT:
|
|
107
|
-
raise CudaCheckpointException(
|
|
108
|
-
f"PID: {self.pid} Timeout after {elapsed:.2f}s waiting for state {target_state.value}. "
|
|
109
|
-
f"Current state: {self.state}"
|
|
110
|
-
)
|
|
111
|
-
|
|
112
94
|
return True
|
|
113
95
|
|
|
114
96
|
def _execute_toggle_command(self) -> None:
|
|
@@ -119,17 +101,12 @@ class CudaCheckpointProcess:
|
|
|
119
101
|
check=True,
|
|
120
102
|
capture_output=True,
|
|
121
103
|
text=True,
|
|
122
|
-
timeout=CUDA_CHECKPOINT_TIMEOUT,
|
|
123
104
|
)
|
|
124
105
|
logger.debug(f"PID: {self.pid} Successfully toggled CUDA checkpoint state")
|
|
125
106
|
except subprocess.CalledProcessError as e:
|
|
126
107
|
error_msg = f"PID: {self.pid} Failed to toggle CUDA checkpoint state: {e.stderr}"
|
|
127
108
|
logger.debug(error_msg)
|
|
128
109
|
raise CudaCheckpointException(error_msg)
|
|
129
|
-
except subprocess.TimeoutExpired:
|
|
130
|
-
error_msg = f"PID: {self.pid} Toggle command timed out"
|
|
131
|
-
logger.debug(error_msg)
|
|
132
|
-
raise CudaCheckpointException(error_msg)
|
|
133
110
|
|
|
134
111
|
def refresh_state(self) -> None:
|
|
135
112
|
"""Refreshes the current CUDA checkpoint state for this process."""
|
|
@@ -139,7 +116,6 @@ class CudaCheckpointProcess:
|
|
|
139
116
|
check=True,
|
|
140
117
|
capture_output=True,
|
|
141
118
|
text=True,
|
|
142
|
-
timeout=CUDA_CHECKPOINT_TIMEOUT,
|
|
143
119
|
)
|
|
144
120
|
|
|
145
121
|
state_str = result.stdout.strip().lower()
|
|
@@ -149,10 +125,6 @@ class CudaCheckpointProcess:
|
|
|
149
125
|
error_msg = f"PID: {self.pid} Failed to get CUDA checkpoint state: {e.stderr}"
|
|
150
126
|
logger.debug(error_msg)
|
|
151
127
|
raise CudaCheckpointException(error_msg)
|
|
152
|
-
except subprocess.TimeoutExpired:
|
|
153
|
-
error_msg = f"PID: {self.pid} Get state command timed out"
|
|
154
|
-
logger.debug(error_msg)
|
|
155
|
-
raise CudaCheckpointException(error_msg)
|
|
156
128
|
|
|
157
129
|
|
|
158
130
|
class CudaCheckpointSession:
|
|
@@ -208,7 +180,6 @@ class CudaCheckpointSession:
|
|
|
208
180
|
[CUDA_CHECKPOINT_PATH, "--get-state", "--pid", str(pid)],
|
|
209
181
|
capture_output=True,
|
|
210
182
|
text=True,
|
|
211
|
-
timeout=CUDA_CHECKPOINT_TIMEOUT,
|
|
212
183
|
)
|
|
213
184
|
|
|
214
185
|
# If the command succeeds (return code 0), this PID has a CUDA session
|
|
@@ -220,8 +191,6 @@ class CudaCheckpointSession:
|
|
|
220
191
|
except subprocess.CalledProcessError:
|
|
221
192
|
# Command failed, which is expected for PIDs without CUDA sessions
|
|
222
193
|
pass
|
|
223
|
-
except subprocess.TimeoutExpired:
|
|
224
|
-
logger.debug(f"Timeout checking CUDA state for PID {pid}")
|
|
225
194
|
except Exception as e:
|
|
226
195
|
logger.debug(f"Error checking PID {pid}: {e}")
|
|
227
196
|
|
|
@@ -143,6 +143,12 @@ class _TaskLifecycleManager:
|
|
|
143
143
|
else:
|
|
144
144
|
logger.debug(f"modal.Volume background commit success for {volume_id}.")
|
|
145
145
|
|
|
146
|
+
@property
|
|
147
|
+
def _gpu_snapshot_enabled(self) -> bool:
|
|
148
|
+
return bool(
|
|
149
|
+
self.function_def._experimental_enable_gpu_snapshot and self.function_def.resources.gpu_config.gpu_type
|
|
150
|
+
)
|
|
151
|
+
|
|
146
152
|
async def memory_restore(self) -> None:
|
|
147
153
|
# Busy-wait for restore. `/__modal/restore-state.json` is created
|
|
148
154
|
# by the worker process with updates to the container config.
|
|
@@ -177,18 +183,21 @@ class _TaskLifecycleManager:
|
|
|
177
183
|
config.override_locally(key, value)
|
|
178
184
|
|
|
179
185
|
# Restore GPU memory.
|
|
180
|
-
if self.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
186
|
+
if self._gpu_snapshot_enabled:
|
|
187
|
+
if config.get("runtime_managed_cuda_checkpoint"):
|
|
188
|
+
logger.debug("GPU memory restore is managed by the container runtime.")
|
|
189
|
+
else:
|
|
190
|
+
logger.debug("GPU memory snapshot enabled. Attempting to restore GPU memory.")
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
if self._cuda_checkpoint_session is None:
|
|
194
|
+
raise gpu_memory_snapshot.CudaCheckpointException("CudaCheckpointSession not found")
|
|
195
|
+
self._cuda_checkpoint_session.restore()
|
|
196
|
+
except gpu_memory_snapshot.CudaCheckpointException as exc:
|
|
197
|
+
logger.warning(f"GPU memory snapshot restore failed; retrying task without snapshot. Error: {exc}")
|
|
198
|
+
sys.stderr.flush()
|
|
199
|
+
# Exit with a sentinel code that the runtime will use to retry the task without a snapshot.
|
|
200
|
+
os._exit(gpu_memory_snapshot.SNAPSHOT_RESTORE_FAILED_EXIT_CODE)
|
|
192
201
|
|
|
193
202
|
self._client = await _Client.from_env()
|
|
194
203
|
|
|
@@ -199,11 +208,14 @@ class _TaskLifecycleManager:
|
|
|
199
208
|
else:
|
|
200
209
|
raise ValueError("No checkpoint ID provided for memory snapshot")
|
|
201
210
|
|
|
202
|
-
if self.
|
|
203
|
-
|
|
211
|
+
if self._gpu_snapshot_enabled:
|
|
212
|
+
if config.get("runtime_managed_cuda_checkpoint"):
|
|
213
|
+
logger.debug("GPU memory snapshot is managed by the container runtime.")
|
|
214
|
+
else:
|
|
215
|
+
logger.debug("GPU memory snapshot enabled. Attempting to snapshot GPU memory.")
|
|
204
216
|
|
|
205
|
-
|
|
206
|
-
|
|
217
|
+
self._cuda_checkpoint_session = gpu_memory_snapshot.CudaCheckpointSession()
|
|
218
|
+
self._cuda_checkpoint_session.checkpoint()
|
|
207
219
|
|
|
208
220
|
await self._client.stub.ContainerCheckpoint(
|
|
209
221
|
api_pb2.ContainerCheckpointRequest(checkpoint_id=self.checkpoint_id)
|
|
@@ -54,6 +54,8 @@ class _TaskLifecycleManager:
|
|
|
54
54
|
"""
|
|
55
55
|
...
|
|
56
56
|
|
|
57
|
+
@property
|
|
58
|
+
def _gpu_snapshot_enabled(self) -> bool: ...
|
|
57
59
|
async def memory_restore(self) -> None: ...
|
|
58
60
|
async def memory_snapshot(self) -> None:
|
|
59
61
|
"""Message server indicating that function is ready to be checkpointed."""
|
|
@@ -111,6 +113,9 @@ class TaskLifecycleManager:
|
|
|
111
113
|
|
|
112
114
|
volume_commit: __volume_commit_spec
|
|
113
115
|
|
|
116
|
+
@property
|
|
117
|
+
def _gpu_snapshot_enabled(self) -> bool: ...
|
|
118
|
+
|
|
114
119
|
class __memory_restore_spec(typing_extensions.Protocol):
|
|
115
120
|
def __call__(self, /) -> None: ...
|
|
116
121
|
async def aio(self, /) -> None: ...
|
|
@@ -77,7 +77,7 @@ class _Client:
|
|
|
77
77
|
server_url: str,
|
|
78
78
|
client_type: int,
|
|
79
79
|
credentials: typing.Optional[tuple[str, str]],
|
|
80
|
-
version: str = "1.5.6.
|
|
80
|
+
version: str = "1.5.6.dev4",
|
|
81
81
|
*,
|
|
82
82
|
oauth_credentials: typing.Optional[_OAuthCredentials] = None,
|
|
83
83
|
):
|
|
@@ -277,7 +277,7 @@ class Client:
|
|
|
277
277
|
server_url: str,
|
|
278
278
|
client_type: int,
|
|
279
279
|
credentials: typing.Optional[tuple[str, str]],
|
|
280
|
-
version: str = "1.5.6.
|
|
280
|
+
version: str = "1.5.6.dev4",
|
|
281
281
|
*,
|
|
282
282
|
oauth_credentials: typing.Optional[_OAuthCredentials] = None,
|
|
283
283
|
):
|
|
@@ -339,6 +339,8 @@ _SETTINGS = {
|
|
|
339
339
|
"sandbox_v2": _Setting(None, transform=_to_boolean),
|
|
340
340
|
"snapshot_debug": _Setting(False, transform=_to_boolean),
|
|
341
341
|
"cuda_checkpoint_path": _Setting("/__modal/.bin/cuda-checkpoint"), # Used for snapshotting GPU memory.
|
|
342
|
+
# Used to indicate gVisor cuda-checkpoint automation.
|
|
343
|
+
"runtime_managed_cuda_checkpoint": _Setting(False, transform=_to_boolean),
|
|
342
344
|
"build_validation": _Setting("error", transform=_check_value(["error", "warn", "ignore"])),
|
|
343
345
|
# Payload format for function inputs/outputs: 'pickle' (default) or 'cbor'
|
|
344
346
|
"payload_format": _Setting(
|
|
@@ -619,7 +619,7 @@ class Function(
|
|
|
619
619
|
|
|
620
620
|
_call_generator: ___call_generator_spec
|
|
621
621
|
|
|
622
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
622
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
623
623
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
624
624
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result.
|
|
625
625
|
|
|
@@ -644,7 +644,7 @@ class Function(
|
|
|
644
644
|
"""
|
|
645
645
|
...
|
|
646
646
|
|
|
647
|
-
remote: __remote_spec[modal._functions.
|
|
647
|
+
remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
|
|
648
648
|
|
|
649
649
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
650
650
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -694,7 +694,7 @@ class Function(
|
|
|
694
694
|
"""
|
|
695
695
|
...
|
|
696
696
|
|
|
697
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
697
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
698
698
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
699
699
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
700
700
|
|
|
@@ -727,7 +727,7 @@ class Function(
|
|
|
727
727
|
"""
|
|
728
728
|
...
|
|
729
729
|
|
|
730
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
730
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
731
731
|
|
|
732
732
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
733
733
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -735,7 +735,7 @@ class Function(
|
|
|
735
735
|
|
|
736
736
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
737
737
|
|
|
738
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
738
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
739
739
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
740
740
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
741
741
|
|
|
@@ -768,7 +768,7 @@ class Function(
|
|
|
768
768
|
"""
|
|
769
769
|
...
|
|
770
770
|
|
|
771
|
-
spawn: __spawn_spec[modal._functions.
|
|
771
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
772
772
|
|
|
773
773
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
774
774
|
"""Return the inner Python object wrapped by this Modal Function.
|
|
@@ -1577,6 +1577,15 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
1577
1577
|
raise InvalidError("ttl is not supported with MODAL_USE_LEGACY_FILESYSTEM_SNAPSHOT")
|
|
1578
1578
|
return await self._legacy_snapshot_filesystem(timeout)
|
|
1579
1579
|
|
|
1580
|
+
return await self._snapshot_filesystem(timeout, ttl=ttl)
|
|
1581
|
+
|
|
1582
|
+
async def _snapshot_filesystem(
|
|
1583
|
+
self,
|
|
1584
|
+
timeout: int,
|
|
1585
|
+
*,
|
|
1586
|
+
ttl: int | None,
|
|
1587
|
+
container_id: str = "",
|
|
1588
|
+
) -> _Image:
|
|
1580
1589
|
wire_ttl_seconds = _ttl_to_wire_ttl(ttl)
|
|
1581
1590
|
|
|
1582
1591
|
task_id = await self._get_task_id()
|
|
@@ -1586,6 +1595,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
1586
1595
|
task_id=task_id,
|
|
1587
1596
|
snapshot_id=str(uuid.uuid4()),
|
|
1588
1597
|
ttl_seconds=wire_ttl_seconds,
|
|
1598
|
+
container_id=container_id,
|
|
1589
1599
|
)
|
|
1590
1600
|
res = await command_router_client.snapshot_filesystem(req, timeout=float(timeout))
|
|
1591
1601
|
return _Image._new_hydrated(res.image_id, self._client, None)
|
|
@@ -2755,6 +2765,31 @@ class _SidecarContainer:
|
|
|
2755
2765
|
command_router_client = await self._sandbox._get_command_router_client(task_id)
|
|
2756
2766
|
return task_id, command_router_client
|
|
2757
2767
|
|
|
2768
|
+
async def snapshot_filesystem(
|
|
2769
|
+
self,
|
|
2770
|
+
timeout: int = 55,
|
|
2771
|
+
*,
|
|
2772
|
+
ttl: int | None = 30 * 24 * 3600,
|
|
2773
|
+
) -> _Image:
|
|
2774
|
+
"""Snapshot this Sidecar container's filesystem.
|
|
2775
|
+
|
|
2776
|
+
Args:
|
|
2777
|
+
timeout:
|
|
2778
|
+
Maximum time in seconds to wait for the snapshot operation.
|
|
2779
|
+
ttl:
|
|
2780
|
+
The resulting Image is retained for `ttl` seconds (default: 30 days). Pass `ttl=None` to retain
|
|
2781
|
+
the image indefinitely.
|
|
2782
|
+
|
|
2783
|
+
Returns:
|
|
2784
|
+
An [`Image`](https://modal.com/docs/sdk/py/latest/Image) containing a snapshot of this Sidecar's
|
|
2785
|
+
filesystem.
|
|
2786
|
+
"""
|
|
2787
|
+
return await self._sandbox._snapshot_filesystem(
|
|
2788
|
+
timeout,
|
|
2789
|
+
ttl=ttl,
|
|
2790
|
+
container_id=self._container_id,
|
|
2791
|
+
)
|
|
2792
|
+
|
|
2758
2793
|
@typing.overload
|
|
2759
2794
|
async def exec(
|
|
2760
2795
|
self,
|
|
@@ -637,6 +637,9 @@ class _Sandbox(modal._object._Object):
|
|
|
637
637
|
"""
|
|
638
638
|
...
|
|
639
639
|
|
|
640
|
+
async def _snapshot_filesystem(
|
|
641
|
+
self, timeout: int, *, ttl: typing.Optional[int], container_id: str = ""
|
|
642
|
+
) -> modal._image._Image: ...
|
|
640
643
|
async def _legacy_snapshot_filesystem(self, timeout: int = 55) -> modal._image._Image: ...
|
|
641
644
|
async def mount_image(
|
|
642
645
|
self,
|
|
@@ -1111,6 +1114,24 @@ class _SidecarContainer:
|
|
|
1111
1114
|
"""Get task ID and command router client."""
|
|
1112
1115
|
...
|
|
1113
1116
|
|
|
1117
|
+
async def snapshot_filesystem(
|
|
1118
|
+
self, timeout: int = 55, *, ttl: typing.Optional[int] = 2592000
|
|
1119
|
+
) -> modal._image._Image:
|
|
1120
|
+
"""Snapshot this Sidecar container's filesystem.
|
|
1121
|
+
|
|
1122
|
+
Args:
|
|
1123
|
+
timeout:
|
|
1124
|
+
Maximum time in seconds to wait for the snapshot operation.
|
|
1125
|
+
ttl:
|
|
1126
|
+
The resulting Image is retained for `ttl` seconds (default: 30 days). Pass `ttl=None` to retain
|
|
1127
|
+
the image indefinitely.
|
|
1128
|
+
|
|
1129
|
+
Returns:
|
|
1130
|
+
An [`Image`](https://modal.com/docs/sdk/py/latest/Image) containing a snapshot of this Sidecar's
|
|
1131
|
+
filesystem.
|
|
1132
|
+
"""
|
|
1133
|
+
...
|
|
1134
|
+
|
|
1114
1135
|
@typing.overload
|
|
1115
1136
|
async def exec(
|
|
1116
1137
|
self,
|
|
@@ -1289,6 +1310,41 @@ class SidecarContainer:
|
|
|
1289
1310
|
|
|
1290
1311
|
_get_command_router: ___get_command_router_spec
|
|
1291
1312
|
|
|
1313
|
+
class __snapshot_filesystem_spec(typing_extensions.Protocol):
|
|
1314
|
+
def __call__(self, /, timeout: int = 55, *, ttl: typing.Optional[int] = 2592000) -> modal.image.Image:
|
|
1315
|
+
"""Snapshot this Sidecar container's filesystem.
|
|
1316
|
+
|
|
1317
|
+
Args:
|
|
1318
|
+
timeout:
|
|
1319
|
+
Maximum time in seconds to wait for the snapshot operation.
|
|
1320
|
+
ttl:
|
|
1321
|
+
The resulting Image is retained for `ttl` seconds (default: 30 days). Pass `ttl=None` to retain
|
|
1322
|
+
the image indefinitely.
|
|
1323
|
+
|
|
1324
|
+
Returns:
|
|
1325
|
+
An [`Image`](https://modal.com/docs/sdk/py/latest/Image) containing a snapshot of this Sidecar's
|
|
1326
|
+
filesystem.
|
|
1327
|
+
"""
|
|
1328
|
+
...
|
|
1329
|
+
|
|
1330
|
+
async def aio(self, /, timeout: int = 55, *, ttl: typing.Optional[int] = 2592000) -> modal.image.Image:
|
|
1331
|
+
"""Snapshot this Sidecar container's filesystem.
|
|
1332
|
+
|
|
1333
|
+
Args:
|
|
1334
|
+
timeout:
|
|
1335
|
+
Maximum time in seconds to wait for the snapshot operation.
|
|
1336
|
+
ttl:
|
|
1337
|
+
The resulting Image is retained for `ttl` seconds (default: 30 days). Pass `ttl=None` to retain
|
|
1338
|
+
the image indefinitely.
|
|
1339
|
+
|
|
1340
|
+
Returns:
|
|
1341
|
+
An [`Image`](https://modal.com/docs/sdk/py/latest/Image) containing a snapshot of this Sidecar's
|
|
1342
|
+
filesystem.
|
|
1343
|
+
"""
|
|
1344
|
+
...
|
|
1345
|
+
|
|
1346
|
+
snapshot_filesystem: __snapshot_filesystem_spec
|
|
1347
|
+
|
|
1292
1348
|
class __exec_spec(typing_extensions.Protocol):
|
|
1293
1349
|
@typing.overload
|
|
1294
1350
|
def __call__(
|
|
@@ -2485,6 +2541,16 @@ class Sandbox(modal.object.Object):
|
|
|
2485
2541
|
|
|
2486
2542
|
snapshot_filesystem: __snapshot_filesystem_spec
|
|
2487
2543
|
|
|
2544
|
+
class ___snapshot_filesystem_spec(typing_extensions.Protocol):
|
|
2545
|
+
def __call__(
|
|
2546
|
+
self, /, timeout: int, *, ttl: typing.Optional[int], container_id: str = ""
|
|
2547
|
+
) -> modal.image.Image: ...
|
|
2548
|
+
async def aio(
|
|
2549
|
+
self, /, timeout: int, *, ttl: typing.Optional[int], container_id: str = ""
|
|
2550
|
+
) -> modal.image.Image: ...
|
|
2551
|
+
|
|
2552
|
+
_snapshot_filesystem: ___snapshot_filesystem_spec
|
|
2553
|
+
|
|
2488
2554
|
class ___legacy_snapshot_filesystem_spec(typing_extensions.Protocol):
|
|
2489
2555
|
def __call__(self, /, timeout: int = 55) -> modal.image.Image: ...
|
|
2490
2556
|
async def aio(self, /, timeout: int = 55) -> modal.image.Image: ...
|
|
@@ -411,6 +411,10 @@ class ModalClientBase(abc.ABC):
|
|
|
411
411
|
async def FunctionGet(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FunctionGetRequest, modal_proto.api_pb2.FunctionGetResponse]') -> None:
|
|
412
412
|
pass
|
|
413
413
|
|
|
414
|
+
@abc.abstractmethod
|
|
415
|
+
async def FunctionGetById(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FunctionGetByIdRequest, modal_proto.api_pb2.FunctionGetByIdResponse]') -> None:
|
|
416
|
+
pass
|
|
417
|
+
|
|
414
418
|
@abc.abstractmethod
|
|
415
419
|
async def FunctionGetCallGraph(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FunctionGetCallGraphRequest, modal_proto.api_pb2.FunctionGetCallGraphResponse]') -> None:
|
|
416
420
|
pass
|
|
@@ -599,6 +603,10 @@ class ModalClientBase(abc.ABC):
|
|
|
599
603
|
async def QueuePut(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.QueuePutRequest, google.protobuf.empty_pb2.Empty]') -> None:
|
|
600
604
|
pass
|
|
601
605
|
|
|
606
|
+
@abc.abstractmethod
|
|
607
|
+
async def SandboxContainerCreateV2(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxContainerCreateV2Request, modal_proto.api_pb2.SandboxContainerCreateV2Response]') -> None:
|
|
608
|
+
pass
|
|
609
|
+
|
|
602
610
|
@abc.abstractmethod
|
|
603
611
|
async def SandboxCreate(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.SandboxCreateRequest, modal_proto.api_pb2.SandboxCreateResponse]') -> None:
|
|
604
612
|
pass
|
|
@@ -1577,6 +1585,12 @@ class ModalClientBase(abc.ABC):
|
|
|
1577
1585
|
modal_proto.api_pb2.FunctionGetRequest,
|
|
1578
1586
|
modal_proto.api_pb2.FunctionGetResponse,
|
|
1579
1587
|
),
|
|
1588
|
+
'/modal.client.ModalClient/FunctionGetById': grpclib.const.Handler(
|
|
1589
|
+
self.FunctionGetById,
|
|
1590
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
|
1591
|
+
modal_proto.api_pb2.FunctionGetByIdRequest,
|
|
1592
|
+
modal_proto.api_pb2.FunctionGetByIdResponse,
|
|
1593
|
+
),
|
|
1580
1594
|
'/modal.client.ModalClient/FunctionGetCallGraph': grpclib.const.Handler(
|
|
1581
1595
|
self.FunctionGetCallGraph,
|
|
1582
1596
|
grpclib.const.Cardinality.UNARY_UNARY,
|
|
@@ -1859,6 +1873,12 @@ class ModalClientBase(abc.ABC):
|
|
|
1859
1873
|
modal_proto.api_pb2.QueuePutRequest,
|
|
1860
1874
|
google.protobuf.empty_pb2.Empty,
|
|
1861
1875
|
),
|
|
1876
|
+
'/modal.client.ModalClient/SandboxContainerCreateV2': grpclib.const.Handler(
|
|
1877
|
+
self.SandboxContainerCreateV2,
|
|
1878
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
|
1879
|
+
modal_proto.api_pb2.SandboxContainerCreateV2Request,
|
|
1880
|
+
modal_proto.api_pb2.SandboxContainerCreateV2Response,
|
|
1881
|
+
),
|
|
1862
1882
|
'/modal.client.ModalClient/SandboxCreate': grpclib.const.Handler(
|
|
1863
1883
|
self.SandboxCreate,
|
|
1864
1884
|
grpclib.const.Cardinality.UNARY_UNARY,
|
|
@@ -3035,6 +3055,12 @@ class ModalClientStub:
|
|
|
3035
3055
|
modal_proto.api_pb2.FunctionGetRequest,
|
|
3036
3056
|
modal_proto.api_pb2.FunctionGetResponse,
|
|
3037
3057
|
)
|
|
3058
|
+
self.FunctionGetById = grpclib.client.UnaryUnaryMethod(
|
|
3059
|
+
channel,
|
|
3060
|
+
'/modal.client.ModalClient/FunctionGetById',
|
|
3061
|
+
modal_proto.api_pb2.FunctionGetByIdRequest,
|
|
3062
|
+
modal_proto.api_pb2.FunctionGetByIdResponse,
|
|
3063
|
+
)
|
|
3038
3064
|
self.FunctionGetCallGraph = grpclib.client.UnaryUnaryMethod(
|
|
3039
3065
|
channel,
|
|
3040
3066
|
'/modal.client.ModalClient/FunctionGetCallGraph',
|
|
@@ -3317,6 +3343,12 @@ class ModalClientStub:
|
|
|
3317
3343
|
modal_proto.api_pb2.QueuePutRequest,
|
|
3318
3344
|
google.protobuf.empty_pb2.Empty,
|
|
3319
3345
|
)
|
|
3346
|
+
self.SandboxContainerCreateV2 = grpclib.client.UnaryUnaryMethod(
|
|
3347
|
+
channel,
|
|
3348
|
+
'/modal.client.ModalClient/SandboxContainerCreateV2',
|
|
3349
|
+
modal_proto.api_pb2.SandboxContainerCreateV2Request,
|
|
3350
|
+
modal_proto.api_pb2.SandboxContainerCreateV2Response,
|
|
3351
|
+
)
|
|
3320
3352
|
self.SandboxCreate = grpclib.client.UnaryUnaryMethod(
|
|
3321
3353
|
channel,
|
|
3322
3354
|
'/modal.client.ModalClient/SandboxCreate',
|