From 8a1e69fe05f1387cbba705f2eb721e30450bc59d Mon Sep 17 00:00:00 2001 From: Pete Gadomski Date: Mon, 21 Aug 2023 06:35:01 -0600 Subject: [PATCH 1/3] fix: get_items without ids Passing empty list to `search` has different semantics than `None`. --- CHANGELOG.md | 2 +- pystac_client/client.py | 2 +- .../test_get_items_without_ids.yaml | 524 ++++++++++++++++++ tests/test_client.py | 8 + 4 files changed, 534 insertions(+), 2 deletions(-) create mode 100644 tests/cassettes/test_client/test_get_items_without_ids.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 420d57f0..1a470a49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed -- Updated `get_items` signatures for PySTAC v1.8 [#559](https://github.com/stac-utils/pystac-client/pull/559) +- Updated `get_items` signatures for PySTAC v1.8 [#559](https://github.com/stac-utils/pystac-client/pull/559), [#579](https://github.com/stac-utils/pystac-client/pull/579) ## [v0.7.2] - 2023-06-23 diff --git a/pystac_client/client.py b/pystac_client/client.py index c16e341d..640849df 100644 --- a/pystac_client/client.py +++ b/pystac_client/client.py @@ -451,7 +451,7 @@ def get_items(self, *ids: str, recursive: bool = False) -> Iterator["Item_Type"] catalog. """ if self.conforms_to(ConformanceClasses.ITEM_SEARCH): - search = self.search(ids=ids) + search = self.search(ids=ids or None) yield from search.items() else: self._warn_about_fallback("ITEM_SEARCH") diff --git a/tests/cassettes/test_client/test_get_items_without_ids.yaml b/tests/cassettes/test_client/test_get_items_without_ids.yaml new file mode 100644 index 00000000..5fe9aaaf --- /dev/null +++ b/tests/cassettes/test_client/test_get_items_without_ids.yaml @@ -0,0 +1,524 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.31.0 + method: GET + uri: https://planetarycomputer.microsoft.com/api/stac/v1/ + response: + body: + string: !!binary | + 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 + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Length: + - '3227' + Content-Type: + - application/json + Date: + - Mon, 21 Aug 2023 12:34:57 GMT + Strict-Transport-Security: + - max-age=15724800; includeSubDomains + X-Cache: + - CONFIG_NOCACHE + content-encoding: + - gzip + vary: + - Accept-Encoding + x-azure-ref: + - 20230821T123456Z-590cyt4v1d20h5yzdqguwr1mq80000000dhg000000004gv3 + status: + code: 200 + message: OK +- request: + body: '{"limit": 100}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '14' + Content-Type: + - application/json + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://planetarycomputer.microsoft.com/api/stac/v1/search + response: + body: + string: !!binary | + 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 + headers: + Accept-Ranges: + - bytes + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Length: + - '21250' + Content-Type: + - application/geo+json + Date: + - Mon, 21 Aug 2023 12:34:57 GMT + Strict-Transport-Security: + - max-age=15724800; includeSubDomains + X-Cache: + - CONFIG_NOCACHE + content-encoding: + - gzip + vary: + - Accept-Encoding + x-azure-ref: + - 20230821T123457Z-590cyt4v1d20h5yzdqguwr1mq80000000dhg000000004gxa + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_client.py b/tests/test_client.py index f93e3a24..bd5a4085 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -695,3 +695,11 @@ def test_collections_are_clients() -> None: ) assert item item.get_collection() + + +@pytest.mark.vcr +def test_get_items_without_ids() -> None: + client = Client.open( + "https://planetarycomputer.microsoft.com/api/stac/v1/", + ) + next(client.get_items()) From 6bfc5b0f91135a0b6bd3465fce0ddc51c613ff5b Mon Sep 17 00:00:00 2001 From: Pete Gadomski Date: Mon, 21 Aug 2023 09:39:35 -0600 Subject: [PATCH 2/3] fix: disallow empty lists in ItemSearch --- pystac_client/client.py | 2 +- pystac_client/item_search.py | 2 +- .../test_get_items_without_ids.yaml | 40 ++++++++----------- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/pystac_client/client.py b/pystac_client/client.py index 640849df..c16e341d 100644 --- a/pystac_client/client.py +++ b/pystac_client/client.py @@ -451,7 +451,7 @@ def get_items(self, *ids: str, recursive: bool = False) -> Iterator["Item_Type"] catalog. """ if self.conforms_to(ConformanceClasses.ITEM_SEARCH): - search = self.search(ids=ids or None) + search = self.search(ids=ids) yield from search.items() else: self._warn_about_fallback("ITEM_SEARCH") diff --git a/pystac_client/item_search.py b/pystac_client/item_search.py index 88f111c7..9710dfaf 100644 --- a/pystac_client/item_search.py +++ b/pystac_client/item_search.py @@ -550,7 +550,7 @@ def _format(c: Any) -> Collections: @staticmethod def _format_ids(value: Optional[IDsLike]) -> Optional[IDs]: - if value is None: + if not value: return None if isinstance(value, str): diff --git a/tests/cassettes/test_client/test_get_items_without_ids.yaml b/tests/cassettes/test_client/test_get_items_without_ids.yaml index 5fe9aaaf..b7a8f3b9 100644 --- a/tests/cassettes/test_client/test_get_items_without_ids.yaml +++ b/tests/cassettes/test_client/test_get_items_without_ids.yaml @@ -15,7 +15,7 @@ interactions: response: body: string: !!binary | - H4sIAPFZ42QC/81cbXPbNhL+KxjfzI0zV0iiZKeNb+4DrTfrznqppCTXu+ncQCBEIQEJFqCkqJ3+ + H4sIADWF42QC/81cbXPbNhL+KxjfzI0zV0iiZKeNb+4DrTfrznqppCTXu+ncQCBEIQEJFqCkqJ3+ 91uQlKy4TpqAgNtPHkvC7oPlYt/BXy7yQ8Yubi66JCdCxhffXPAI/k04VVLLdY4zCp/lPBfmV+Pj x2gmSMpyog6oK5NsmzOFFsuwi8LZCH4fMU0Vz3IuU1i1YETRDVkJhnRG4MOcJZlURKAESETAGZUL VjyNUZ+ofIM05SylDJlvNcs12kidswitDijfMPQ5IMBf54T+b8eULgEEjVajBR9Tma6lSvRSXtz8 @@ -73,30 +73,26 @@ interactions: 22Q55DPmXd5PI9ylUUMSXrwNGsgXb1v9e/Wa7n90irr/Eb2Z7wpnI1QRRedvFK+1lYp3o5DWE+Dl GXbzFu7mJk/E54BJujVTJw5uugIpsJU//vp/N/ssoZVdAAA= headers: - Accept-Ranges: - - bytes Access-Control-Allow-Credentials: - 'true' Access-Control-Allow-Origin: - '*' - Connection: - - keep-alive + Content-Encoding: + - gzip Content-Length: - '3227' Content-Type: - application/json Date: - - Mon, 21 Aug 2023 12:34:57 GMT + - Mon, 21 Aug 2023 15:39:32 GMT Strict-Transport-Security: - max-age=15724800; includeSubDomains + Vary: + - Accept-Encoding + X-Azure-Ref: + - 0NIXjZAAAAAD2Y2CtLmIMSrQ/AH4PbZbGREVOMzAxMDAwMTA5MDUzADkyN2FiZmE2LTE5ZjYtNGFmMS1hMDlkLWM5NTlkOWExZTY0NA== X-Cache: - CONFIG_NOCACHE - content-encoding: - - gzip - vary: - - Accept-Encoding - x-azure-ref: - - 20230821T123456Z-590cyt4v1d20h5yzdqguwr1mq80000000dhg000000004gv3 status: code: 200 message: OK @@ -120,7 +116,7 @@ interactions: response: body: string: !!binary | - H4sIAPFZ42QC/+3dDW/bRrov8K9CGDjH8a5lS3Lktt5zD5BVkioonU1td7O468JQLMXmrSy5ouTU + H4sIADWF42QC/+3dDW/bRrov8K9CGDjH8a5lS3Lktt5zD5BVkioonU1td7O468JQLMXmrSy5ouTU WPS73xmKkjjUzJAzfPEz0h/Yc9LEtMg/X0Ykf89D/mdv9vw43Dvbez/sz+bTYXcyGg1vZ8FkvHe4 93Xxb+He2b//sxcM2FS//PTu8rzVaDZ8/ygMHzvfd47arWaTTfvly+QPNl2j9X3zsPFD85D/+UPz 18PU57MpR8H4t8VHTocj9pPb5CzjqfuPj6Pgts//8fj/hdFP7qfDr+wn97PZY3h2fPw46o+Hs/70 @@ -494,30 +490,26 @@ interactions: QEQgIhARiAhEBCICEYGIQEQgIhARiAhEtETEXzfpb8w+PdOfVofEp39cXhXzqJDtuLf3XCsng+hW zyh44GNCix0We7PJb8NxvFBnkhs0Z2qnIgR3xWcTr6Q/f/3z/wM1VmvRoy4MAA== headers: - Accept-Ranges: - - bytes Access-Control-Allow-Credentials: - 'true' Access-Control-Allow-Origin: - '*' - Connection: - - keep-alive + Content-Encoding: + - gzip Content-Length: - '21250' Content-Type: - application/geo+json Date: - - Mon, 21 Aug 2023 12:34:57 GMT + - Mon, 21 Aug 2023 15:39:32 GMT Strict-Transport-Security: - max-age=15724800; includeSubDomains + Vary: + - Accept-Encoding + X-Azure-Ref: + - 0NYXjZAAAAACMHF2YdovWTo0b9bzBYQolREVOMzAxMDAwMTA5MDUzADkyN2FiZmE2LTE5ZjYtNGFmMS1hMDlkLWM5NTlkOWExZTY0NA== X-Cache: - CONFIG_NOCACHE - content-encoding: - - gzip - vary: - - Accept-Encoding - x-azure-ref: - - 20230821T123457Z-590cyt4v1d20h5yzdqguwr1mq80000000dhg000000004gxa status: code: 200 message: OK From 009590b586ed120dfef44ea312a6bae054ecab65 Mon Sep 17 00:00:00 2001 From: Pete Gadomski Date: Mon, 21 Aug 2023 09:46:39 -0600 Subject: [PATCH 3/3] fix: wayy overengineer _format_ids --- pystac_client/item_search.py | 17 +++++--- .../test_get_items_without_ids.yaml | 40 +++++++++++-------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/pystac_client/item_search.py b/pystac_client/item_search.py index 9710dfaf..497d7459 100644 --- a/pystac_client/item_search.py +++ b/pystac_client/item_search.py @@ -550,13 +550,18 @@ def _format(c: Any) -> Collections: @staticmethod def _format_ids(value: Optional[IDsLike]) -> Optional[IDs]: - if not value: + if value is None or isinstance(value, (tuple, list)) and not value: + # We can't just check for truthiness here because of the Iterator[str] case return None - - if isinstance(value, str): - return tuple(value.split(",")) - - return tuple(value) + elif isinstance(value, str): + # We could check for str in the first branch, but then we'd be checking + # for str twice #microoptimizations + if value: + return tuple(value.split(",")) + else: + return None + else: + return tuple(value) def _format_sortby(self, value: Optional[SortbyLike]) -> Optional[Sortby]: if value is None: diff --git a/tests/cassettes/test_client/test_get_items_without_ids.yaml b/tests/cassettes/test_client/test_get_items_without_ids.yaml index b7a8f3b9..83bd31e8 100644 --- a/tests/cassettes/test_client/test_get_items_without_ids.yaml +++ b/tests/cassettes/test_client/test_get_items_without_ids.yaml @@ -15,7 +15,7 @@ interactions: response: body: string: !!binary | - H4sIADWF42QC/81cbXPbNhL+KxjfzI0zV0iiZKeNb+4DrTfrznqppCTXu+ncQCBEIQEJFqCkqJ3+ + H4sIAImG42QC/81cbXPbNhL+KxjfzI0zV0iiZKeNb+4DrTfrznqppCTXu+ncQCBEIQEJFqCkqJ3+ 91uQlKy4TpqAgNtPHkvC7oPlYt/BXy7yQ8Yubi66JCdCxhffXPAI/k04VVLLdY4zCp/lPBfmV+Pj x2gmSMpyog6oK5NsmzOFFsuwi8LZCH4fMU0Vz3IuU1i1YETRDVkJhnRG4MOcJZlURKAESETAGZUL VjyNUZ+ofIM05SylDJlvNcs12kidswitDijfMPQ5IMBf54T+b8eULgEEjVajBR9Tma6lSvRSXtz8 @@ -73,26 +73,30 @@ interactions: 22Q55DPmXd5PI9ylUUMSXrwNGsgXb1v9e/Wa7n90irr/Eb2Z7wpnI1QRRedvFK+1lYp3o5DWE+Dl GXbzFu7mJk/E54BJujVTJw5uugIpsJU//vp/N/ssoZVdAAA= headers: + Accept-Ranges: + - bytes Access-Control-Allow-Credentials: - 'true' Access-Control-Allow-Origin: - '*' - Content-Encoding: - - gzip + Connection: + - keep-alive Content-Length: - '3227' Content-Type: - application/json Date: - - Mon, 21 Aug 2023 15:39:32 GMT + - Mon, 21 Aug 2023 15:45:14 GMT Strict-Transport-Security: - max-age=15724800; includeSubDomains - Vary: - - Accept-Encoding - X-Azure-Ref: - - 0NIXjZAAAAAD2Y2CtLmIMSrQ/AH4PbZbGREVOMzAxMDAwMTA5MDUzADkyN2FiZmE2LTE5ZjYtNGFmMS1hMDlkLWM5NTlkOWExZTY0NA== X-Cache: - CONFIG_NOCACHE + content-encoding: + - gzip + vary: + - Accept-Encoding + x-azure-ref: + - 20230821T154513Z-yr2m264nsp6bm42nunq3abrrpg0000000dhg00000001qhah status: code: 200 message: OK @@ -116,7 +120,7 @@ interactions: response: body: string: !!binary | - H4sIADWF42QC/+3dDW/bRrov8K9CGDjH8a5lS3Lktt5zD5BVkioonU1td7O468JQLMXmrSy5ouTU + H4sIAIqG42QC/+3dDW/bRrov8K9CGDjH8a5lS3Lktt5zD5BVkioonU1td7O468JQLMXmrSy5ouTU WPS73xmKkjjUzJAzfPEz0h/Yc9LEtMg/X0Ykf89D/mdv9vw43Dvbez/sz+bTYXcyGg1vZ8FkvHe4 93Xxb+He2b//sxcM2FS//PTu8rzVaDZ8/ygMHzvfd47arWaTTfvly+QPNl2j9X3zsPFD85D/+UPz 18PU57MpR8H4t8VHTocj9pPb5CzjqfuPj6Pgts//8fj/hdFP7qfDr+wn97PZY3h2fPw46o+Hs/70 @@ -490,26 +494,30 @@ interactions: QEQgIhARiAhEBCICEYGIQEQgIhARiAhEtETEXzfpb8w+PdOfVofEp39cXhXzqJDtuLf3XCsng+hW zyh44GNCix0We7PJb8NxvFBnkhs0Z2qnIgR3xWcTr6Q/f/3z/wM1VmvRoy4MAA== headers: + Accept-Ranges: + - bytes Access-Control-Allow-Credentials: - 'true' Access-Control-Allow-Origin: - '*' - Content-Encoding: - - gzip + Connection: + - keep-alive Content-Length: - '21250' Content-Type: - application/geo+json Date: - - Mon, 21 Aug 2023 15:39:32 GMT + - Mon, 21 Aug 2023 15:45:14 GMT Strict-Transport-Security: - max-age=15724800; includeSubDomains - Vary: - - Accept-Encoding - X-Azure-Ref: - - 0NYXjZAAAAACMHF2YdovWTo0b9bzBYQolREVOMzAxMDAwMTA5MDUzADkyN2FiZmE2LTE5ZjYtNGFmMS1hMDlkLWM5NTlkOWExZTY0NA== X-Cache: - CONFIG_NOCACHE + content-encoding: + - gzip + vary: + - Accept-Encoding + x-azure-ref: + - 20230821T154514Z-yr2m264nsp6bm42nunq3abrrpg0000000dhg00000001qhe9 status: code: 200 message: OK