diff --git a/CHANGELOG.md b/CHANGELOG.md index 8db9430..f18d3c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,11 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). having to write cumbersome code to get around the limitation. ([#106](https://github.com/nasa/python_cmr/issues/106)) +### Fixed + +- Respect the requested result limit when tool, service, and variable queries + retrieve a partial final page of JSON results with `get`. + ## [0.13.0] ### Added diff --git a/cmr/queries.py b/cmr/queries.py index 3e4a1f9..ace1140 100644 --- a/cmr/queries.py +++ b/cmr/queries.py @@ -1198,7 +1198,7 @@ def get(self, limit: int = 2000) -> Sequence[Any]: if len(latest) == 0: break - results.extend(latest) + results.extend(latest[:limit - len(results)]) page += 1 return results diff --git a/tests/test_get_limit.py b/tests/test_get_limit.py new file mode 100644 index 0000000..35cc9b8 --- /dev/null +++ b/tests/test_get_limit.py @@ -0,0 +1,32 @@ +from unittest.mock import Mock, patch + +import pytest + +from cmr import ServiceQuery, ToolQuery, VariableQuery + + +@pytest.mark.parametrize("query_class", [ToolQuery, ServiceQuery, VariableQuery]) +@pytest.mark.parametrize("limit", [0, 2001, 4000, 4001, 5000]) +def test_get_respects_limit_across_pages(query_class, limit): + records = [{"id": index} for index in range(4500)] + pages = [] + + def get_page(url, params): + page_size = params["page_size"] + page = params["page_num"] + pages.append((page, page_size)) + start = (page - 1) * page_size + response = Mock() + response.json.return_value = {"items": records[start:start + page_size]} + return response + + with patch("cmr.queries.requests.get", side_effect=get_page): + results = query_class().get(limit) + + assert results == records[:limit] + if limit: + # Changing page_size between page numbers would skip or repeat records. + assert all(page_size == 2000 for _, page_size in pages) + assert [page for page, _ in pages] == list(range(1, len(pages) + 1)) + else: + assert pages == []