modal 1.5.4.dev12__tar.gz → 1.5.4.dev13__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.4.dev12 → modal-1.5.4.dev13}/PKG-INFO +1 -1
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/shell.py +2 -2
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/client.pyi +2 -2
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/functions.pyi +6 -6
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/sandbox.py +49 -37
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/sandbox.pyi +50 -1
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/api_grpc.py +0 -16
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/api_pb2.py +1155 -1185
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/api_pb2.pyi +5 -63
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/api_pb2_grpc.py +0 -34
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/api_pb2_grpc.pyi +0 -12
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/modal_api_grpc.py +0 -1
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_version/__init__.py +1 -1
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/LICENSE +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/README.md +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/__main__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_billing.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_clustered_functions.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_environments.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_function_variants.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_functions.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_grpc_client.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_image.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_ipython.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_load_context.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_location.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_logs.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_logs_manager.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_logs_manager.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_object.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_output/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_output/manager.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_output/pty.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_output/rich.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_output/status.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_partial_function.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_resolver.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_resources.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_serialization.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_server.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_supports_logs.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_traceback.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_tunnel.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_tunnel.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_type_manager.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/display_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/logger.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_vendor/version.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_watcher.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/_workspace.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/app.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/app.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/billing.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/billing.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/builder/README.md +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/builder/base-images.json +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/call_graph.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/_download.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/_help.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/_traceback.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/app.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/billing.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/changelog.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/cluster.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/config.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/container.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/curl.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/dashboard.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/dict.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/endpoint.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/entry_point.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/environment.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/image.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/import_refs.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/launch.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/logo.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/profile.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/queues.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/run.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/secret.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/selector.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/skills.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/token.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/utils.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/volume.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cli/workspace.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/client.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cls.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/cls.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/config.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/container_process.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/container_process.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/dict.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/dict.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/environments.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/environments.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/exception.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/experimental/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/experimental/flash.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/experimental/ipython.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/file_io.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/file_io.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/functions.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/image.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/image.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/io_streams.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/io_streams.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/mount.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/mount.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/network_file_system.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/network_file_system.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/object.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/object.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/output.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/parallel_map.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/parallel_map.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/partial_function.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/partial_function.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/proxy.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/proxy.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/py.typed +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/queue.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/queue.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/retries.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/runner.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/runner.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/running_app.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/sandbox_fs.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/schedule.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/scheduler_placement.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/secret.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/secret.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/server.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/server.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/serving.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/serving.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/snapshot.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/snapshot.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/stream_type.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/token_flow.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/token_flow.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/types.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/volume.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/volume.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/workspace.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal/workspace.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_docs/reference_intro.md +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/__init__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/py.typed +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/modal_version/__main__.py +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/pyproject.toml +0 -0
- {modal-1.5.4.dev12 → modal-1.5.4.dev13}/setup.cfg +0 -0
|
@@ -17,7 +17,7 @@ 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 _MAIN_CONTAINER_NAME, Sandbox, _container_exec,
|
|
20
|
+
from ..sandbox import _MAIN_CONTAINER_NAME, Sandbox, SandboxVersion, _container_exec, _get_sandbox_version
|
|
21
21
|
from ..secret import Secret
|
|
22
22
|
from ..stream_type import StreamType
|
|
23
23
|
from ..volume import Volume
|
|
@@ -144,7 +144,7 @@ def _start_shell_in_running_container(ref: str, cmd: str, pty: bool) -> None:
|
|
|
144
144
|
raise ClickException(f"Sandbox '{sandbox_id}' not found (is it still running?)")
|
|
145
145
|
except Exception as e:
|
|
146
146
|
raise ClickException(f"Error connecting to Sandbox '{sandbox_id}': {str(e)}")
|
|
147
|
-
if
|
|
147
|
+
if _get_sandbox_version(sandbox_id) == SandboxVersion.V2:
|
|
148
148
|
sandbox_id_v2 = sandbox_id
|
|
149
149
|
|
|
150
150
|
assert _is_valid_modal_id(ref, "ta-")
|
|
@@ -37,7 +37,7 @@ class _Client:
|
|
|
37
37
|
server_url: str,
|
|
38
38
|
client_type: int,
|
|
39
39
|
credentials: typing.Optional[tuple[str, str]],
|
|
40
|
-
version: str = "1.5.4.
|
|
40
|
+
version: str = "1.5.4.dev13",
|
|
41
41
|
):
|
|
42
42
|
"""mdmd:hidden
|
|
43
43
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -207,7 +207,7 @@ class Client:
|
|
|
207
207
|
server_url: str,
|
|
208
208
|
client_type: int,
|
|
209
209
|
credentials: typing.Optional[tuple[str, str]],
|
|
210
|
-
version: str = "1.5.4.
|
|
210
|
+
version: str = "1.5.4.dev13",
|
|
211
211
|
):
|
|
212
212
|
"""mdmd:hidden
|
|
213
213
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -546,7 +546,7 @@ class Function(
|
|
|
546
546
|
|
|
547
547
|
_call_generator: ___call_generator_spec
|
|
548
548
|
|
|
549
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
549
|
+
class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
550
550
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
551
551
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result.
|
|
552
552
|
|
|
@@ -571,7 +571,7 @@ class Function(
|
|
|
571
571
|
"""
|
|
572
572
|
...
|
|
573
573
|
|
|
574
|
-
remote: __remote_spec[modal._functions.
|
|
574
|
+
remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
|
|
575
575
|
|
|
576
576
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
577
577
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -621,7 +621,7 @@ class Function(
|
|
|
621
621
|
"""
|
|
622
622
|
...
|
|
623
623
|
|
|
624
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
624
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
625
625
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
626
626
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
627
627
|
|
|
@@ -654,7 +654,7 @@ class Function(
|
|
|
654
654
|
"""
|
|
655
655
|
...
|
|
656
656
|
|
|
657
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
657
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
|
|
658
658
|
|
|
659
659
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
660
660
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -662,7 +662,7 @@ class Function(
|
|
|
662
662
|
|
|
663
663
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
664
664
|
|
|
665
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
665
|
+
class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
666
666
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
667
667
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
668
668
|
|
|
@@ -695,7 +695,7 @@ class Function(
|
|
|
695
695
|
"""
|
|
696
696
|
...
|
|
697
697
|
|
|
698
|
-
spawn: __spawn_spec[modal._functions.
|
|
698
|
+
spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
|
|
699
699
|
|
|
700
700
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
701
701
|
"""Return the inner Python object wrapped by this Modal Function.
|
|
@@ -154,7 +154,6 @@ def _ttl_to_wire_ttl(ttl: int | None) -> int:
|
|
|
154
154
|
|
|
155
155
|
|
|
156
156
|
_V1_SANDBOX_ID_ALPHABET = frozenset("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
|
|
157
|
-
_ULID_ALPHABET = frozenset("0123456789ABCDEFGHJKMNPQRSTVWXYZ")
|
|
158
157
|
_CUSTOMER_SUPPLIED_ENCRYPTION_KEY_MIN_LENGTH = 16
|
|
159
158
|
_CUSTOMER_SUPPLIED_ENCRYPTION_KEY_MAX_LENGTH = 512
|
|
160
159
|
|
|
@@ -196,23 +195,13 @@ def _is_v1_sandbox_id(sandbox_id: str) -> bool:
|
|
|
196
195
|
)
|
|
197
196
|
|
|
198
197
|
|
|
199
|
-
def _is_v2_sandbox_id(sandbox_id: str) -> bool:
|
|
200
|
-
prefix, separator, suffix = sandbox_id.partition("-")
|
|
201
|
-
return (
|
|
202
|
-
prefix == "sb"
|
|
203
|
-
and separator == "-"
|
|
204
|
-
and len(suffix) == 26
|
|
205
|
-
and suffix[0] in "01234567"
|
|
206
|
-
and all(ch in _ULID_ALPHABET for ch in suffix)
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
|
|
210
198
|
def _get_sandbox_version(sandbox_id: str) -> SandboxVersion:
|
|
211
|
-
|
|
212
|
-
|
|
199
|
+
# IDs that don't match the V1 shape are assumed to be V2, so that Sandbox
|
|
200
|
+
# IDs minted in newer formats route to the newer backend instead of
|
|
201
|
+
# failing client-side.
|
|
213
202
|
if _is_v1_sandbox_id(sandbox_id):
|
|
214
203
|
return SandboxVersion.V1
|
|
215
|
-
|
|
204
|
+
return SandboxVersion.V2
|
|
216
205
|
|
|
217
206
|
|
|
218
207
|
def _result_returncode(result: api_pb2.GenericResult | None) -> int | None:
|
|
@@ -237,6 +226,31 @@ def _validate_exec_args(args: Sequence[str]) -> None:
|
|
|
237
226
|
)
|
|
238
227
|
|
|
239
228
|
|
|
229
|
+
def _build_outbound_network_access(
|
|
230
|
+
block_network: bool,
|
|
231
|
+
outbound_cidr_allowlist: Sequence[str] | None,
|
|
232
|
+
outbound_domain_allowlist: Sequence[str] | None,
|
|
233
|
+
) -> api_pb2.NetworkAccess:
|
|
234
|
+
"""Build the outbound `NetworkAccess` for the given params.
|
|
235
|
+
|
|
236
|
+
Shared by `Sandbox.create` and the sidecar create path. When nothing is
|
|
237
|
+
specified, defaults to open network access.
|
|
238
|
+
"""
|
|
239
|
+
if block_network:
|
|
240
|
+
if outbound_cidr_allowlist is not None:
|
|
241
|
+
raise InvalidError("`outbound_cidr_allowlist` cannot be used when `block_network` is enabled")
|
|
242
|
+
if outbound_domain_allowlist is not None:
|
|
243
|
+
raise InvalidError("`outbound_domain_allowlist` cannot be used when `block_network` is enabled")
|
|
244
|
+
return api_pb2.NetworkAccess(network_access_type=api_pb2.NetworkAccess.NetworkAccessType.BLOCKED)
|
|
245
|
+
if outbound_cidr_allowlist is None and outbound_domain_allowlist is None:
|
|
246
|
+
return api_pb2.NetworkAccess(network_access_type=api_pb2.NetworkAccess.NetworkAccessType.OPEN)
|
|
247
|
+
return api_pb2.NetworkAccess(
|
|
248
|
+
network_access_type=api_pb2.NetworkAccess.NetworkAccessType.ALLOWLIST,
|
|
249
|
+
allowed_cidrs=list(outbound_cidr_allowlist or []),
|
|
250
|
+
allowed_domains=list(outbound_domain_allowlist or []),
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
|
|
240
254
|
class DefaultSandboxNameOverride(str):
|
|
241
255
|
"""A singleton class that represents the default sandbox name override.
|
|
242
256
|
|
|
@@ -439,27 +453,11 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
439
453
|
]
|
|
440
454
|
)
|
|
441
455
|
|
|
442
|
-
if block_network:
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
if inbound_cidr_allowlist is not None:
|
|
448
|
-
raise InvalidError("`inbound_cidr_allowlist` cannot be used when `block_network` is enabled")
|
|
449
|
-
network_access = api_pb2.NetworkAccess(
|
|
450
|
-
network_access_type=api_pb2.NetworkAccess.NetworkAccessType.BLOCKED,
|
|
451
|
-
)
|
|
452
|
-
else:
|
|
453
|
-
if outbound_domain_allowlist is None and outbound_cidr_allowlist is None:
|
|
454
|
-
network_access = api_pb2.NetworkAccess(
|
|
455
|
-
network_access_type=api_pb2.NetworkAccess.NetworkAccessType.OPEN,
|
|
456
|
-
)
|
|
457
|
-
else:
|
|
458
|
-
network_access = api_pb2.NetworkAccess(
|
|
459
|
-
network_access_type=api_pb2.NetworkAccess.NetworkAccessType.ALLOWLIST,
|
|
460
|
-
allowed_cidrs=list(outbound_cidr_allowlist or []),
|
|
461
|
-
allowed_domains=list(outbound_domain_allowlist or []),
|
|
462
|
-
)
|
|
456
|
+
if block_network and inbound_cidr_allowlist is not None:
|
|
457
|
+
raise InvalidError("`inbound_cidr_allowlist` cannot be used when `block_network` is enabled")
|
|
458
|
+
network_access = _build_outbound_network_access(
|
|
459
|
+
block_network, outbound_cidr_allowlist, outbound_domain_allowlist
|
|
460
|
+
)
|
|
463
461
|
|
|
464
462
|
ephemeral_disk = None # Ephemeral disk requests not supported on Sandboxes.
|
|
465
463
|
definition = api_pb2.Sandbox(
|
|
@@ -1128,7 +1126,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
|
1128
1126
|
self._command_router_client = None
|
|
1129
1127
|
self._init_command_router_access = None
|
|
1130
1128
|
self._filesystem = None
|
|
1131
|
-
self._is_v2 =
|
|
1129
|
+
self._is_v2 = _get_sandbox_version(self.object_id) == SandboxVersion.V2
|
|
1132
1130
|
if self._is_v2:
|
|
1133
1131
|
self._hydrate_metadata_v2()
|
|
1134
1132
|
|
|
@@ -2796,6 +2794,8 @@ class _SidecarManager:
|
|
|
2796
2794
|
secrets: Collection[_Secret] | None = None,
|
|
2797
2795
|
workdir: str | None = None,
|
|
2798
2796
|
volumes: dict[str | os.PathLike, _Volume] | None = None,
|
|
2797
|
+
outbound_cidr_allowlist: Sequence[str] | None = None,
|
|
2798
|
+
outbound_domain_allowlist: Sequence[str] | None = None,
|
|
2799
2799
|
) -> _SidecarContainer:
|
|
2800
2800
|
"""Create a sidecar container running alongside the Sandbox's main container.
|
|
2801
2801
|
|
|
@@ -2803,6 +2803,12 @@ class _SidecarManager:
|
|
|
2803
2803
|
can be used to run auxiliary processes, such as a database or a service the main container
|
|
2804
2804
|
depends on.
|
|
2805
2805
|
|
|
2806
|
+
The sidecar's outbound network policy is independent of the main container's and defaults to
|
|
2807
|
+
open network access. To restrict it, pass `outbound_cidr_allowlist` and/or
|
|
2808
|
+
`outbound_domain_allowlist`. To block all external egress while keeping connectivity to the
|
|
2809
|
+
main container, pass an empty allowlist (`outbound_cidr_allowlist=[]`); a fully network-blocked
|
|
2810
|
+
sidecar is not supported because it would have no IP and could not reach the main container.
|
|
2811
|
+
|
|
2806
2812
|
Args:
|
|
2807
2813
|
*args: Command and arguments to run inside the sidecar container.
|
|
2808
2814
|
name: Unique name for the sidecar container. The name ``"main"`` is reserved.
|
|
@@ -2811,6 +2817,11 @@ class _SidecarManager:
|
|
|
2811
2817
|
secrets: Secrets to inject as environment variables in the sidecar container.
|
|
2812
2818
|
workdir: Working directory for the command; must be absolute if set.
|
|
2813
2819
|
volumes: Mapping of mount paths to `Volume` objects to mount in the sidecar container.
|
|
2820
|
+
outbound_cidr_allowlist: If set, restrict the sidecar's outbound traffic to these CIDR
|
|
2821
|
+
blocks. An empty list blocks all external egress while preserving connectivity to the
|
|
2822
|
+
main container.
|
|
2823
|
+
outbound_domain_allowlist: If set, restrict the sidecar's outbound TLS connections (port
|
|
2824
|
+
443) to these SNI domains. Supports wildcards like ``*.example.com``.
|
|
2814
2825
|
|
|
2815
2826
|
Returns:
|
|
2816
2827
|
A `SidecarContainer` handle for the running container.
|
|
@@ -2865,6 +2876,7 @@ class _SidecarManager:
|
|
|
2865
2876
|
workdir=workdir or "",
|
|
2866
2877
|
secret_ids=[secret.object_id for secret in secrets],
|
|
2867
2878
|
volume_mounts=volume_mounts,
|
|
2879
|
+
network_access=_build_outbound_network_access(False, outbound_cidr_allowlist, outbound_domain_allowlist),
|
|
2868
2880
|
)
|
|
2869
2881
|
create_resp = await command_router_client.container_create(create_req)
|
|
2870
2882
|
container_id = create_resp.container_id
|
|
@@ -54,10 +54,20 @@ class SandboxVersion(enum.Enum):
|
|
|
54
54
|
V2 = 2
|
|
55
55
|
|
|
56
56
|
def _is_v1_sandbox_id(sandbox_id: str) -> bool: ...
|
|
57
|
-
def _is_v2_sandbox_id(sandbox_id: str) -> bool: ...
|
|
58
57
|
def _get_sandbox_version(sandbox_id: str) -> SandboxVersion: ...
|
|
59
58
|
def _result_returncode(result: typing.Optional[modal_proto.api_pb2.GenericResult]) -> typing.Optional[int]: ...
|
|
60
59
|
def _validate_exec_args(args: collections.abc.Sequence[str]) -> None: ...
|
|
60
|
+
def _build_outbound_network_access(
|
|
61
|
+
block_network: bool,
|
|
62
|
+
outbound_cidr_allowlist: typing.Optional[collections.abc.Sequence[str]],
|
|
63
|
+
outbound_domain_allowlist: typing.Optional[collections.abc.Sequence[str]],
|
|
64
|
+
) -> modal_proto.api_pb2.NetworkAccess:
|
|
65
|
+
"""Build the outbound `NetworkAccess` for the given params.
|
|
66
|
+
|
|
67
|
+
Shared by `Sandbox.create` and the sidecar create path. When nothing is
|
|
68
|
+
specified, defaults to open network access.
|
|
69
|
+
"""
|
|
70
|
+
...
|
|
61
71
|
|
|
62
72
|
class DefaultSandboxNameOverride(str):
|
|
63
73
|
"""A singleton class that represents the default sandbox name override.
|
|
@@ -1134,6 +1144,8 @@ class _SidecarManager:
|
|
|
1134
1144
|
secrets: typing.Optional[collections.abc.Collection[modal.secret._Secret]] = None,
|
|
1135
1145
|
workdir: typing.Optional[str] = None,
|
|
1136
1146
|
volumes: typing.Optional[dict[typing.Union[str, os.PathLike], modal.volume._Volume]] = None,
|
|
1147
|
+
outbound_cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1148
|
+
outbound_domain_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1137
1149
|
) -> _SidecarContainer:
|
|
1138
1150
|
"""Create a sidecar container running alongside the Sandbox's main container.
|
|
1139
1151
|
|
|
@@ -1141,6 +1153,12 @@ class _SidecarManager:
|
|
|
1141
1153
|
can be used to run auxiliary processes, such as a database or a service the main container
|
|
1142
1154
|
depends on.
|
|
1143
1155
|
|
|
1156
|
+
The sidecar's outbound network policy is independent of the main container's and defaults to
|
|
1157
|
+
open network access. To restrict it, pass `outbound_cidr_allowlist` and/or
|
|
1158
|
+
`outbound_domain_allowlist`. To block all external egress while keeping connectivity to the
|
|
1159
|
+
main container, pass an empty allowlist (`outbound_cidr_allowlist=[]`); a fully network-blocked
|
|
1160
|
+
sidecar is not supported because it would have no IP and could not reach the main container.
|
|
1161
|
+
|
|
1144
1162
|
Args:
|
|
1145
1163
|
*args: Command and arguments to run inside the sidecar container.
|
|
1146
1164
|
name: Unique name for the sidecar container. The name ``"main"`` is reserved.
|
|
@@ -1149,6 +1167,11 @@ class _SidecarManager:
|
|
|
1149
1167
|
secrets: Secrets to inject as environment variables in the sidecar container.
|
|
1150
1168
|
workdir: Working directory for the command; must be absolute if set.
|
|
1151
1169
|
volumes: Mapping of mount paths to `Volume` objects to mount in the sidecar container.
|
|
1170
|
+
outbound_cidr_allowlist: If set, restrict the sidecar's outbound traffic to these CIDR
|
|
1171
|
+
blocks. An empty list blocks all external egress while preserving connectivity to the
|
|
1172
|
+
main container.
|
|
1173
|
+
outbound_domain_allowlist: If set, restrict the sidecar's outbound TLS connections (port
|
|
1174
|
+
443) to these SNI domains. Supports wildcards like ``*.example.com``.
|
|
1152
1175
|
|
|
1153
1176
|
Returns:
|
|
1154
1177
|
A `SidecarContainer` handle for the running container.
|
|
@@ -1374,6 +1397,8 @@ class SidecarManager:
|
|
|
1374
1397
|
secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
|
|
1375
1398
|
workdir: typing.Optional[str] = None,
|
|
1376
1399
|
volumes: typing.Optional[dict[typing.Union[str, os.PathLike], modal.volume.Volume]] = None,
|
|
1400
|
+
outbound_cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1401
|
+
outbound_domain_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1377
1402
|
) -> SidecarContainer:
|
|
1378
1403
|
"""Create a sidecar container running alongside the Sandbox's main container.
|
|
1379
1404
|
|
|
@@ -1381,6 +1406,12 @@ class SidecarManager:
|
|
|
1381
1406
|
can be used to run auxiliary processes, such as a database or a service the main container
|
|
1382
1407
|
depends on.
|
|
1383
1408
|
|
|
1409
|
+
The sidecar's outbound network policy is independent of the main container's and defaults to
|
|
1410
|
+
open network access. To restrict it, pass `outbound_cidr_allowlist` and/or
|
|
1411
|
+
`outbound_domain_allowlist`. To block all external egress while keeping connectivity to the
|
|
1412
|
+
main container, pass an empty allowlist (`outbound_cidr_allowlist=[]`); a fully network-blocked
|
|
1413
|
+
sidecar is not supported because it would have no IP and could not reach the main container.
|
|
1414
|
+
|
|
1384
1415
|
Args:
|
|
1385
1416
|
*args: Command and arguments to run inside the sidecar container.
|
|
1386
1417
|
name: Unique name for the sidecar container. The name ``"main"`` is reserved.
|
|
@@ -1389,6 +1420,11 @@ class SidecarManager:
|
|
|
1389
1420
|
secrets: Secrets to inject as environment variables in the sidecar container.
|
|
1390
1421
|
workdir: Working directory for the command; must be absolute if set.
|
|
1391
1422
|
volumes: Mapping of mount paths to `Volume` objects to mount in the sidecar container.
|
|
1423
|
+
outbound_cidr_allowlist: If set, restrict the sidecar's outbound traffic to these CIDR
|
|
1424
|
+
blocks. An empty list blocks all external egress while preserving connectivity to the
|
|
1425
|
+
main container.
|
|
1426
|
+
outbound_domain_allowlist: If set, restrict the sidecar's outbound TLS connections (port
|
|
1427
|
+
443) to these SNI domains. Supports wildcards like ``*.example.com``.
|
|
1392
1428
|
|
|
1393
1429
|
Returns:
|
|
1394
1430
|
A `SidecarContainer` handle for the running container.
|
|
@@ -1405,6 +1441,8 @@ class SidecarManager:
|
|
|
1405
1441
|
secrets: typing.Optional[collections.abc.Collection[modal.secret.Secret]] = None,
|
|
1406
1442
|
workdir: typing.Optional[str] = None,
|
|
1407
1443
|
volumes: typing.Optional[dict[typing.Union[str, os.PathLike], modal.volume.Volume]] = None,
|
|
1444
|
+
outbound_cidr_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1445
|
+
outbound_domain_allowlist: typing.Optional[collections.abc.Sequence[str]] = None,
|
|
1408
1446
|
) -> SidecarContainer:
|
|
1409
1447
|
"""Create a sidecar container running alongside the Sandbox's main container.
|
|
1410
1448
|
|
|
@@ -1412,6 +1450,12 @@ class SidecarManager:
|
|
|
1412
1450
|
can be used to run auxiliary processes, such as a database or a service the main container
|
|
1413
1451
|
depends on.
|
|
1414
1452
|
|
|
1453
|
+
The sidecar's outbound network policy is independent of the main container's and defaults to
|
|
1454
|
+
open network access. To restrict it, pass `outbound_cidr_allowlist` and/or
|
|
1455
|
+
`outbound_domain_allowlist`. To block all external egress while keeping connectivity to the
|
|
1456
|
+
main container, pass an empty allowlist (`outbound_cidr_allowlist=[]`); a fully network-blocked
|
|
1457
|
+
sidecar is not supported because it would have no IP and could not reach the main container.
|
|
1458
|
+
|
|
1415
1459
|
Args:
|
|
1416
1460
|
*args: Command and arguments to run inside the sidecar container.
|
|
1417
1461
|
name: Unique name for the sidecar container. The name ``"main"`` is reserved.
|
|
@@ -1420,6 +1464,11 @@ class SidecarManager:
|
|
|
1420
1464
|
secrets: Secrets to inject as environment variables in the sidecar container.
|
|
1421
1465
|
workdir: Working directory for the command; must be absolute if set.
|
|
1422
1466
|
volumes: Mapping of mount paths to `Volume` objects to mount in the sidecar container.
|
|
1467
|
+
outbound_cidr_allowlist: If set, restrict the sidecar's outbound traffic to these CIDR
|
|
1468
|
+
blocks. An empty list blocks all external egress while preserving connectivity to the
|
|
1469
|
+
main container.
|
|
1470
|
+
outbound_domain_allowlist: If set, restrict the sidecar's outbound TLS connections (port
|
|
1471
|
+
443) to these SNI domains. Supports wildcards like ``*.example.com``.
|
|
1423
1472
|
|
|
1424
1473
|
Returns:
|
|
1425
1474
|
A `SidecarContainer` handle for the running container.
|
|
@@ -123,10 +123,6 @@ class ModalClientBase(abc.ABC):
|
|
|
123
123
|
async def AuthTokenGet(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.AuthTokenGetRequest, modal_proto.api_pb2.AuthTokenGetResponse]') -> None:
|
|
124
124
|
pass
|
|
125
125
|
|
|
126
|
-
@abc.abstractmethod
|
|
127
|
-
async def AutoscalerOverrideHistory(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.AutoscalerOverrideHistoryRequest, modal_proto.api_pb2.AutoscalerOverrideHistoryResponse]') -> None:
|
|
128
|
-
pass
|
|
129
|
-
|
|
130
126
|
@abc.abstractmethod
|
|
131
127
|
async def BlobCreate(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.BlobCreateRequest, modal_proto.api_pb2.BlobCreateResponse]') -> None:
|
|
132
128
|
pass
|
|
@@ -1121,12 +1117,6 @@ class ModalClientBase(abc.ABC):
|
|
|
1121
1117
|
modal_proto.api_pb2.AuthTokenGetRequest,
|
|
1122
1118
|
modal_proto.api_pb2.AuthTokenGetResponse,
|
|
1123
1119
|
),
|
|
1124
|
-
'/modal.client.ModalClient/AutoscalerOverrideHistory': grpclib.const.Handler(
|
|
1125
|
-
self.AutoscalerOverrideHistory,
|
|
1126
|
-
grpclib.const.Cardinality.UNARY_UNARY,
|
|
1127
|
-
modal_proto.api_pb2.AutoscalerOverrideHistoryRequest,
|
|
1128
|
-
modal_proto.api_pb2.AutoscalerOverrideHistoryResponse,
|
|
1129
|
-
),
|
|
1130
1120
|
'/modal.client.ModalClient/BlobCreate': grpclib.const.Handler(
|
|
1131
1121
|
self.BlobCreate,
|
|
1132
1122
|
grpclib.const.Cardinality.UNARY_UNARY,
|
|
@@ -2543,12 +2533,6 @@ class ModalClientStub:
|
|
|
2543
2533
|
modal_proto.api_pb2.AuthTokenGetRequest,
|
|
2544
2534
|
modal_proto.api_pb2.AuthTokenGetResponse,
|
|
2545
2535
|
)
|
|
2546
|
-
self.AutoscalerOverrideHistory = grpclib.client.UnaryUnaryMethod(
|
|
2547
|
-
channel,
|
|
2548
|
-
'/modal.client.ModalClient/AutoscalerOverrideHistory',
|
|
2549
|
-
modal_proto.api_pb2.AutoscalerOverrideHistoryRequest,
|
|
2550
|
-
modal_proto.api_pb2.AutoscalerOverrideHistoryResponse,
|
|
2551
|
-
)
|
|
2552
2536
|
self.BlobCreate = grpclib.client.UnaryUnaryMethod(
|
|
2553
2537
|
channel,
|
|
2554
2538
|
'/modal.client.ModalClient/BlobCreate',
|