diff --git a/pyiceberg/catalog/rest/__init__.py b/pyiceberg/catalog/rest/__init__.py index d8f58773e6..8a50c22f15 100644 --- a/pyiceberg/catalog/rest/__init__.py +++ b/pyiceberg/catalog/rest/__init__.py @@ -1796,6 +1796,14 @@ def view_exists(self, identifier: str | Identifier) -> bool: Returns: bool: True if the view exists, False otherwise. """ + # fallback in order to work with older rest catalog implementations + if Capability.V1_VIEW_EXISTS not in self._supported_endpoints: + try: + self.load_view(identifier) + return True + except NoSuchViewError: + return False + response = self._session.head( self.url(Endpoints.view_exists, prefixed=True, **self._split_identifier_for_path(identifier, IdentifierKind.VIEW)), ) diff --git a/tests/catalog/test_rest.py b/tests/catalog/test_rest.py index a918829c24..3eb3e5d748 100644 --- a/tests/catalog/test_rest.py +++ b/tests/catalog/test_rest.py @@ -945,6 +945,53 @@ def test_view_exists_multilevel_namespace_404(rest_mock: Mocker) -> None: assert not catalog.view_exists((multilevel_namespace, view)) +def test_view_exists_fallback_200(requests_mock: Mocker, example_view_metadata_rest_json: dict[str, Any]) -> None: + requests_mock.get( + f"{TEST_URI}v1/config", + json={"defaults": {}, "overrides": {}, "endpoints": [str(Capability.V1_LOAD_VIEW)]}, + status_code=200, + ) + requests_mock.get( + f"{TEST_URI}v1/namespaces/fokko/views/view", + json=example_view_metadata_rest_json, + status_code=200, + request_headers=TEST_HEADERS, + ) + catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN) + assert catalog.view_exists(("fokko", "view")) + + +def test_view_exists_fallback_200_legacy_server(requests_mock: Mocker, example_view_metadata_rest_json: dict[str, Any]) -> None: + requests_mock.get( + f"{TEST_URI}v1/config", + json={"defaults": {"view-endpoints-supported": "true"}, "overrides": {}}, + status_code=200, + ) + requests_mock.get( + f"{TEST_URI}v1/namespaces/fokko/views/view", + json=example_view_metadata_rest_json, + status_code=200, + request_headers=TEST_HEADERS, + ) + catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN) + assert catalog.view_exists(("fokko", "view")) + + +def test_view_exists_fallback_404(requests_mock: Mocker) -> None: + requests_mock.get( + f"{TEST_URI}v1/config", + json={"defaults": {}, "overrides": {}, "endpoints": [str(Capability.V1_LOAD_VIEW)]}, + status_code=200, + ) + requests_mock.get( + f"{TEST_URI}v1/namespaces/fokko/views/view", + status_code=404, + request_headers=TEST_HEADERS, + ) + catalog = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN) + assert not catalog.view_exists(("fokko", "view")) + + def test_list_namespaces_200(rest_mock: Mocker) -> None: rest_mock.get( f"{TEST_URI}v1/namespaces",