@@ -147,6 +147,7 @@ class Endpoints:
147147 create_table : str = "namespaces/{namespace}/tables"
148148 register_table : str = "namespaces/{namespace}/register"
149149 load_table : str = "namespaces/{namespace}/tables/{table}"
150+ load_credentials : str = "namespaces/{namespace}/tables/{table}/credentials"
150151 update_table : str = "namespaces/{namespace}/tables/{table}"
151152 drop_table : str = "namespaces/{namespace}/tables/{table}"
152153 table_exists : str = "namespaces/{namespace}/tables/{table}"
@@ -181,6 +182,7 @@ class Capability:
181182 V1_DELETE_TABLE = Endpoint (http_method = HttpMethod .DELETE , path = f"{ API_PREFIX } /{ Endpoints .drop_table } " )
182183 V1_RENAME_TABLE = Endpoint (http_method = HttpMethod .POST , path = f"{ API_PREFIX } /{ Endpoints .rename_table } " )
183184 V1_REGISTER_TABLE = Endpoint (http_method = HttpMethod .POST , path = f"{ API_PREFIX } /{ Endpoints .register_table } " )
185+ V1_LOAD_CREDENTIALS = Endpoint (http_method = HttpMethod .GET , path = f"{ API_PREFIX } /{ Endpoints .load_credentials } " )
184186
185187 V1_LIST_VIEWS = Endpoint (http_method = HttpMethod .GET , path = f"{ API_PREFIX } /{ Endpoints .list_views } " )
186188 V1_LOAD_VIEW = Endpoint (http_method = HttpMethod .GET , path = f"{ API_PREFIX } /{ Endpoints .load_view } " )
@@ -293,6 +295,10 @@ class TableResponse(IcebergBaseModel):
293295 storage_credentials : list [StorageCredential ] = Field (alias = "storage-credentials" , default_factory = list )
294296
295297
298+ class LoadCredentialsResponse (IcebergBaseModel ):
299+ storage_credentials : list [StorageCredential ] = Field (alias = "storage-credentials" )
300+
301+
296302class ViewResponse (IcebergBaseModel ):
297303 metadata_location : str | None = Field (alias = "metadata-location" , default = None )
298304 metadata : ViewMetadata
@@ -545,6 +551,32 @@ def _fetch_scan_tasks(self, identifier: str | Identifier, plan_task: str) -> Sca
545551
546552 return ScanTasks .model_validate_json (response .text )
547553
554+ @retry (** _RETRY_ARGS )
555+ def _load_credentials (
556+ self ,
557+ identifier : str | Identifier ,
558+ ) -> LoadCredentialsResponse :
559+ """Load raw vended storage credentials for a table."""
560+ self ._check_endpoint (Capability .V1_LOAD_CREDENTIALS )
561+ response = self ._session .get (
562+ self .url (Endpoints .load_credentials , prefixed = True , ** self ._split_identifier_for_path (identifier )),
563+ )
564+ try :
565+ response .raise_for_status ()
566+ except HTTPError as exc :
567+ _handle_non_200_response (exc , {404 : NoSuchTableError })
568+
569+ return LoadCredentialsResponse .model_validate_json (response .text )
570+
571+ def load_credentials (
572+ self ,
573+ identifier : str | Identifier ,
574+ location : str ,
575+ ) -> Properties :
576+ """Load vended storage credentials and return the best match for a location."""
577+ credentials_response = self ._load_credentials (identifier )
578+ return self ._resolve_storage_credentials (credentials_response .storage_credentials , location )
579+
548580 def plan_scan (self , identifier : str | Identifier , request : PlanTableScanRequest ) -> list [FileScanTask ]:
549581 """Plan a table scan and return FileScanTasks.
550582
0 commit comments