From 6a9f15d0dba0be8f43995838f6d470ca61a33d8d Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Thu, 6 Nov 2025 20:45:56 +0000 Subject: [PATCH 1/3] Handle case when totalRecords is the first key in the json --- src/ldlite/_folio.py | 12 ++++++++++-- tests/test_cases/base.py | 7 +++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ldlite/_folio.py b/src/ldlite/_folio.py index c7f8046..fed9309 100644 --- a/src/ldlite/_folio.py +++ b/src/ldlite/_folio.py @@ -36,7 +36,7 @@ class FolioClient: def __init__(self, params: FolioParams): self._client_factory = default_client_factory(params) - def iterate_records( + def iterate_records( # noqa: C901 (to be really fixed in a non-bugfix release) self, path: str, timeout: float, @@ -92,7 +92,15 @@ def iterate_records( record = "" return - key = next(iter(j.keys())) + # folio records usually have two keys + # the actual list and the totalRecords key + # totalRecords isn't always in the same spot + # so we check for keys until we find a good one + # totalRecords as of right now is the only key that could get in the way + # but there may end up with more + keys = iter(j.keys()) + while (key := next(keys)) and key in ["totalRecords"]: + ... nonid_key = ( # Grab the first key if there isn't an id column # because we need it to offset page properly diff --git a/tests/test_cases/base.py b/tests/test_cases/base.py index c908912..d11a6dd 100644 --- a/tests/test_cases/base.py +++ b/tests/test_cases/base.py @@ -33,10 +33,13 @@ def patch_request_get( httpx_post_mock.return_value.cookies.__getitem__.return_value = "token" side_effects = [] - for values in self.values.values(): + for i, values in enumerate(self.values.values()): key = next(iter(values[0].keys())) total_mock = MagicMock() - total_mock.text = f'{{"{key}": [{{"id": ""}}], "totalRecords": 100000}}' + if i % 2 == 0: + total_mock.text = f'{{"{key}": [{{"id": ""}}], "totalRecords": 100000}}' + else: + total_mock.text = f'{{"totalRecords": 100000, "{key}": [{{"id": ""}}]}}' value_mocks = [] for v in values: From 4aeeadaf91fcf35c2fa143cb433e0a273e85296f Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Wed, 12 Nov 2025 14:53:48 +0000 Subject: [PATCH 2/3] Handle case where erm keys are the first keys in json --- src/ldlite/_folio.py | 18 +++++++++++------ tests/test_cases/base.py | 2 +- tests/test_cases/query_cases.py | 35 +++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/ldlite/_folio.py b/src/ldlite/_folio.py index fed9309..30fec18 100644 --- a/src/ldlite/_folio.py +++ b/src/ldlite/_folio.py @@ -92,15 +92,21 @@ def iterate_records( # noqa: C901 (to be really fixed in a non-bugfix release) record = "" return - # folio records usually have two keys - # the actual list and the totalRecords key - # totalRecords isn't always in the same spot + # folio records usually have additional keys besides the actual list + # the items are usually first but not always # so we check for keys until we find a good one - # totalRecords as of right now is the only key that could get in the way + # totalRecords and erm as of right now are the only keys like this # but there may end up with more keys = iter(j.keys()) - while (key := next(keys)) and key in ["totalRecords"]: - ... + while (key := next(keys)) and key in [ + "totalRecords", + "pageSize", + "page", + "totalPages", + "meta", + "total", + ]: + continue nonid_key = ( # Grab the first key if there isn't an id column # because we need it to offset page properly diff --git a/tests/test_cases/base.py b/tests/test_cases/base.py index d11a6dd..4a7894a 100644 --- a/tests/test_cases/base.py +++ b/tests/test_cases/base.py @@ -34,7 +34,7 @@ def patch_request_get( side_effects = [] for i, values in enumerate(self.values.values()): - key = next(iter(values[0].keys())) + *_, key = iter(values[0].keys()) total_mock = MagicMock() if i % 2 == 0: total_mock.text = f'{{"{key}": [{{"id": ""}}], "totalRecords": 100000}}' diff --git a/tests/test_cases/query_cases.py b/tests/test_cases/query_cases.py index 408b429..b414371 100644 --- a/tests/test_cases/query_cases.py +++ b/tests/test_cases/query_cases.py @@ -603,3 +603,38 @@ def case_null_records(self) -> QueryCase: ("prefix__t", "id"), ], ) + + def case_erm_keys(self) -> QueryCase: + return QueryCase( + json_depth=3, + values={ + "prefix": [ + { + "pageSize": 30, + "page": 1, + "totalPages": 10, + "meta": {"updated": "by"}, + "total": 285, + "purchaseOrders": [ + { + "id": "b096504a-3d54-4664-9bf5-1b872466fd66", + "value": "value", + }, + ], + }, + ], + }, + expected_tables=["prefix", "prefix__t", "prefix__tcatalog"], + expected_values={ + "prefix__t": ( + ["id", "value"], + [("b096504a-3d54-4664-9bf5-1b872466fd66", "value")], + ), + "prefix__tcatalog": (["table_name"], [("prefix__t",)]), + }, + expected_indexes=[ + ("prefix", "__id"), + ("prefix__t", "__id"), + ("prefix__t", "id"), + ], + ) From cc7b5c3fdc4327c8f24084f896587f1e8a600aba Mon Sep 17 00:00:00 2001 From: Katherine Bargar Date: Thu, 6 Nov 2025 20:48:53 +0000 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b958f7..c610db3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ Please see [MIGRATING.md](./MIGRATING.md) for information on breaking changes. ### Fixed +- Endpoints which return system fields before the record list + ### Changed ### Removed