Skip to content

Commit 5becad1

Browse files
kevinjqliuCopilot
andauthored
REST: Require metadata-location in view responses (#4152)
Require metadata-location in REST view responses The REST spec marks metadata-location as required in LoadViewResult, and Java's LoadViewResponseParser rejects responses without it. Make ViewResponse.metadata_location required to match. Behavior change: create_view, load_view, and register_view now raise a pydantic ValidationError for non-compliant servers that omit metadata-location, instead of silently accepting the response. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent e6eb6a9 commit 5becad1

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

‎pyiceberg/catalog/rest/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ class LoadCredentialsResponse(IcebergBaseModel):
361361

362362

363363
class ViewResponse(IcebergBaseModel):
364-
metadata_location: str | None = Field(alias="metadata-location", default=None)
364+
metadata_location: str = Field(..., alias="metadata-location")
365365
metadata: ViewMetadata
366366
config: Properties = Field(default_factory=dict)
367367

‎tests/catalog/test_rest.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from urllib.parse import parse_qs, urlsplit
2727

2828
import pytest
29+
from pydantic import ValidationError
2930
from requests import Request
3031
from requests.adapters import HTTPAdapter
3132
from requests.exceptions import HTTPError
@@ -1856,6 +1857,19 @@ def test_load_view_200(rest_mock: Mocker, example_view_metadata_rest_json: dict[
18561857
assert actual.config == example_view_metadata_rest_json["config"]
18571858

18581859

1860+
def test_load_view_missing_metadata_location(rest_mock: Mocker, example_view_metadata_rest_json: dict[str, Any]) -> None:
1861+
response = {k: v for k, v in example_view_metadata_rest_json.items() if k != "metadata-location"}
1862+
rest_mock.get(
1863+
f"{TEST_URI}v1/namespaces/fokko/views/view",
1864+
json=response,
1865+
status_code=200,
1866+
request_headers=TEST_HEADERS,
1867+
)
1868+
catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN)
1869+
with pytest.raises(ValidationError, match="metadata-location"):
1870+
catalog.load_view(("fokko", "view"))
1871+
1872+
18591873
def test_load_view_404(rest_mock: Mocker) -> None:
18601874
rest_mock.get(
18611875
f"{TEST_URI}v1/namespaces/fokko/views/non_existent_view",

0 commit comments

Comments
 (0)