modal 1.4.4.dev2__tar.gz → 1.4.4.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.4.4.dev2 → modal-1.4.4.dev4}/PKG-INFO +1 -1
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/task_command_router_client.py +16 -9
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/client.pyi +2 -2
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/sandbox.py +35 -4
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/sandbox.pyi +27 -12
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/volume.py +2 -2
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/volume.pyi +4 -4
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/api_grpc.py +16 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/api_pb2.py +1026 -976
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/api_pb2.pyi +94 -6
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/api_pb2_grpc.py +33 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/api_pb2_grpc.pyi +10 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/modal_api_grpc.py +1 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_version/__init__.py +1 -1
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/pyproject.toml +13 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/LICENSE +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/README.md +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/__main__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_billing.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_clustered_functions.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_clustered_functions.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_container_entrypoint.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_environments.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_function_variants.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_functions.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_grpc_client.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_ipython.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_load_context.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_location.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_logs.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_object.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_output/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_output/manager.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_output/pty.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_output/rich.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_output/status.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_partial_function.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_resolver.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_resources.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/asgi.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/execution_context.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/telemetry.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_serialization.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_server.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_traceback.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_tunnel.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_tunnel.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_type_manager.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/app_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/async_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/blob_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/browser_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/deprecation.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/docker_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/function_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/git_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/hash_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/http_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/logger.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/mount_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/name_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/package_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/shell_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_utils/time_utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_vendor/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_vendor/tblib.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_vendor/version.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/_watcher.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/app.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/app.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/billing.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/builder/2023.12.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/builder/2024.04.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/builder/2024.10.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/builder/2025.06.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/builder/README.md +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/builder/base-images.json +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/call_graph.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/_download.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/_help.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/_traceback.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/app.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/billing.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/bootstrap.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/changelog.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/cluster.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/config.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/container.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/dashboard.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/dict.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/entry_point.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/environment.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/import_refs.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/launch.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/logo.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/network_file_system.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/profile.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/programs/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/programs/vscode.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/queues.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/run.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/secret.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/selector.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/shell.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/token.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/utils.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cli/volume.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/client.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cls.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/cls.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/config.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/container_process.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/container_process.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/dict.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/dict.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/environments.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/environments.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/exception.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/experimental/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/experimental/flash.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/experimental/flash.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/experimental/ipython.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/file_io.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/file_io.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/file_pattern_matcher.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/functions.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/functions.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/image.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/image.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/io_streams.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/io_streams.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/mount.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/mount.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/network_file_system.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/network_file_system.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/object.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/object.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/output.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/parallel_map.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/parallel_map.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/partial_function.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/partial_function.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/proxy.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/proxy.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/py.typed +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/queue.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/queue.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/retries.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/runner.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/runner.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/running_app.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/sandbox_fs.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/sandbox_fs.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/schedule.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/scheduler_placement.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/secret.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/secret.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/server.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/server.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/serving.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/serving.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/snapshot.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/snapshot.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/stream_type.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/token_flow.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal/token_flow.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal.egg-info/requires.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal.egg-info/top_level.txt +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_docs/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/__init__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/py.typed +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/modal_version/__main__.py +0 -0
- {modal-1.4.4.dev2 → modal-1.4.4.dev4}/setup.cfg +0 -0
|
@@ -193,18 +193,25 @@ class TaskCommandRouterClient:
|
|
|
193
193
|
) -> "TaskCommandRouterClient":
|
|
194
194
|
"""Build a connected client from a jwt and url."""
|
|
195
195
|
o = urllib.parse.urlparse(url)
|
|
196
|
-
|
|
196
|
+
is_localhost_client = server_client._is_localhost
|
|
197
|
+
if o.scheme == "http":
|
|
198
|
+
# plain http serving should only be used for unit tests
|
|
199
|
+
if not is_localhost_client:
|
|
200
|
+
raise ValueError(f"Task router URL must be https, got: {url}")
|
|
201
|
+
ssl_context = None
|
|
202
|
+
elif o.scheme == "https":
|
|
203
|
+
ssl_context = ssl.create_default_context()
|
|
204
|
+
if is_localhost_client:
|
|
205
|
+
# Allow insecure TLS when the Modal server client points to localhost
|
|
206
|
+
# This is typically triggered from local e2e testing
|
|
207
|
+
logger.warning("Using insecure TLS for task command router because server client points to localhost")
|
|
208
|
+
ssl_context.check_hostname = False
|
|
209
|
+
ssl_context.verify_mode = ssl.CERT_NONE
|
|
210
|
+
else:
|
|
197
211
|
raise ValueError(f"Task router URL must be https, got: {url}")
|
|
198
212
|
|
|
199
213
|
host, _, port_str = o.netloc.partition(":")
|
|
200
|
-
port = int(port_str) if port_str else 443
|
|
201
|
-
ssl_context = ssl.create_default_context()
|
|
202
|
-
|
|
203
|
-
# Allow insecure TLS when explicitly enabled via config.
|
|
204
|
-
if server_client._is_localhost:
|
|
205
|
-
logger.warning("Using insecure TLS for task command router because server client points to localhost")
|
|
206
|
-
ssl_context.check_hostname = False
|
|
207
|
-
ssl_context.verify_mode = ssl.CERT_NONE
|
|
214
|
+
port = int(port_str) if port_str else (443 if o.scheme == "https" else 80)
|
|
208
215
|
|
|
209
216
|
channel = PermanentCloseableChannel(
|
|
210
217
|
host,
|
|
@@ -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.4.4.
|
|
38
|
+
version: str = "1.4.4.dev4",
|
|
39
39
|
):
|
|
40
40
|
"""mdmd:hidden
|
|
41
41
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -175,7 +175,7 @@ class Client:
|
|
|
175
175
|
server_url: str,
|
|
176
176
|
client_type: int,
|
|
177
177
|
credentials: typing.Optional[tuple[str, str]],
|
|
178
|
-
version: str = "1.4.4.
|
|
178
|
+
version: str = "1.4.4.dev4",
|
|
179
179
|
):
|
|
180
180
|
"""mdmd:hidden
|
|
181
181
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -696,6 +696,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
696
696
|
block_network: bool = False,
|
|
697
697
|
cidr_allowlist: Optional[Sequence[str]] = None,
|
|
698
698
|
inbound_cidr_allowlist: Optional[Sequence[str]] = None,
|
|
699
|
+
volumes: dict[Union[str, os.PathLike], Union[_Volume, _CloudBucketMount]] = {},
|
|
699
700
|
pty: bool = False,
|
|
700
701
|
encrypted_ports: Sequence[int] = [],
|
|
701
702
|
h2_ports: Sequence[int] = [],
|
|
@@ -707,11 +708,12 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
707
708
|
"""Create a sandbox using the V2 backend.
|
|
708
709
|
|
|
709
710
|
Supported features include exec, encrypted tunnels, wait/poll/terminate,
|
|
710
|
-
CPU and memory configuration, region placement,
|
|
711
|
-
and filesystem snapshots.
|
|
711
|
+
CPU and memory configuration, region placement, volumes, cloud bucket mounts
|
|
712
|
+
(with static credentials via `secret=...`), and filesystem snapshots.
|
|
712
713
|
|
|
713
|
-
Features like tags, memory snapshots,
|
|
714
|
-
|
|
714
|
+
Features like tags, memory snapshots, network file systems, GPUs, custom
|
|
715
|
+
domains, OIDC identity tokens (including `oidc_auth_role_arn` on a
|
|
716
|
+
CloudBucketMount), and proxies are not supported.
|
|
715
717
|
|
|
716
718
|
V2 sandboxes created with this method are not currently returned by
|
|
717
719
|
`Sandbox.list()` and cannot be looked up with `Sandbox.from_name()`.
|
|
@@ -730,6 +732,24 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
730
732
|
if block_network and (encrypted_ports or h2_ports or unencrypted_ports):
|
|
731
733
|
raise InvalidError("Cannot specify open ports when `block_network` is enabled")
|
|
732
734
|
|
|
735
|
+
validated_volumes = validate_volumes(volumes)
|
|
736
|
+
cloud_bucket_mounts = [(k, v) for k, v in validated_volumes if isinstance(v, _CloudBucketMount)]
|
|
737
|
+
validated_volumes = [(k, v) for k, v in validated_volumes if isinstance(v, _Volume)]
|
|
738
|
+
|
|
739
|
+
# The V2 backend does not yet propagate `oidc_identity_token` from server to worker - it is silently dropped
|
|
740
|
+
# TODO(akshay) add support for OIDC tokens
|
|
741
|
+
if include_oidc_identity_token:
|
|
742
|
+
raise InvalidError(
|
|
743
|
+
"Sandbox._experimental_create does not support include_oidc_identity_token=True. "
|
|
744
|
+
"Use Sandbox.create instead."
|
|
745
|
+
)
|
|
746
|
+
for path, cbm in cloud_bucket_mounts:
|
|
747
|
+
if cbm.oidc_auth_role_arn:
|
|
748
|
+
raise InvalidError(
|
|
749
|
+
"Sandbox._experimental_create does not support CloudBucketMount with oidc_auth_role_arn "
|
|
750
|
+
f"(at mount path {path!r}). Use static credentials via `secret=...`, or use Sandbox.create."
|
|
751
|
+
)
|
|
752
|
+
|
|
733
753
|
secrets = secrets or []
|
|
734
754
|
if env:
|
|
735
755
|
secrets = [*secrets, _Secret.from_dict(env)]
|
|
@@ -777,9 +797,18 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
777
797
|
dep_tasks.append(resolver.load(image, load_context))
|
|
778
798
|
for secret in secrets:
|
|
779
799
|
dep_tasks.append(resolver.load(secret, load_context))
|
|
800
|
+
for _, vol in validated_volumes:
|
|
801
|
+
dep_tasks.append(resolver.load(vol, load_context))
|
|
802
|
+
for _, cloud_bucket_mount in cloud_bucket_mounts:
|
|
803
|
+
if cloud_bucket_mount.secret:
|
|
804
|
+
dep_tasks.append(resolver.load(cloud_bucket_mount.secret, load_context))
|
|
780
805
|
if dep_tasks:
|
|
781
806
|
await asyncio.gather(*dep_tasks)
|
|
782
807
|
|
|
808
|
+
validate_volumes_by_object_id(validated_volumes)
|
|
809
|
+
|
|
810
|
+
volume_mounts = [_volume_to_mount_proto(path, volume) for path, volume in validated_volumes]
|
|
811
|
+
|
|
783
812
|
definition = api_pb2.Sandbox(
|
|
784
813
|
entrypoint_args=args,
|
|
785
814
|
image_id=image.object_id,
|
|
@@ -801,6 +830,8 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
801
830
|
name=name,
|
|
802
831
|
include_oidc_identity_token=include_oidc_identity_token,
|
|
803
832
|
inbound_cidr_allowlist=list(inbound_cidr_allowlist) if inbound_cidr_allowlist is not None else [],
|
|
833
|
+
volume_mounts=volume_mounts,
|
|
834
|
+
cloud_bucket_mounts=cloud_bucket_mounts_to_proto(cloud_bucket_mounts),
|
|
804
835
|
)
|
|
805
836
|
|
|
806
837
|
create_req = api_pb2.SandboxCreateV2Request(app_id=load_context.app_id, definition=definition)
|
|
@@ -325,6 +325,10 @@ class _Sandbox(modal._object._Object):
|
|
|
325
325
|
block_network: bool = False,
|
|
326
326
|
cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
327
327
|
inbound_cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
328
|
+
volumes: dict[
|
|
329
|
+
typing.Union[str, os.PathLike],
|
|
330
|
+
typing.Union[modal.volume._Volume, modal.cloud_bucket_mount._CloudBucketMount],
|
|
331
|
+
] = {},
|
|
328
332
|
pty: bool = False,
|
|
329
333
|
encrypted_ports: collections.abc.Sequence[int] = [],
|
|
330
334
|
h2_ports: collections.abc.Sequence[int] = [],
|
|
@@ -336,11 +340,12 @@ class _Sandbox(modal._object._Object):
|
|
|
336
340
|
"""Create a sandbox using the V2 backend.
|
|
337
341
|
|
|
338
342
|
Supported features include exec, encrypted tunnels, wait/poll/terminate,
|
|
339
|
-
CPU and memory configuration, region placement,
|
|
340
|
-
and filesystem snapshots.
|
|
343
|
+
CPU and memory configuration, region placement, volumes, cloud bucket mounts
|
|
344
|
+
(with static credentials via `secret=...`), and filesystem snapshots.
|
|
341
345
|
|
|
342
|
-
Features like tags, memory snapshots,
|
|
343
|
-
|
|
346
|
+
Features like tags, memory snapshots, network file systems, GPUs, custom
|
|
347
|
+
domains, OIDC identity tokens (including `oidc_auth_role_arn` on a
|
|
348
|
+
CloudBucketMount), and proxies are not supported.
|
|
344
349
|
|
|
345
350
|
V2 sandboxes created with this method are not currently returned by
|
|
346
351
|
`Sandbox.list()` and cannot be looked up with `Sandbox.from_name()`.
|
|
@@ -1216,6 +1221,10 @@ class Sandbox(modal.object.Object):
|
|
|
1216
1221
|
block_network: bool = False,
|
|
1217
1222
|
cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1218
1223
|
inbound_cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1224
|
+
volumes: dict[
|
|
1225
|
+
typing.Union[str, os.PathLike],
|
|
1226
|
+
typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
|
|
1227
|
+
] = {},
|
|
1219
1228
|
pty: bool = False,
|
|
1220
1229
|
encrypted_ports: collections.abc.Sequence[int] = [],
|
|
1221
1230
|
h2_ports: collections.abc.Sequence[int] = [],
|
|
@@ -1227,11 +1236,12 @@ class Sandbox(modal.object.Object):
|
|
|
1227
1236
|
"""Create a sandbox using the V2 backend.
|
|
1228
1237
|
|
|
1229
1238
|
Supported features include exec, encrypted tunnels, wait/poll/terminate,
|
|
1230
|
-
CPU and memory configuration, region placement,
|
|
1231
|
-
and filesystem snapshots.
|
|
1239
|
+
CPU and memory configuration, region placement, volumes, cloud bucket mounts
|
|
1240
|
+
(with static credentials via `secret=...`), and filesystem snapshots.
|
|
1232
1241
|
|
|
1233
|
-
Features like tags, memory snapshots,
|
|
1234
|
-
|
|
1242
|
+
Features like tags, memory snapshots, network file systems, GPUs, custom
|
|
1243
|
+
domains, OIDC identity tokens (including `oidc_auth_role_arn` on a
|
|
1244
|
+
CloudBucketMount), and proxies are not supported.
|
|
1235
1245
|
|
|
1236
1246
|
V2 sandboxes created with this method are not currently returned by
|
|
1237
1247
|
`Sandbox.list()` and cannot be looked up with `Sandbox.from_name()`.
|
|
@@ -1259,6 +1269,10 @@ class Sandbox(modal.object.Object):
|
|
|
1259
1269
|
block_network: bool = False,
|
|
1260
1270
|
cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1261
1271
|
inbound_cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1272
|
+
volumes: dict[
|
|
1273
|
+
typing.Union[str, os.PathLike],
|
|
1274
|
+
typing.Union[modal.volume.Volume, modal.cloud_bucket_mount.CloudBucketMount],
|
|
1275
|
+
] = {},
|
|
1262
1276
|
pty: bool = False,
|
|
1263
1277
|
encrypted_ports: collections.abc.Sequence[int] = [],
|
|
1264
1278
|
h2_ports: collections.abc.Sequence[int] = [],
|
|
@@ -1270,11 +1284,12 @@ class Sandbox(modal.object.Object):
|
|
|
1270
1284
|
"""Create a sandbox using the V2 backend.
|
|
1271
1285
|
|
|
1272
1286
|
Supported features include exec, encrypted tunnels, wait/poll/terminate,
|
|
1273
|
-
CPU and memory configuration, region placement,
|
|
1274
|
-
and filesystem snapshots.
|
|
1287
|
+
CPU and memory configuration, region placement, volumes, cloud bucket mounts
|
|
1288
|
+
(with static credentials via `secret=...`), and filesystem snapshots.
|
|
1275
1289
|
|
|
1276
|
-
Features like tags, memory snapshots,
|
|
1277
|
-
|
|
1290
|
+
Features like tags, memory snapshots, network file systems, GPUs, custom
|
|
1291
|
+
domains, OIDC identity tokens (including `oidc_auth_role_arn` on a
|
|
1292
|
+
CloudBucketMount), and proxies are not supported.
|
|
1278
1293
|
|
|
1279
1294
|
V2 sandboxes created with this method are not currently returned by
|
|
1280
1295
|
`Sandbox.list()` and cannot be looked up with `Sandbox.from_name()`.
|
|
@@ -471,8 +471,8 @@ class _Volume(_Object, type_prefix="vo"):
|
|
|
471
471
|
Note that these options are not properties stored with the Volume itself - they can be individually configured
|
|
472
472
|
for each Volume - container association.
|
|
473
473
|
|
|
474
|
-
read_only
|
|
475
|
-
sub_path
|
|
474
|
+
`read_only`: bool (optional) - set this to True to make the Volume read only from within containers
|
|
475
|
+
`sub_path`: str | PurePosixPath (optional) - only mount this sub_path directory from the Volume.
|
|
476
476
|
If the directory doesn't exist in the Volume, it will be created when the container starts up
|
|
477
477
|
|
|
478
478
|
|
|
@@ -519,8 +519,8 @@ class _Volume(modal._object._Object):
|
|
|
519
519
|
Note that these options are not properties stored with the Volume itself - they can be individually configured
|
|
520
520
|
for each Volume - container association.
|
|
521
521
|
|
|
522
|
-
read_only
|
|
523
|
-
sub_path
|
|
522
|
+
`read_only`: bool (optional) - set this to True to make the Volume read only from within containers
|
|
523
|
+
`sub_path`: str | PurePosixPath (optional) - only mount this sub_path directory from the Volume.
|
|
524
524
|
If the directory doesn't exist in the Volume, it will be created when the container starts up
|
|
525
525
|
|
|
526
526
|
|
|
@@ -879,8 +879,8 @@ class Volume(modal.object.Object):
|
|
|
879
879
|
Note that these options are not properties stored with the Volume itself - they can be individually configured
|
|
880
880
|
for each Volume - container association.
|
|
881
881
|
|
|
882
|
-
read_only
|
|
883
|
-
sub_path
|
|
882
|
+
`read_only`: bool (optional) - set this to True to make the Volume read only from within containers
|
|
883
|
+
`sub_path`: str | PurePosixPath (optional) - only mount this sub_path directory from the Volume.
|
|
884
884
|
If the directory doesn't exist in the Volume, it will be created when the container starts up
|
|
885
885
|
|
|
886
886
|
|
|
@@ -267,6 +267,10 @@ class ModalClientBase(abc.ABC):
|
|
|
267
267
|
async def EndpointList(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.EndpointListRequest, modal_proto.api_pb2.EndpointListResponse]') -> None:
|
|
268
268
|
pass
|
|
269
269
|
|
|
270
|
+
@abc.abstractmethod
|
|
271
|
+
async def EndpointStop(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.EndpointStopRequest, modal_proto.api_pb2.EndpointStopResponse]') -> None:
|
|
272
|
+
pass
|
|
273
|
+
|
|
270
274
|
@abc.abstractmethod
|
|
271
275
|
async def EnvironmentCreate(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.EnvironmentCreateRequest, google.protobuf.empty_pb2.Empty]') -> None:
|
|
272
276
|
pass
|
|
@@ -1193,6 +1197,12 @@ class ModalClientBase(abc.ABC):
|
|
|
1193
1197
|
modal_proto.api_pb2.EndpointListRequest,
|
|
1194
1198
|
modal_proto.api_pb2.EndpointListResponse,
|
|
1195
1199
|
),
|
|
1200
|
+
'/modal.client.ModalClient/EndpointStop': grpclib.const.Handler(
|
|
1201
|
+
self.EndpointStop,
|
|
1202
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
|
1203
|
+
modal_proto.api_pb2.EndpointStopRequest,
|
|
1204
|
+
modal_proto.api_pb2.EndpointStopResponse,
|
|
1205
|
+
),
|
|
1196
1206
|
'/modal.client.ModalClient/EnvironmentCreate': grpclib.const.Handler(
|
|
1197
1207
|
self.EnvironmentCreate,
|
|
1198
1208
|
grpclib.const.Cardinality.UNARY_UNARY,
|
|
@@ -2399,6 +2409,12 @@ class ModalClientStub:
|
|
|
2399
2409
|
modal_proto.api_pb2.EndpointListRequest,
|
|
2400
2410
|
modal_proto.api_pb2.EndpointListResponse,
|
|
2401
2411
|
)
|
|
2412
|
+
self.EndpointStop = grpclib.client.UnaryUnaryMethod(
|
|
2413
|
+
channel,
|
|
2414
|
+
'/modal.client.ModalClient/EndpointStop',
|
|
2415
|
+
modal_proto.api_pb2.EndpointStopRequest,
|
|
2416
|
+
modal_proto.api_pb2.EndpointStopResponse,
|
|
2417
|
+
)
|
|
2402
2418
|
self.EnvironmentCreate = grpclib.client.UnaryUnaryMethod(
|
|
2403
2419
|
channel,
|
|
2404
2420
|
'/modal.client.ModalClient/EnvironmentCreate',
|