modal 1.6.2.dev3__tar.gz → 1.6.2.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.6.2.dev3 → modal-1.6.2.dev4}/PKG-INFO +1 -1
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_functions.py +2 -2
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/container.py +2 -1
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/shell.py +3 -1
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/client.pyi +2 -2
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/experimental/__init__.py +66 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/functions.pyi +6 -6
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/runner.py +1 -1
- modal-1.6.2.dev4/modal/sandbox/__init__.py +9 -0
- modal-1.6.2.dev3/modal/sandbox.py → modal-1.6.2.dev4/modal/sandbox/_sandbox.py +38 -53
- modal-1.6.2.dev4/modal/sandbox/sandbox.py +9 -0
- {modal-1.6.2.dev3/modal → modal-1.6.2.dev4/modal/sandbox}/sandbox.pyi +43 -1371
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/sandbox_fs.py +6 -4
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/sandbox_fs.pyi +10 -5
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/secret.py +13 -4
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/secret.pyi +4 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal.egg-info/SOURCES.txt +4 -2
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/api_grpc.py +16 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/api_pb2.py +1275 -1233
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/api_pb2.pyi +96 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/api_pb2_grpc.py +33 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/api_pb2_grpc.pyi +10 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/modal_api_grpc.py +1 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_version/__init__.py +1 -1
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/pyproject.toml +5 -2
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/LICENSE +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/README.md +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/__main__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_billing.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_cluster.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_cluster.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_container_entrypoint.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_environments.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_function_variants.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_grpc_client.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_image.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_ipython.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_load_context.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_location.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_logs.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_logs_manager.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_logs_manager.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_object.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_outbound_policy.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_outbound_policy.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_output/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_output/manager.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_output/pty.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_output/rich.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_output/status.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_partial_function.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_resolver.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_resources.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/asgi.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/execution_context.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/telemetry.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_serialization.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_server.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_server.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_supports_logs.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_traceback.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_tunnel.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_tunnel.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_type_manager.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/app_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/async_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/blob_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/browser_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/curl_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/deprecation.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/display_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/docker_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/function_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/git_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/hash_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/http_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/idle_countdown.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/logger.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/mount_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/name_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/package_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/proxy_support.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/shell_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_utils/time_utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_vendor/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_vendor/tblib.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_vendor/version.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_watcher.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/_workspace.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/app.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/app.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/billing.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/billing.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/builder/2023.12.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/builder/2024.04.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/builder/2024.10.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/builder/2025.06.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/builder/README.md +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/builder/base-images.json +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/call_graph.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/_download.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/_help.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/_logs.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/_stats.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/_traceback.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/app.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/billing.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/changelog.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/config.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/curl.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/dashboard.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/dict.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/endpoint.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/entry_point.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/environment.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/function.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/image.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/import_refs.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/logo.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/network_file_system.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/profile.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/queues.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/run.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/secret.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/selector.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/server.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/skills.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/token.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/utils.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/volume.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cli/workspace.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/client.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cls.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cls.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cluster.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/cluster.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/config.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/container_process.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/container_process.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/dict.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/dict.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/environments.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/environments.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/exception.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/experimental/_flash_container_entry.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/experimental/flash.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/experimental/flash.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/experimental/flash_server.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/experimental/flash_server.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/experimental/ipython.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/file_pattern_matcher.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/functions.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/image.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/image.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/io_streams.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/io_streams.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/mount.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/mount.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/network_file_system.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/network_file_system.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/object.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/object.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/output.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/parallel_map.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/parallel_map.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/partial_function.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/partial_function.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/proxy.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/proxy.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/py.typed +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/queue.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/queue.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/retries.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/runner.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/running_app.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/schedule.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/scheduler_placement.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/server.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/server.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/serving.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/serving.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/snapshot.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/snapshot.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/stream_type.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/token_flow.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/token_flow.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/types.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/volume.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/volume.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/workspace.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal/workspace.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal.egg-info/requires.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal.egg-info/top_level.txt +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/mdmd/types.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_docs/reference_intro.md +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/__init__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/py.typed +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/modal_version/__main__.py +0 -0
- {modal-1.6.2.dev3 → modal-1.6.2.dev4}/setup.cfg +0 -0
|
@@ -819,8 +819,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
819
819
|
raise InvalidError(
|
|
820
820
|
f"`min_containers` ({min_containers}) cannot be greater than `max_containers` ({max_containers})"
|
|
821
821
|
)
|
|
822
|
-
if scaledown_window is not None and scaledown_window <=
|
|
823
|
-
raise InvalidError("`scaledown_window` must be
|
|
822
|
+
if scaledown_window is not None and not (2 <= scaledown_window <= 3600):
|
|
823
|
+
raise InvalidError("`scaledown_window` must be between 2 and 3600 (inclusive)")
|
|
824
824
|
|
|
825
825
|
autoscaler_settings = api_pb2.AutoscalerSettings(
|
|
826
826
|
min_containers=min_containers,
|
|
@@ -27,7 +27,8 @@ from modal.cli.utils import (
|
|
|
27
27
|
)
|
|
28
28
|
from modal.client import _Client
|
|
29
29
|
from modal.exception import ConflictError, InvalidError
|
|
30
|
-
from modal.sandbox import SandboxVersion,
|
|
30
|
+
from modal.sandbox._sandbox import SandboxVersion, _get_sandbox_version, _Sandbox
|
|
31
|
+
from modal.sandbox.sandbox import _container_exec
|
|
31
32
|
from modal_proto import api_pb2
|
|
32
33
|
|
|
33
34
|
from ._help import ModalGroup
|
|
@@ -17,7 +17,9 @@ from ..functions import Function
|
|
|
17
17
|
from ..image import Image
|
|
18
18
|
from ..mount import _Mount
|
|
19
19
|
from ..runner import interactive_shell
|
|
20
|
-
from ..sandbox import
|
|
20
|
+
from ..sandbox import Sandbox
|
|
21
|
+
from ..sandbox._sandbox import _MAIN_CONTAINER_NAME, SandboxVersion, _get_sandbox_version
|
|
22
|
+
from ..sandbox.sandbox import _container_exec
|
|
21
23
|
from ..secret import Secret
|
|
22
24
|
from ..stream_type import StreamType
|
|
23
25
|
from ..types import SandboxRuntime
|
|
@@ -80,7 +80,7 @@ class _Client:
|
|
|
80
80
|
server_url: str,
|
|
81
81
|
client_type: int,
|
|
82
82
|
credentials: typing.Optional[tuple[str, str]],
|
|
83
|
-
version: str = "1.6.2.
|
|
83
|
+
version: str = "1.6.2.dev4",
|
|
84
84
|
*,
|
|
85
85
|
oauth_credentials: typing.Optional[_OAuthCredentials] = None,
|
|
86
86
|
):
|
|
@@ -290,7 +290,7 @@ class Client:
|
|
|
290
290
|
server_url: str,
|
|
291
291
|
client_type: int,
|
|
292
292
|
credentials: typing.Optional[tuple[str, str]],
|
|
293
|
-
version: str = "1.6.2.
|
|
293
|
+
version: str = "1.6.2.dev4",
|
|
294
294
|
*,
|
|
295
295
|
oauth_credentials: typing.Optional[_OAuthCredentials] = None,
|
|
296
296
|
):
|
|
@@ -93,6 +93,72 @@ def clustered(size: int, broadcast: bool = True, rdma: bool = False, fabric_size
|
|
|
93
93
|
return wrapper
|
|
94
94
|
|
|
95
95
|
|
|
96
|
+
@dataclass
|
|
97
|
+
class ClusterReservationTask:
|
|
98
|
+
"""A container running on a worker that belongs to a cluster reservation."""
|
|
99
|
+
|
|
100
|
+
task_id: str
|
|
101
|
+
cluster_rank: int
|
|
102
|
+
app_id: str
|
|
103
|
+
function_id: str
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@dataclass
|
|
107
|
+
class ClusterReservation:
|
|
108
|
+
"""Current state of reserved multi-node cluster capacity in a Workspace."""
|
|
109
|
+
|
|
110
|
+
name: str # Reservation name, as configured by Modal
|
|
111
|
+
gpu_type: str # e.g. "B300"
|
|
112
|
+
region: str
|
|
113
|
+
min_reserved_workers: int # Number of workers Modal has committed to keep reserved
|
|
114
|
+
reserved_workers: int # Healthy reserved workers currently present (active + idle)
|
|
115
|
+
active_workers: int # Reserved workers running this Workspace's containers
|
|
116
|
+
idle_workers: int # Reserved workers available for new clusters
|
|
117
|
+
unfulfilled_workers: int # max(0, min_reserved_workers - reserved_workers)
|
|
118
|
+
tasks: list[ClusterReservationTask] # Containers on reserved workers, ordered by cluster then rank
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@synchronizer.create_blocking
|
|
122
|
+
async def list_cluster_reservations(*, client: _Client | None = None) -> list[ClusterReservation]:
|
|
123
|
+
"""List reserved multi-node cluster capacity for the current Workspace.
|
|
124
|
+
|
|
125
|
+
Returns one entry per reservation Modal has configured for the Workspace, with how many of the
|
|
126
|
+
reserved workers are currently present, in use, idle or missing. Only Workspaces with reserved
|
|
127
|
+
cluster capacity (or explicitly allowlisted by Modal) may call this; others get a
|
|
128
|
+
`modal.exception.PermissionDeniedError`.
|
|
129
|
+
|
|
130
|
+
This interface is experimental. This information will continue to be available in the future,
|
|
131
|
+
but it may be accessed via a different interface, and the return value may have a different shape.
|
|
132
|
+
"""
|
|
133
|
+
client = client or await _Client.from_env()
|
|
134
|
+
|
|
135
|
+
resp: api_pb2.ClusterReservationListResponse = await client._stub.ClusterReservationList(
|
|
136
|
+
api_pb2.ClusterReservationListRequest()
|
|
137
|
+
)
|
|
138
|
+
return [
|
|
139
|
+
ClusterReservation(
|
|
140
|
+
name=reservation.name,
|
|
141
|
+
gpu_type=reservation.gpu_type,
|
|
142
|
+
region=reservation.region,
|
|
143
|
+
min_reserved_workers=reservation.min_reserved_workers,
|
|
144
|
+
reserved_workers=reservation.reserved_workers,
|
|
145
|
+
active_workers=reservation.active_workers,
|
|
146
|
+
idle_workers=reservation.idle_workers,
|
|
147
|
+
unfulfilled_workers=reservation.unfulfilled_workers,
|
|
148
|
+
tasks=[
|
|
149
|
+
ClusterReservationTask(
|
|
150
|
+
task_id=task.task_id,
|
|
151
|
+
cluster_rank=task.cluster_rank,
|
|
152
|
+
app_id=task.app_id,
|
|
153
|
+
function_id=task.function_id,
|
|
154
|
+
)
|
|
155
|
+
for task in reservation.tasks
|
|
156
|
+
],
|
|
157
|
+
)
|
|
158
|
+
for reservation in resp.reservations
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
|
|
96
162
|
@dataclass
|
|
97
163
|
class AppInfo:
|
|
98
164
|
app_id: str
|
|
@@ -613,7 +613,7 @@ class Function(
|
|
|
613
613
|
|
|
614
614
|
_call_generator: ___call_generator_spec
|
|
615
615
|
|
|
616
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
616
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
617
617
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
618
618
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result.
|
|
619
619
|
|
|
@@ -638,7 +638,7 @@ class Function(
|
|
|
638
638
|
"""
|
|
639
639
|
...
|
|
640
640
|
|
|
641
|
-
remote: __remote_spec[modal._functions.
|
|
641
|
+
remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
|
|
642
642
|
|
|
643
643
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
644
644
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -688,7 +688,7 @@ class Function(
|
|
|
688
688
|
"""
|
|
689
689
|
...
|
|
690
690
|
|
|
691
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
691
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
692
692
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
693
693
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
694
694
|
|
|
@@ -721,7 +721,7 @@ class Function(
|
|
|
721
721
|
"""
|
|
722
722
|
...
|
|
723
723
|
|
|
724
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
724
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
725
725
|
|
|
726
726
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
727
727
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -729,7 +729,7 @@ class Function(
|
|
|
729
729
|
|
|
730
730
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
731
731
|
|
|
732
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
732
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
733
733
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
734
734
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
735
735
|
|
|
@@ -762,7 +762,7 @@ class Function(
|
|
|
762
762
|
"""
|
|
763
763
|
...
|
|
764
764
|
|
|
765
|
-
spawn: __spawn_spec[modal._functions.
|
|
765
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
766
766
|
|
|
767
767
|
@property
|
|
768
768
|
def _raw_f_(self) -> collections.abc.Callable[..., typing.Any]: ...
|
|
@@ -43,7 +43,7 @@ from .exception import (
|
|
|
43
43
|
)
|
|
44
44
|
from .output import OutputManager
|
|
45
45
|
from .running_app import RunningApp, running_app_from_layout
|
|
46
|
-
from .sandbox import _Sandbox
|
|
46
|
+
from .sandbox._sandbox import _Sandbox
|
|
47
47
|
from .secret import _Secret
|
|
48
48
|
from .stream_type import StreamType
|
|
49
49
|
|
|
@@ -23,31 +23,31 @@ from modal._supports_logs import LogsFilters, _LogQueryData
|
|
|
23
23
|
from modal._tunnel import Tunnel
|
|
24
24
|
from modal.cloud_bucket_mount import _CloudBucketMount, cloud_bucket_mounts_to_proto
|
|
25
25
|
from modal.mount import _Mount
|
|
26
|
-
from modal.secret import _local_secret_env, _resolvable_secrets
|
|
26
|
+
from modal.secret import _local_secret_env, _resolvable_secrets, _secret_sources
|
|
27
27
|
from modal.volume import _Volume, _volume_to_mount_proto
|
|
28
28
|
from modal_proto import api_pb2, task_command_router_pb2 as sr_pb2
|
|
29
29
|
|
|
30
|
-
from
|
|
31
|
-
from
|
|
32
|
-
from
|
|
33
|
-
from
|
|
34
|
-
from
|
|
35
|
-
from
|
|
36
|
-
from
|
|
37
|
-
from
|
|
38
|
-
from
|
|
39
|
-
from
|
|
40
|
-
from
|
|
30
|
+
from .._image import _Image
|
|
31
|
+
from .._load_context import LoadContext
|
|
32
|
+
from .._object import _get_environment_name, _Object
|
|
33
|
+
from .._outbound_policy import _OutboundPolicy, _validate_compatible_network_access
|
|
34
|
+
from .._output.pty import get_pty_info
|
|
35
|
+
from .._resolver import Resolver
|
|
36
|
+
from .._resources import convert_fn_config_to_resources_config
|
|
37
|
+
from .._utils.async_utils import TaskContext
|
|
38
|
+
from .._utils.deprecation import deprecation_warning
|
|
39
|
+
from .._utils.grpc_utils import Retry, RetryTimeoutError
|
|
40
|
+
from .._utils.mount_utils import (
|
|
41
41
|
validate_network_file_systems,
|
|
42
42
|
validate_volumes,
|
|
43
43
|
validate_volumes_by_object_id,
|
|
44
44
|
)
|
|
45
|
-
from
|
|
46
|
-
from
|
|
47
|
-
from
|
|
48
|
-
from
|
|
49
|
-
from
|
|
50
|
-
from
|
|
45
|
+
from .._utils.name_utils import check_object_name
|
|
46
|
+
from .._utils.task_command_router_client import TaskCommandRouterClient, _is_v2_task_id
|
|
47
|
+
from ..client import _Client
|
|
48
|
+
from ..config import config, logger
|
|
49
|
+
from ..container_process import _ContainerProcess
|
|
50
|
+
from ..exception import (
|
|
51
51
|
ClientClosed,
|
|
52
52
|
ConflictError,
|
|
53
53
|
ExecutionError,
|
|
@@ -61,7 +61,7 @@ from .exception import (
|
|
|
61
61
|
SnapshotCreationError,
|
|
62
62
|
TimeoutError,
|
|
63
63
|
)
|
|
64
|
-
from
|
|
64
|
+
from ..io_streams import (
|
|
65
65
|
StreamReader,
|
|
66
66
|
StreamWriter,
|
|
67
67
|
_StreamReader,
|
|
@@ -71,13 +71,13 @@ from .io_streams import (
|
|
|
71
71
|
_StreamWriterThroughCommandRouterSandboxParams,
|
|
72
72
|
_StreamWriterThroughServerParams,
|
|
73
73
|
)
|
|
74
|
-
from
|
|
75
|
-
from
|
|
76
|
-
from
|
|
77
|
-
from
|
|
78
|
-
from
|
|
79
|
-
from
|
|
80
|
-
from
|
|
74
|
+
from ..network_file_system import _NetworkFileSystem, network_file_system_mount_protos
|
|
75
|
+
from ..proxy import _Proxy
|
|
76
|
+
from ..sandbox_fs import _SandboxFilesystem
|
|
77
|
+
from ..secret import _Secret
|
|
78
|
+
from ..snapshot import _SandboxSnapshot
|
|
79
|
+
from ..stream_type import StreamType
|
|
80
|
+
from ..types import SandboxConnectCredentials, SandboxRuntime
|
|
81
81
|
|
|
82
82
|
_default_image: _Image = _Image.debian_slim()
|
|
83
83
|
_EXIT_SNAPSHOT_NOT_FOUND_ERROR_CODES = frozenset(
|
|
@@ -307,11 +307,11 @@ class DefaultSandboxNameOverride(str):
|
|
|
307
307
|
"""
|
|
308
308
|
|
|
309
309
|
def __repr__(self) -> str:
|
|
310
|
-
# NOTE: this must match the instance var name below in order for type stubs to work 😬
|
|
311
|
-
return "_DEFAULT_SANDBOX_NAME_OVERRIDE"
|
|
310
|
+
# NOTE: this must match the qualified instance var name below in order for type stubs to work 😬
|
|
311
|
+
return "modal.sandbox._sandbox._DEFAULT_SANDBOX_NAME_OVERRIDE"
|
|
312
312
|
|
|
313
313
|
|
|
314
|
-
_DEFAULT_SANDBOX_NAME_OVERRIDE = DefaultSandboxNameOverride()
|
|
314
|
+
_DEFAULT_SANDBOX_NAME_OVERRIDE: DefaultSandboxNameOverride = DefaultSandboxNameOverride()
|
|
315
315
|
|
|
316
316
|
|
|
317
317
|
@dataclass(frozen=True)
|
|
@@ -386,7 +386,7 @@ def _resolve_app_id_and_client(
|
|
|
386
386
|
client: "_Client | None",
|
|
387
387
|
) -> "tuple[str | None, _Client | None]":
|
|
388
388
|
"""Resolve the App id and client for Sandbox creation, validating that an App is available."""
|
|
389
|
-
from
|
|
389
|
+
from ..app import _App
|
|
390
390
|
|
|
391
391
|
if app is not None:
|
|
392
392
|
if app.app_id is None:
|
|
@@ -1116,9 +1116,6 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
1116
1116
|
dep_tasks.append(resolver.load(proxy, load_context))
|
|
1117
1117
|
dep_timings = await _gather_load_with_timings(dep_tasks) if dep_tasks else []
|
|
1118
1118
|
|
|
1119
|
-
# `env` takes precedence over environment variables from secrets
|
|
1120
|
-
env_dict = _local_secret_env(secrets) | ephemeral_env
|
|
1121
|
-
|
|
1122
1119
|
validate_volumes_by_object_id(validated_volumes)
|
|
1123
1120
|
|
|
1124
1121
|
volume_mounts = [_volume_to_mount_proto(path, volume) for path, volume in validated_volumes]
|
|
@@ -1165,7 +1162,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
1165
1162
|
create_req = api_pb2.SandboxCreateV2Request(
|
|
1166
1163
|
app_id=load_context.app_id,
|
|
1167
1164
|
definition=definition,
|
|
1168
|
-
|
|
1165
|
+
secret_sources=_secret_sources(secrets, ephemeral_env),
|
|
1169
1166
|
tags=tag_protos,
|
|
1170
1167
|
cloud_bucket_mount_credentials=cloud_bucket_credientials,
|
|
1171
1168
|
)
|
|
@@ -2306,8 +2303,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
2306
2303
|
secret_coros = [secret.hydrate(client=self._client) for secret in resolvable_secrets]
|
|
2307
2304
|
await TaskContext.gather(*secret_coros)
|
|
2308
2305
|
|
|
2309
|
-
env_dict =
|
|
2310
|
-
env_dict |= {k: v for k, v in (env or {}).items() if v is not None}
|
|
2306
|
+
env_dict = {k: v for k, v in (env or {}).items() if v is not None}
|
|
2311
2307
|
|
|
2312
2308
|
task_id = await self._get_task_id(raise_if_task_complete=True)
|
|
2313
2309
|
|
|
@@ -2324,8 +2320,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
2324
2320
|
stderr=stderr,
|
|
2325
2321
|
timeout=timeout,
|
|
2326
2322
|
workdir=workdir,
|
|
2327
|
-
|
|
2328
|
-
env=env_dict,
|
|
2323
|
+
secret_sources=_secret_sources(secrets, env_dict),
|
|
2329
2324
|
text=text,
|
|
2330
2325
|
bufsize=bufsize,
|
|
2331
2326
|
runtime_debug=config.get("function_runtime_debug"),
|
|
@@ -2342,8 +2337,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
2342
2337
|
stderr: StreamType = StreamType.PIPE,
|
|
2343
2338
|
timeout: int | None = None,
|
|
2344
2339
|
workdir: str | None = None,
|
|
2345
|
-
|
|
2346
|
-
env: dict[str, str] | None = None,
|
|
2340
|
+
secret_sources: Collection[api_pb2.SecretSource] | None = None,
|
|
2347
2341
|
text: bool = True,
|
|
2348
2342
|
bufsize: Literal[-1, 1] = -1,
|
|
2349
2343
|
runtime_debug: bool = False,
|
|
@@ -2382,11 +2376,10 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
2382
2376
|
stderr_config=stderr_config,
|
|
2383
2377
|
timeout_secs=timeout,
|
|
2384
2378
|
workdir=workdir,
|
|
2385
|
-
|
|
2379
|
+
secret_sources=secret_sources,
|
|
2386
2380
|
pty_info=pty_info,
|
|
2387
2381
|
runtime_debug=runtime_debug,
|
|
2388
2382
|
container_id=container_id or "",
|
|
2389
|
-
env=env or {},
|
|
2390
2383
|
)
|
|
2391
2384
|
_ = await command_router_client.exec_start(start_req)
|
|
2392
2385
|
|
|
@@ -3233,8 +3226,7 @@ class _SidecarManager:
|
|
|
3233
3226
|
*(resolver.load(dependency, load_context) for dependency in dependencies if not dependency._is_hydrated)
|
|
3234
3227
|
)
|
|
3235
3228
|
|
|
3236
|
-
|
|
3237
|
-
env_dict = _local_secret_env(secrets) | (env or {})
|
|
3229
|
+
secret_sources = _secret_sources(secrets, env)
|
|
3238
3230
|
|
|
3239
3231
|
# Validate that the same volume (by object_id) isn't mounted at multiple paths. This relies on
|
|
3240
3232
|
# the volumes being hydrated above, since it compares object_ids.
|
|
@@ -3271,7 +3263,7 @@ class _SidecarManager:
|
|
|
3271
3263
|
sandbox_id=self._sandbox.object_id,
|
|
3272
3264
|
container_name=name,
|
|
3273
3265
|
definition=definition,
|
|
3274
|
-
|
|
3266
|
+
secret_sources=secret_sources,
|
|
3275
3267
|
cloud_bucket_mount_credentials=cloud_bucket_credentials,
|
|
3276
3268
|
)
|
|
3277
3269
|
client = self._sandbox._client
|
|
@@ -3286,9 +3278,8 @@ class _SidecarManager:
|
|
|
3286
3278
|
container_name=name,
|
|
3287
3279
|
image_id=image.object_id,
|
|
3288
3280
|
args=list(args),
|
|
3289
|
-
env=env_dict,
|
|
3290
3281
|
workdir=workdir or "",
|
|
3291
|
-
|
|
3282
|
+
secret_sources=secret_sources,
|
|
3292
3283
|
volume_mounts=volume_mounts,
|
|
3293
3284
|
network_access=network_access,
|
|
3294
3285
|
pty_info=pty_info,
|
|
@@ -3328,7 +3319,6 @@ class _SidecarManager:
|
|
|
3328
3319
|
]
|
|
3329
3320
|
|
|
3330
3321
|
|
|
3331
|
-
@synchronizer.create_blocking
|
|
3332
3322
|
async def _container_exec(
|
|
3333
3323
|
pty: bool,
|
|
3334
3324
|
container_id: str = "",
|
|
@@ -3386,8 +3376,3 @@ async def _container_exec(
|
|
|
3386
3376
|
stdout=StreamType.STDOUT,
|
|
3387
3377
|
stderr=StreamType.STDOUT,
|
|
3388
3378
|
).wait()
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
SidecarContainer = synchronize_api(_SidecarContainer)
|
|
3392
|
-
SidecarManager = synchronize_api(_SidecarManager)
|
|
3393
|
-
Sandbox = synchronize_api(_Sandbox)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright Modal Labs 2026
|
|
2
|
+
from .._utils.async_utils import synchronize_api, synchronizer
|
|
3
|
+
from . import _sandbox
|
|
4
|
+
|
|
5
|
+
SidecarContainer = synchronize_api(_sandbox._SidecarContainer, target_module=__name__)
|
|
6
|
+
SidecarManager = synchronize_api(_sandbox._SidecarManager, target_module=__name__)
|
|
7
|
+
Sandbox = synchronize_api(_sandbox._Sandbox, target_module=__name__)
|
|
8
|
+
|
|
9
|
+
_container_exec = synchronizer.create_blocking(_sandbox._container_exec, "_container_exec", target_module=__name__)
|