from __future__ import annotations from typing import Protocol class StorageAdapter(Protocol): """The object-store specifics the shared external loader needs, supplied per loader so the orchestration stays storage-agnostic. S3 and GCS differ only in how objects are listed and how the Databend external stage is addressed/authenticated.""" def list_objects(self, uri: str) -> list[dict]: """List objects under ``uri`` as ``[{name, size, last_modified_ms}]`` where ``name`` is the bucket-relative object path and ``last_modified_ms`` is epoch milliseconds.""" ... def create_stage_sql(self, stage_name: str, uri: str) -> str: """The ``CREATE OR REPLACE STAGE`` statement for ``uri`` (correct scheme + credential connection for this object store).""" ... def credential_env_names(self) -> list[str]: """Env var names holding this store's credentials, redacted from error messages.""" ...