diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f3bca95..e934c3c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Fixed +- Values from `parameters` and `headers` arguments to `Client.open` and `Client.from_file` are now also used in requests made from `CollectionClient` instances + fetched from the same API ([#126](https://github.com/stac-utils/pystac-client/pull/126)) - The tests folder is no longer installed as a package. ## [0.3.1] - 2021-11-17 diff --git a/pystac_client/client.py b/pystac_client/client.py index c623f6a6..695f2735 100644 --- a/pystac_client/client.py +++ b/pystac_client/client.py @@ -89,7 +89,7 @@ def get_collection(self, collection_id: str) -> CollectionClient: """ if self._stac_io.conforms_to(ConformanceClasses.COLLECTIONS): url = f"{self.get_self_href()}/collections/{collection_id}" - collection = CollectionClient.from_dict(self._stac_io.read_json(url)) + collection = CollectionClient.from_dict(self._stac_io.read_json(url), root=self) return collection else: for col in self.get_collections(): diff --git a/pystac_client/collection_client.py b/pystac_client/collection_client.py index 4b22f91f..991176a5 100644 --- a/pystac_client/collection_client.py +++ b/pystac_client/collection_client.py @@ -23,7 +23,7 @@ def get_items(self) -> Iterable["Item_Type"]: link = self.get_single_link('items') if link is not None: - search = ItemSearch(link.href, method='GET') + search = ItemSearch(link.href, method='GET', stac_io=self.get_root()._stac_io) yield from search.get_items() else: yield from super().get_items() diff --git a/tests/test_client.py b/tests/test_client.py index 83ee40ca..96f01654 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -144,6 +144,111 @@ def test_custom_request_parameters(self, requests_mock): assert len(actual_qp[init_qp_name]) == 1 assert actual_qp[init_qp_name][0] == init_qp_value + def test_custom_query_params_get_collections_propagation(self, requests_mock) -> None: + """Checks that query params passed to the init method are added to requests for CollectionClients fetched from + the /collections endpoint.""" + pc_root_text = read_data_file("planetary-computer-root.json") + pc_collection_dict = read_data_file("planetary-computer-collection.json", parse_json=True) + + requests_mock.get(STAC_URLS["PLANETARY-COMPUTER"], status_code=200, text=pc_root_text) + + init_qp_name = "my-param" + init_qp_value = "some-value" + + client = Client.open(STAC_URLS['PLANETARY-COMPUTER'], + parameters={init_qp_name: init_qp_value}) + + # Get the /collections endpoint + collections_link = client.get_single_link("data") + + # Mock the request + requests_mock.get(collections_link.href, + status_code=200, + json={ + "collections": [pc_collection_dict], + "links": [] + }) + + # Make the collections request + collection = next(client.get_collections()) + + # Mock the items endpoint + items_link = collection.get_single_link('items') + assert items_link is not None + requests_mock.get(items_link.href, + status_code=200, + json={ + "type": "FeatureCollection", + "stac_version": "1.0.0", + "features": [], + "links": [] + }) + + # Make the items request + _ = list(collection.get_items()) + + history = requests_mock.request_history + assert len(history) == 3 + + actual_qs = urlsplit(history[2].url).query + actual_qp = parse_qs(actual_qs) + + # Check that the query param from the root Client is present + assert init_qp_name in actual_qp + assert len(actual_qp[init_qp_name]) == 1 + assert actual_qp[init_qp_name][0] == init_qp_value + + def test_custom_query_params_get_collection_propagation(self, requests_mock) -> None: + """Checks that query params passed to the init method are added to requests for CollectionClients fetched from + the /collections endpoint.""" + pc_root_text = read_data_file("planetary-computer-root.json") + pc_collection_dict = read_data_file("planetary-computer-collection.json", parse_json=True) + pc_collection_id = pc_collection_dict["id"] + + requests_mock.get(STAC_URLS["PLANETARY-COMPUTER"], status_code=200, text=pc_root_text) + + init_qp_name = "my-param" + init_qp_value = "some-value" + + client = Client.open(STAC_URLS['PLANETARY-COMPUTER'], + parameters={init_qp_name: init_qp_value}) + + # Get the /collections endpoint + collections_link = client.get_single_link("data") + collection_href = collections_link.href + "/" + pc_collection_id + + # Mock the request + requests_mock.get(collection_href, status_code=200, json=pc_collection_dict) + + # Make the collections request + collection = client.get_collection(pc_collection_id) + + # Mock the items endpoint + items_link = collection.get_single_link('items') + assert items_link is not None + requests_mock.get(items_link.href, + status_code=200, + json={ + "type": "FeatureCollection", + "stac_version": "1.0.0", + "features": [], + "links": [] + }) + + # Make the items request + _ = list(collection.get_items()) + + history = requests_mock.request_history + assert len(history) == 3 + + actual_qs = urlsplit(history[2].url).query + actual_qp = parse_qs(actual_qs) + + # Check that the query param from the root Client is present + assert init_qp_name in actual_qp + assert len(actual_qp[init_qp_name]) == 1 + assert actual_qp[init_qp_name][0] == init_qp_value + def test_get_collections_without_conformance(self, requests_mock): """Checks that the "data" endpoint is used if the API published the collections conformance class.""" pc_root_dict = read_data_file("planetary-computer-root.json", parse_json=True)