diff --git a/eodag/resources/providers.yml b/eodag/resources/providers.yml index 044de6b35..c3af8f28e 100644 --- a/eodag/resources/providers.yml +++ b/eodag/resources/providers.yml @@ -839,6 +839,8 @@ # Additional metadata provided by the providers but that don't appear in the reference spec thumbnail: '$.properties.thumbnail' + links: $.null + services: $.null products: S1_SAR_OCN: productType: OCN diff --git a/eodag/rest/stac.py b/eodag/rest/stac.py index cddcbd1ff..f6146dc57 100644 --- a/eodag/rest/stac.py +++ b/eodag/rest/stac.py @@ -29,6 +29,7 @@ import shapefile from dateutil import tz from dateutil.relativedelta import relativedelta +from jsonpath_ng.jsonpath import Child from shapely.geometry import shape from shapely.geometry.base import BaseGeometry from shapely.ops import unary_union @@ -68,6 +69,36 @@ STAC_CATALOGS_PREFIX = "catalogs" +# fields not to put in item properties +COLLECTION_PROPERTIES = [ + "abstract", + "instrument", + "platform", + "platformSerialIdentifier", + "processingLevel", + "sensorType", + "md5", + "license", + "title", + "missionStartDate", + "missionEndDate", + "keywords", + "stacCollection", +] +IGNORED_ITEM_PROPERTIES = [ + "_id", + "id", + "keyword", + "quicklook", + "thumbnail", + "downloadLink", + "orderLink", + "_dc_qs", + "qs", + "defaultGeometry", + "_date", +] + class StacCommon: """Stac common object @@ -248,6 +279,13 @@ def __get_item_list( k, item_model["properties"][k] ) + item_props = [ + p.right.fields[0] + for p in item_model["properties"].values() + if isinstance(p, Child) + ] + ignored_props = COLLECTION_PROPERTIES + item_props + IGNORED_ITEM_PROPERTIES + item_list: List[Dict[str, Any]] = [] for product in search_results: product_dict = deepcopy(product.__dict__) @@ -259,6 +297,17 @@ def __get_item_list( "providers": [self.get_provider_dict(product.provider)], }, ) + + # add additional item props + for p in set(product.properties) - set(ignored_props): + prefix = getattr( + self.eodag_api.providers_config[product.provider], + "group", + product.provider, + ) + key = p if ":" in p else f"{prefix}:{p}" + product_item["properties"][key] = product.properties[p] + # parse download link downloadlink_href = ( f"{catalog['url']}/items/{product.properties['title']}/download" @@ -716,7 +765,11 @@ def __generate_stac_collection( ) except TypeError as e: logger.warning( - f"Could not merge keywords from external collection for {product_type}: {str(e)}" + f"Could not merge keywords from external collection for {product_type['ID']}: {str(e)}" + ) + logger.debug( + f"External collection keywords: {str(ext_stac_collection['keywords'])}, ", + f"Product type keywords: {str(product_type_collection['keywords'])}", ) # merge providers diff --git a/tests/units/test_http_server.py b/tests/units/test_http_server.py index 92664e983..8ff5bd421 100644 --- a/tests/units/test_http_server.py +++ b/tests/units/test_http_server.py @@ -223,6 +223,7 @@ def mock_search_result(self): "sensorMode": None, "quicklook": None, "storageStatus": ONLINE_STATUS, + "providerProperty": "foo", }, "id": "578f1768-e66e-5b86-9363-b19f8931cc7b", "type": "Feature", @@ -826,6 +827,9 @@ def test_date_search_from_catalog_items_with_provider(self): self_link = link self.assertIsNotNone(self_link) self.assertIn("?provider=peps", self_link["href"]) + self.assertEqual( + results["features"][0]["properties"]["peps:providerProperty"], "foo" + ) def test_search_item_id_from_catalog(self): """Search by id through eodag server /catalog endpoint should return a valid response"""