@@ -462,7 +462,12 @@ def _response_to_table(self, identifier_tuple: Tuple[str, ...], table_response:
462462 io = self ._load_file_io (
463463 {
464464 ** table_response .metadata .properties ,
465- ** self ._get_credentials (table_response .storage_credentials , table_response .config ),
465+ ** self ._get_credentials (
466+ table_response .storage_credentials ,
467+ table_response .config ,
468+ table_response .metadata_location ,
469+ getattr (table_response .metadata , "location" , None ),
470+ ),
466471 },
467472 table_response .metadata_location ,
468473 ),
@@ -478,25 +483,39 @@ def _response_to_staged_table(self, identifier_tuple: Tuple[str, ...], table_res
478483 io = self ._load_file_io (
479484 {
480485 ** table_response .metadata .properties ,
481- ** self ._get_credentials (table_response .storage_credentials , table_response .config ),
486+ ** self ._get_credentials (
487+ table_response .storage_credentials ,
488+ table_response .config ,
489+ table_response .metadata_location ,
490+ getattr (table_response .metadata , "location" , None ),
491+ ),
482492 },
483493 table_response .metadata_location ,
484494 ),
485495 catalog = self ,
486496 )
487497
488- def _get_credentials (self , storage_credentials : List [StorageCredential ], config : Properties ) -> Properties :
489- if storage_credentials :
490- return self ._get_storage_credentials (storage_credentials )
491- return config
492-
493498 @staticmethod
494- def _get_storage_credentials (storage_credentials : List [StorageCredential ]) -> Properties :
495- credentials : List [StorageCredential ] = [sc for sc in storage_credentials if sc .prefix .startswith ("s3" )]
496- if len (credentials ) > 1 :
497- raise ValueError ("Multiple S3 storage credentials found" )
498- elif len (credentials ) == 1 :
499- return credentials [0 ].config
499+ def _get_credentials (
500+ storage_credentials : Optional [List [StorageCredential ]],
501+ config : Properties ,
502+ metadata_location : Optional [str ],
503+ table_location : Optional [str ],
504+ ) -> Properties :
505+ if not storage_credentials :
506+ return config
507+
508+ target = metadata_location or table_location
509+ if not target :
510+ return config
511+
512+ # Choose the most specific (longest) matching prefix
513+ matching : List [StorageCredential ] = [sc for sc in storage_credentials if target .startswith (sc .prefix )]
514+ if not matching :
515+ return config
516+
517+ selected = max (matching , key = lambda sc : len (sc .prefix ))
518+ return selected .config
500519
501520 def _refresh_token (self ) -> None :
502521 # Reactive token refresh is atypical - we should proactively refresh tokens in a separate thread
0 commit comments