Skip to content

Commit 7cf58d3

Browse files
committed
REST: Add support for page-size in list_views
1 parent 2be1827 commit 7cf58d3

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

pyiceberg/catalog/rest/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ class ScanPlanningMode(Enum):
267267
VIEW_ENDPOINTS_SUPPORTED = "view-endpoints-supported"
268268
VIEW_ENDPOINTS_SUPPORTED_DEFAULT = False
269269

270+
PAGE_SIZE = "rest-page-size"
271+
270272
NAMESPACE_SEPARATOR_PROPERTY = "namespace-separator"
271273
DEFAULT_NAMESPACE_SEPARATOR = b"\x1f".decode(UTF8)
272274

@@ -1149,12 +1151,20 @@ def list_views(self, namespace: str | Identifier) -> list[Identifier]:
11491151
namespace_tuple = self._check_valid_namespace_identifier(namespace)
11501152
namespace_concat = self._encode_namespace_path(namespace_tuple)
11511153
url = self.url(Endpoints.list_views, namespace=namespace_concat)
1154+
params = {}
1155+
page_size = property_as_int(self.properties, PAGE_SIZE, None)
1156+
if page_size is not None:
1157+
if page_size <= 0:
1158+
raise ValueError(f"{PAGE_SIZE} must be a positive integer")
1159+
params["pageSize"] = str(page_size)
11521160

11531161
views: list[Identifier] = []
11541162
page_token: str | None = None
11551163

11561164
while True:
1157-
params = {"pageToken": page_token} if page_token else None
1165+
if page_token:
1166+
params["pageToken"] = page_token
1167+
11581168
response = self._session.get(url, params=params)
11591169
try:
11601170
response.raise_for_status()

tests/catalog/test_rest.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
DEFAULT_ENDPOINTS,
3636
EMPTY_BODY_SHA256,
3737
OAUTH2_SERVER_URI,
38+
PAGE_SIZE,
3839
SIGV4_MAX_RETRIES,
3940
SIGV4_MAX_RETRIES_DEFAULT,
4041
SNAPSHOT_LOADING_MODE,
@@ -810,6 +811,48 @@ def test_list_views_paginated_200_none_next_page_token(rest_mock: Mocker) -> Non
810811
]
811812

812813

814+
def test_list_views_page_size(rest_mock: Mocker) -> None:
815+
namespace = "examples"
816+
rest_mock.get(
817+
f"{TEST_URI}v1/namespaces/{namespace}/views",
818+
json={
819+
"identifiers": [
820+
{"namespace": ["examples"], "name": "view1"},
821+
{"namespace": ["examples"], "name": "view2"},
822+
],
823+
},
824+
status_code=200,
825+
request_headers=TEST_HEADERS,
826+
)
827+
828+
result = RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN, **{PAGE_SIZE: "100"}).list_views(namespace)
829+
assert rest_mock.last_request.url == f"{TEST_URI}v1/namespaces/examples/views?pageSize=100"
830+
831+
assert result == [
832+
("examples", "view1"),
833+
("examples", "view2"),
834+
]
835+
836+
837+
def test_list_views_invalid_page_size(rest_mock: Mocker) -> None:
838+
namespace = "examples"
839+
rest_mock.get(
840+
f"{TEST_URI}v1/namespaces/{namespace}/views",
841+
json={
842+
"identifiers": [
843+
{"namespace": ["examples"], "name": "view1"},
844+
{"namespace": ["examples"], "name": "view2"},
845+
],
846+
},
847+
status_code=200,
848+
request_headers=TEST_HEADERS,
849+
)
850+
851+
with pytest.raises(ValueError) as e:
852+
RestCatalog("rest", uri=TEST_URI, token=TEST_TOKEN, **{PAGE_SIZE: "0"}).list_views(namespace)
853+
assert str(e.value) == "rest-page-size must be a positive integer"
854+
855+
813856
def test_list_views_200_sigv4(rest_mock: Mocker) -> None:
814857
namespace = "examples"
815858
rest_mock.get(

0 commit comments

Comments
 (0)