Skip to content

Commit f137852

Browse files
REST: Allow disabling remote signing with an empty s3.signer
Closes #3888
1 parent 7d51e52 commit f137852

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

‎pyiceberg/catalog/rest/__init__.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
AWS_REGION,
7474
AWS_SECRET_ACCESS_KEY,
7575
AWS_SESSION_TOKEN,
76+
S3_SIGNER,
7677
FileIO,
7778
load_file_io,
7879
)
@@ -645,6 +646,10 @@ def _load_file_io(
645646
table_properties: Properties = EMPTY_DICT,
646647
) -> FileIO:
647648
merged_properties = {**table_properties, **self.properties, **properties}
649+
# An explicitly empty s3.signer in the catalog config opts out of remote signing,
650+
# even when the server config or vended credentials set a signer.
651+
if self.properties.get(S3_SIGNER) == "":
652+
merged_properties[S3_SIGNER] = ""
648653
if self._auth_manager:
649654
merged_properties[AUTH_MANAGER] = self._auth_manager
650655
return load_file_io(merged_properties, location)

‎tests/catalog/test_rest.py‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,6 +3481,46 @@ def test_load_table_catalog_config_outranks_table_properties(
34813481
assert table.io.properties["s3.proxy-uri"] == "http://table-only-proxy"
34823482

34833483

3484+
def test_load_table_empty_catalog_signer_disables_remote_signing(
3485+
rest_mock: Mocker, example_table_metadata_with_snapshot_v1: dict[str, Any]
3486+
) -> None:
3487+
metadata_location = "s3://warehouse/database/table/metadata/00001.metadata.json"
3488+
rest_mock.get(
3489+
f"{TEST_URI}v1/namespaces/fokko/tables/table",
3490+
json={
3491+
"metadata-location": metadata_location,
3492+
"metadata": example_table_metadata_with_snapshot_v1,
3493+
"config": {"s3.signer": "S3V4RestSigner", "s3.signer.uri": "http://signer"},
3494+
},
3495+
status_code=200,
3496+
request_headers=TEST_HEADERS,
3497+
)
3498+
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN, **{"s3.signer": ""})
3499+
table = catalog.load_table(("fokko", "table"))
3500+
3501+
assert table.io.properties["s3.signer"] == ""
3502+
3503+
3504+
def test_load_table_server_signer_kept_without_catalog_override(
3505+
rest_mock: Mocker, example_table_metadata_with_snapshot_v1: dict[str, Any]
3506+
) -> None:
3507+
metadata_location = "s3://warehouse/database/table/metadata/00001.metadata.json"
3508+
rest_mock.get(
3509+
f"{TEST_URI}v1/namespaces/fokko/tables/table",
3510+
json={
3511+
"metadata-location": metadata_location,
3512+
"metadata": example_table_metadata_with_snapshot_v1,
3513+
"config": {"s3.signer": "S3V4RestSigner", "s3.signer.uri": "http://signer"},
3514+
},
3515+
status_code=200,
3516+
request_headers=TEST_HEADERS,
3517+
)
3518+
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
3519+
table = catalog.load_table(("fokko", "table"))
3520+
3521+
assert table.io.properties["s3.signer"] == "S3V4RestSigner"
3522+
3523+
34843524
def test_load_credentials_with_longest_prefix(rest_mock: Mocker) -> None:
34853525
rest_mock.get(
34863526
f"{TEST_URI}v1/namespaces/fokko/tables/table/credentials",

0 commit comments

Comments
 (0)