Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

search: add new plugin CopDataSpaceSearch #1231

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion eodag/plugins/search/qssearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
from requests.adapters import HTTPAdapter
from requests.auth import AuthBase

from eodag.api.product import EOProduct
from eodag.api.product import AssetsDict, EOProduct
from eodag.api.product.metadata_mapping import (
NOT_AVAILABLE,
format_query_params,
Expand All @@ -81,6 +81,7 @@
format_dict_items,
get_args,
get_ssl_context,
guess_file_type,
quote,
string_to_jsonpath,
update_nested_dict,
Expand Down Expand Up @@ -1246,6 +1247,69 @@ def normalize_results(
return products


class CopDataSpaceSearch(ODataV4Search):
"""A specialisation of a ODataV4Search that performs a multi step search to retrieve
all products assets"""

def __init__(self, provider: str, config: PluginConfig) -> None:
super(CopDataSpaceSearch, self).__init__(provider, config)

def normalize_results(
self, results: RawSearchResult, **kwargs: Any
) -> List[EOProduct]:
"""Build EOProducts from provider results"""

products = super(CopDataSpaceSearch, self).normalize_results(results, **kwargs)

api_endpoint = self.config.api_endpoint.rstrip("/")
for product in products:
product.assets = {}
id = product.properties.get("uid")
name = product.properties.get("title")

base_url = f"{api_endpoint}({id})/Nodes({name})/Nodes(GRANULE)/Nodes"
response = self._request(
PreparedSearch(
url=base_url,
info_message="Fetching granule's list: {}".format(base_url),
exception_message="Skipping error while fetching granule list for product {}".format(
name
),
)
)
granule_list_json = response.json()
# loop over the list of granules
for granule in granule_list_json["result"]:
granule_url = f"{base_url}({granule['Id']})/Nodes(IMG_DATA)/Nodes"
response = self._request(
PreparedSearch(
url=granule_url,
info_message="Fetching granule: {}".format(granule_url),
exception_message="Skipping error while fetching granule {} for product {}".format(
granule["Id"], name
),
)
)
granule_json = response.json()
product.assets = AssetsDict(product)
# loop bands contained in a single granule
for band in granule_json["result"]:
# replace suffix "/Nodes" with "/$value" in the download link
band_url = band["Nodes"]["uri"]
band_url = band_url[: -len("/Nodes")] + "/$value"
asset_basename = f"{granule['Id']}/{band['Id']}"
product.assets[asset_basename] = {
"title": asset_basename,
"roles": ["data"],
"href": band_url,
}
logger.debug(f"Add asset {asset_basename}")
if mime_type := guess_file_type(band["Id"]):
product.assets[asset_basename]["type"] = mime_type

return products


class PostJsonSearch(QueryStringSearch):
"""A specialisation of a QueryStringSearch that uses POST method"""

Expand Down
2 changes: 1 addition & 1 deletion eodag/resources/providers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3845,7 +3845,7 @@
- host
url: https://dataspace.copernicus.eu/
search: !plugin
type: ODataV4Search
type: CopDataSpaceSearch
api_endpoint: 'https://catalogue.dataspace.copernicus.eu/odata/v1/Products'
need_auth: false
timeout: 120
Expand Down
Loading