eodag 3.0.1__py3-none-any.whl → 3.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- eodag/api/core.py +174 -138
- eodag/api/product/_assets.py +44 -15
- eodag/api/product/_product.py +58 -47
- eodag/api/product/drivers/__init__.py +81 -4
- eodag/api/product/drivers/base.py +65 -4
- eodag/api/product/drivers/generic.py +65 -0
- eodag/api/product/drivers/sentinel1.py +97 -0
- eodag/api/product/drivers/sentinel2.py +95 -0
- eodag/api/product/metadata_mapping.py +117 -90
- eodag/api/search_result.py +13 -23
- eodag/cli.py +26 -5
- eodag/config.py +86 -92
- eodag/plugins/apis/base.py +1 -1
- eodag/plugins/apis/ecmwf.py +42 -22
- eodag/plugins/apis/usgs.py +17 -16
- eodag/plugins/authentication/aws_auth.py +16 -13
- eodag/plugins/authentication/base.py +5 -3
- eodag/plugins/authentication/header.py +3 -3
- eodag/plugins/authentication/keycloak.py +4 -4
- eodag/plugins/authentication/oauth.py +7 -3
- eodag/plugins/authentication/openid_connect.py +22 -16
- eodag/plugins/authentication/sas_auth.py +4 -4
- eodag/plugins/authentication/token.py +41 -10
- eodag/plugins/authentication/token_exchange.py +1 -1
- eodag/plugins/base.py +4 -4
- eodag/plugins/crunch/base.py +4 -4
- eodag/plugins/crunch/filter_date.py +4 -4
- eodag/plugins/crunch/filter_latest_intersect.py +6 -6
- eodag/plugins/crunch/filter_latest_tpl_name.py +7 -7
- eodag/plugins/crunch/filter_overlap.py +4 -4
- eodag/plugins/crunch/filter_property.py +6 -7
- eodag/plugins/download/aws.py +146 -87
- eodag/plugins/download/base.py +38 -56
- eodag/plugins/download/creodias_s3.py +29 -0
- eodag/plugins/download/http.py +173 -183
- eodag/plugins/download/s3rest.py +10 -11
- eodag/plugins/manager.py +10 -20
- eodag/plugins/search/__init__.py +6 -5
- eodag/plugins/search/base.py +90 -46
- eodag/plugins/search/build_search_result.py +1048 -361
- eodag/plugins/search/cop_marine.py +22 -12
- eodag/plugins/search/creodias_s3.py +9 -73
- eodag/plugins/search/csw.py +11 -11
- eodag/plugins/search/data_request_search.py +19 -18
- eodag/plugins/search/qssearch.py +99 -258
- eodag/plugins/search/stac_list_assets.py +85 -0
- eodag/plugins/search/static_stac_search.py +4 -4
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +1134 -325
- eodag/resources/providers.yml +906 -2006
- eodag/resources/stac_api.yml +2 -2
- eodag/resources/user_conf_template.yml +10 -9
- eodag/rest/cache.py +2 -2
- eodag/rest/config.py +3 -3
- eodag/rest/core.py +112 -82
- eodag/rest/errors.py +5 -5
- eodag/rest/server.py +33 -14
- eodag/rest/stac.py +41 -38
- eodag/rest/types/collections_search.py +3 -3
- eodag/rest/types/eodag_search.py +29 -23
- eodag/rest/types/queryables.py +42 -31
- eodag/rest/types/stac_search.py +15 -25
- eodag/rest/utils/__init__.py +14 -21
- eodag/rest/utils/cql_evaluate.py +6 -6
- eodag/rest/utils/rfc3339.py +2 -2
- eodag/types/__init__.py +141 -32
- eodag/types/bbox.py +2 -2
- eodag/types/download_args.py +3 -3
- eodag/types/queryables.py +183 -72
- eodag/types/search_args.py +4 -4
- eodag/types/whoosh.py +127 -3
- eodag/utils/__init__.py +153 -51
- eodag/utils/exceptions.py +28 -21
- eodag/utils/import_system.py +2 -2
- eodag/utils/repr.py +65 -6
- eodag/utils/requests.py +13 -13
- eodag/utils/rest.py +2 -2
- eodag/utils/s3.py +231 -0
- eodag/utils/stac_reader.py +10 -10
- {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/METADATA +77 -76
- eodag-3.1.0.dist-info/RECORD +113 -0
- {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/WHEEL +1 -1
- {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/entry_points.txt +4 -2
- eodag/utils/constraints.py +0 -244
- eodag-3.0.1.dist-info/RECORD +0 -109
- {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/LICENSE +0 -0
- {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/top_level.txt +0 -0
|
@@ -22,7 +22,7 @@ import logging
|
|
|
22
22
|
import os
|
|
23
23
|
import re
|
|
24
24
|
from datetime import datetime
|
|
25
|
-
from typing import TYPE_CHECKING, Any,
|
|
25
|
+
from typing import TYPE_CHECKING, Any, Optional, cast
|
|
26
26
|
from urllib.parse import urlsplit
|
|
27
27
|
|
|
28
28
|
import boto3
|
|
@@ -69,8 +69,8 @@ def _get_date_from_yyyymmdd(date_str: str, item_key: str) -> Optional[datetime]:
|
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
def _get_dates_from_dataset_data(
|
|
72
|
-
dataset_item:
|
|
73
|
-
) -> Optional[
|
|
72
|
+
dataset_item: dict[str, Any]
|
|
73
|
+
) -> Optional[dict[str, str]]:
|
|
74
74
|
dates = {}
|
|
75
75
|
if "start_datetime" in dataset_item["properties"]:
|
|
76
76
|
dates["start"] = dataset_item["properties"]["start_datetime"]
|
|
@@ -96,7 +96,7 @@ def _get_s3_client(endpoint_url: str) -> S3Client:
|
|
|
96
96
|
)
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
def _check_int_values_properties(properties:
|
|
99
|
+
def _check_int_values_properties(properties: dict[str, Any]):
|
|
100
100
|
# remove int values with a bit length of more than 64 from the properties
|
|
101
101
|
invalid = []
|
|
102
102
|
for prop, prop_value in properties.items():
|
|
@@ -134,7 +134,7 @@ class CopMarineSearch(StaticStacSearch):
|
|
|
134
134
|
|
|
135
135
|
def _get_product_type_info(
|
|
136
136
|
self, product_type: str
|
|
137
|
-
) ->
|
|
137
|
+
) -> tuple[dict[str, Any], list[dict[str, Any]]]:
|
|
138
138
|
"""Fetch product type and associated datasets info"""
|
|
139
139
|
|
|
140
140
|
fetch_url = cast(str, self.config.discover_product_types["fetch_url"]).format(
|
|
@@ -183,13 +183,23 @@ class CopMarineSearch(StaticStacSearch):
|
|
|
183
183
|
product_id: str,
|
|
184
184
|
s3_url: str,
|
|
185
185
|
product_type: str,
|
|
186
|
-
dataset_item:
|
|
187
|
-
collection_dict:
|
|
186
|
+
dataset_item: dict[str, Any],
|
|
187
|
+
collection_dict: dict[str, Any],
|
|
188
188
|
):
|
|
189
|
+
# try to find date(s) in product id
|
|
190
|
+
item_dates = re.findall(r"(\d{4})(0[1-9]|1[0-2])([0-3]\d)", product_id)
|
|
191
|
+
if not item_dates:
|
|
192
|
+
item_dates = re.findall(r"_(\d{4})(0[1-9]|1[0-2])", product_id)
|
|
193
|
+
use_dataset_dates = not bool(item_dates)
|
|
189
194
|
for obj in collection_objects["Contents"]:
|
|
190
195
|
if product_id in obj["Key"]:
|
|
191
196
|
return self._create_product(
|
|
192
|
-
product_type,
|
|
197
|
+
product_type,
|
|
198
|
+
obj["Key"],
|
|
199
|
+
s3_url,
|
|
200
|
+
dataset_item,
|
|
201
|
+
collection_dict,
|
|
202
|
+
use_dataset_dates,
|
|
193
203
|
)
|
|
194
204
|
return None
|
|
195
205
|
|
|
@@ -198,8 +208,8 @@ class CopMarineSearch(StaticStacSearch):
|
|
|
198
208
|
product_type: str,
|
|
199
209
|
item_key: str,
|
|
200
210
|
s3_url: str,
|
|
201
|
-
dataset_item:
|
|
202
|
-
collection_dict:
|
|
211
|
+
dataset_item: dict[str, Any],
|
|
212
|
+
collection_dict: dict[str, Any],
|
|
203
213
|
use_dataset_dates: bool = False,
|
|
204
214
|
) -> Optional[EOProduct]:
|
|
205
215
|
|
|
@@ -278,7 +288,7 @@ class CopMarineSearch(StaticStacSearch):
|
|
|
278
288
|
self,
|
|
279
289
|
prep: PreparedSearch = PreparedSearch(),
|
|
280
290
|
**kwargs: Any,
|
|
281
|
-
) ->
|
|
291
|
+
) -> tuple[list[EOProduct], Optional[int]]:
|
|
282
292
|
"""
|
|
283
293
|
Implementation of search for the Copernicus Marine provider
|
|
284
294
|
:param prep: object containing search parameterds
|
|
@@ -298,7 +308,7 @@ class CopMarineSearch(StaticStacSearch):
|
|
|
298
308
|
"parameter product type is required for search with cop_marine provider"
|
|
299
309
|
)
|
|
300
310
|
collection_dict, datasets_items_list = self._get_product_type_info(product_type)
|
|
301
|
-
products:
|
|
311
|
+
products: list[EOProduct] = []
|
|
302
312
|
start_index = items_per_page * (page - 1) + 1
|
|
303
313
|
num_total = 0
|
|
304
314
|
for i, dataset_item in enumerate(datasets_items_list):
|
|
@@ -17,31 +17,22 @@
|
|
|
17
17
|
# limitations under the License.
|
|
18
18
|
import logging
|
|
19
19
|
from types import MethodType
|
|
20
|
-
from typing import Any
|
|
20
|
+
from typing import Any
|
|
21
21
|
|
|
22
|
-
import boto3
|
|
23
|
-
import botocore
|
|
24
22
|
from botocore.exceptions import BotoCoreError
|
|
25
23
|
|
|
26
|
-
from eodag.api.product import
|
|
24
|
+
from eodag.api.product import EOProduct # type: ignore
|
|
27
25
|
from eodag.api.search_result import RawSearchResult
|
|
28
|
-
from eodag.config import PluginConfig
|
|
29
|
-
from eodag.plugins.authentication.aws_auth import AwsAuth
|
|
30
26
|
from eodag.plugins.search.qssearch import ODataV4Search
|
|
31
|
-
from eodag.utils import
|
|
32
|
-
from eodag.utils.
|
|
33
|
-
AuthenticationError,
|
|
34
|
-
MisconfiguredError,
|
|
35
|
-
NotAvailableError,
|
|
36
|
-
RequestError,
|
|
37
|
-
)
|
|
27
|
+
from eodag.utils.exceptions import RequestError
|
|
28
|
+
from eodag.utils.s3 import update_assets_from_s3
|
|
38
29
|
|
|
39
|
-
DATA_EXTENSIONS = ["jp2", "tiff", "nc", "grib"]
|
|
40
30
|
logger = logging.getLogger("eodag.search.creodiass3")
|
|
41
31
|
|
|
42
32
|
|
|
43
33
|
def patched_register_downloader(self, downloader, authenticator):
|
|
44
34
|
"""Add the download information to the product.
|
|
35
|
+
|
|
45
36
|
:param self: product to which information should be added
|
|
46
37
|
:param downloader: The download method that it can use
|
|
47
38
|
:class:`~eodag.plugins.download.base.Download` or
|
|
@@ -53,68 +44,13 @@ def patched_register_downloader(self, downloader, authenticator):
|
|
|
53
44
|
self.register_downloader_only(downloader, authenticator)
|
|
54
45
|
# and also update assets
|
|
55
46
|
try:
|
|
56
|
-
|
|
47
|
+
update_assets_from_s3(
|
|
48
|
+
self, authenticator, getattr(downloader.config, "s3_endpoint", None)
|
|
49
|
+
)
|
|
57
50
|
except BotoCoreError as e:
|
|
58
51
|
raise RequestError.from_error(e, "could not update assets") from e
|
|
59
52
|
|
|
60
53
|
|
|
61
|
-
def _update_assets(product: EOProduct, config: PluginConfig, auth: AwsAuth):
|
|
62
|
-
product.assets = {}
|
|
63
|
-
prefix = (
|
|
64
|
-
product.properties.get("productIdentifier", None).replace("/eodata/", "") + "/"
|
|
65
|
-
)
|
|
66
|
-
if prefix:
|
|
67
|
-
try:
|
|
68
|
-
auth_dict = auth.authenticate()
|
|
69
|
-
required_creds = ["aws_access_key_id", "aws_secret_access_key"]
|
|
70
|
-
if not all(x in auth_dict for x in required_creds):
|
|
71
|
-
raise MisconfiguredError(
|
|
72
|
-
f"Incomplete credentials for {product.provider}, missing "
|
|
73
|
-
f"{[x for x in required_creds if x not in auth_dict]}"
|
|
74
|
-
)
|
|
75
|
-
if not getattr(auth, "s3_client", None):
|
|
76
|
-
auth.s3_client = boto3.client(
|
|
77
|
-
"s3",
|
|
78
|
-
endpoint_url=config.s3_endpoint,
|
|
79
|
-
aws_access_key_id=auth_dict["aws_access_key_id"],
|
|
80
|
-
aws_secret_access_key=auth_dict["aws_secret_access_key"],
|
|
81
|
-
)
|
|
82
|
-
logger.debug("Listing assets in %s", prefix)
|
|
83
|
-
product.assets = AssetsDict(product)
|
|
84
|
-
for asset in auth.s3_client.list_objects(
|
|
85
|
-
Bucket=config.s3_bucket, Prefix=prefix, MaxKeys=300
|
|
86
|
-
)["Contents"]:
|
|
87
|
-
asset_basename = (
|
|
88
|
-
asset["Key"].split("/")[-1] if "/" in asset["Key"] else asset["Key"]
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
if len(asset_basename) > 0 and asset_basename not in product.assets:
|
|
92
|
-
role = (
|
|
93
|
-
"data"
|
|
94
|
-
if asset_basename.split(".")[-1] in DATA_EXTENSIONS
|
|
95
|
-
else "metadata"
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
product.assets[asset_basename] = {
|
|
99
|
-
"title": asset_basename,
|
|
100
|
-
"roles": [role],
|
|
101
|
-
"href": f"s3://{config.s3_bucket}/{asset['Key']}",
|
|
102
|
-
}
|
|
103
|
-
if mime_type := guess_file_type(asset["Key"]):
|
|
104
|
-
product.assets[asset_basename]["type"] = mime_type
|
|
105
|
-
# update driver
|
|
106
|
-
product.driver = product.get_driver()
|
|
107
|
-
|
|
108
|
-
except botocore.exceptions.ClientError as e:
|
|
109
|
-
if str(auth.config.auth_error_code) in str(e):
|
|
110
|
-
raise AuthenticationError(
|
|
111
|
-
f"Authentication failed on {config.base_uri} s3"
|
|
112
|
-
) from e
|
|
113
|
-
raise NotAvailableError(
|
|
114
|
-
f"assets for product {prefix} could not be found"
|
|
115
|
-
) from e
|
|
116
|
-
|
|
117
|
-
|
|
118
54
|
class CreodiasS3Search(ODataV4Search):
|
|
119
55
|
"""
|
|
120
56
|
``CreodiasS3Search`` is an extension of :class:`~eodag.plugins.search.qssearch.ODataV4Search`,
|
|
@@ -133,7 +69,7 @@ class CreodiasS3Search(ODataV4Search):
|
|
|
133
69
|
|
|
134
70
|
def normalize_results(
|
|
135
71
|
self, results: RawSearchResult, **kwargs: Any
|
|
136
|
-
) ->
|
|
72
|
+
) -> list[EOProduct]:
|
|
137
73
|
"""Build EOProducts from provider results"""
|
|
138
74
|
|
|
139
75
|
products = super(CreodiasS3Search, self).normalize_results(results, **kwargs)
|
eodag/plugins/search/csw.py
CHANGED
|
@@ -19,7 +19,7 @@ from __future__ import annotations
|
|
|
19
19
|
|
|
20
20
|
import logging
|
|
21
21
|
import re
|
|
22
|
-
from typing import TYPE_CHECKING, Any,
|
|
22
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
|
23
23
|
|
|
24
24
|
import pyproj
|
|
25
25
|
from owslib.csw import CatalogueServiceWeb
|
|
@@ -60,13 +60,13 @@ class CSWSearch(Search):
|
|
|
60
60
|
* :attr:`~eodag.config.PluginConfig.api_endpoint` (``str``) (**mandatory**): The endpoint of the
|
|
61
61
|
provider's search interface
|
|
62
62
|
* :attr:`~eodag.config.PluginConfig.version` (``str``): OGC Catalogue Service version; default: ``2.0.2``
|
|
63
|
-
* :attr:`~eodag.config.PluginConfig.search_definition` (``
|
|
63
|
+
* :attr:`~eodag.config.PluginConfig.search_definition` (``dict[str, Any]``) (**mandatory**):
|
|
64
64
|
|
|
65
|
-
* **product_type_tags** (``
|
|
65
|
+
* **product_type_tags** (``list[dict[str, Any]``): dict of product type tags
|
|
66
66
|
* **resource_location_filter** (``str``): regex string
|
|
67
|
-
* **date_tags** (``
|
|
67
|
+
* **date_tags** (``dict[str, Any]``): tags for start and end
|
|
68
68
|
|
|
69
|
-
* :attr:`~eodag.config.PluginConfig.metadata_mapping` (``
|
|
69
|
+
* :attr:`~eodag.config.PluginConfig.metadata_mapping` (``dict[str, Any]``): The search plugins of this kind can
|
|
70
70
|
detect when a metadata mapping is "query-able", and get the semantics of how to format the query string
|
|
71
71
|
parameter that enables to make a query on the corresponding metadata. To make a metadata query-able,
|
|
72
72
|
just configure it in the metadata mapping to be a list of 2 items, the first one being the
|
|
@@ -107,7 +107,7 @@ class CSWSearch(Search):
|
|
|
107
107
|
self,
|
|
108
108
|
prep: PreparedSearch = PreparedSearch(),
|
|
109
109
|
**kwargs: Any,
|
|
110
|
-
) ->
|
|
110
|
+
) -> tuple[list[EOProduct], Optional[int]]:
|
|
111
111
|
"""Perform a search on a OGC/CSW-like interface"""
|
|
112
112
|
product_type = kwargs.get("productType")
|
|
113
113
|
if product_type is None:
|
|
@@ -117,7 +117,7 @@ class CSWSearch(Search):
|
|
|
117
117
|
self.__init_catalog(**getattr(auth.config, "credentials", {}))
|
|
118
118
|
else:
|
|
119
119
|
self.__init_catalog()
|
|
120
|
-
results:
|
|
120
|
+
results: list[EOProduct] = []
|
|
121
121
|
if self.catalog:
|
|
122
122
|
provider_product_type = self.config.products[product_type]["productType"]
|
|
123
123
|
for product_type_def in self.config.search_definition["product_type_tags"]:
|
|
@@ -229,12 +229,12 @@ class CSWSearch(Search):
|
|
|
229
229
|
|
|
230
230
|
def __convert_query_params(
|
|
231
231
|
self,
|
|
232
|
-
product_type_def:
|
|
232
|
+
product_type_def: dict[str, Any],
|
|
233
233
|
product_type: str,
|
|
234
|
-
params:
|
|
235
|
-
) -> Union[
|
|
234
|
+
params: dict[str, Any],
|
|
235
|
+
) -> Union[list[OgcExpression], list[list[OgcExpression]]]:
|
|
236
236
|
"""Translates eodag search to CSW constraints using owslib constraint classes"""
|
|
237
|
-
constraints:
|
|
237
|
+
constraints: list[OgcExpression] = []
|
|
238
238
|
# How the match should be performed (fuzzy, prefix, postfix or exact).
|
|
239
239
|
# defaults to fuzzy
|
|
240
240
|
pt_tag, matching = (
|
|
@@ -20,7 +20,7 @@ from __future__ import annotations
|
|
|
20
20
|
import logging
|
|
21
21
|
import time
|
|
22
22
|
from datetime import datetime, timedelta, timezone
|
|
23
|
-
from typing import TYPE_CHECKING, Any,
|
|
23
|
+
from typing import TYPE_CHECKING, Any, Optional, cast
|
|
24
24
|
|
|
25
25
|
import requests
|
|
26
26
|
|
|
@@ -36,6 +36,7 @@ from eodag.utils import (
|
|
|
36
36
|
DEFAULT_ITEMS_PER_PAGE,
|
|
37
37
|
DEFAULT_MISSION_START_DATE,
|
|
38
38
|
DEFAULT_PAGE,
|
|
39
|
+
DEFAULT_SEARCH_TIMEOUT,
|
|
39
40
|
GENERIC_PRODUCT_TYPE,
|
|
40
41
|
HTTP_REQ_TIMEOUT,
|
|
41
42
|
USER_AGENT,
|
|
@@ -113,10 +114,10 @@ class DataRequestSearch(Search):
|
|
|
113
114
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.generic_product_type_id` (``str``): mapping for the
|
|
114
115
|
product type id
|
|
115
116
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.generic_product_type_parsable_metadata`
|
|
116
|
-
(``
|
|
117
|
+
(``dict[str, str]``): mapping for product type metadata (e.g. ``abstract``, ``licence``) which can be parsed
|
|
117
118
|
from the provider result
|
|
118
119
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.generic_product_type_parsable_properties`
|
|
119
|
-
(``
|
|
120
|
+
(``dict[str, str]``): mapping for product type properties which can be parsed from the result and are not
|
|
120
121
|
product type metadata
|
|
121
122
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.single_collection_fetch_url` (``str``): url to fetch
|
|
122
123
|
data for a single collection; used if product type metadata is not available from the endpoint given in
|
|
@@ -125,7 +126,7 @@ class DataRequestSearch(Search):
|
|
|
125
126
|
to be added to the :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.fetch_url` to filter for a
|
|
126
127
|
collection
|
|
127
128
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.single_product_type_parsable_metadata`
|
|
128
|
-
(``
|
|
129
|
+
(``dict[str, str]``): mapping for product type metadata returned by the endpoint given in
|
|
129
130
|
:attr:`~eodag.config.PluginConfig.DiscoverProductTypes.single_collection_fetch_url`.
|
|
130
131
|
|
|
131
132
|
* :attr:`~eodag.config.PluginConfig.constraints_file_url` (``str``): url to fetch the constraints for a specific
|
|
@@ -133,7 +134,7 @@ class DataRequestSearch(Search):
|
|
|
133
134
|
* :attr:`~eodag.config.PluginConfig.constraints_entry` (``str``): key in the json result where the constraints
|
|
134
135
|
can be found; if not given, it is assumed that the constraints are on top level of the result, i.e.
|
|
135
136
|
the result is an array of constraints
|
|
136
|
-
* :attr:`~eodag.config.PluginConfig.metadata_mapping` (``
|
|
137
|
+
* :attr:`~eodag.config.PluginConfig.metadata_mapping` (``dict[str, Any]``): The search plugins of this kind can
|
|
137
138
|
detect when a metadata mapping is "query-able", and get the semantics of how to format the query string
|
|
138
139
|
parameter that enables to make a query on the corresponding metadata. To make a metadata query-able,
|
|
139
140
|
just configure it in the metadata mapping to be a list of 2 items, the first one being the
|
|
@@ -186,7 +187,7 @@ class DataRequestSearch(Search):
|
|
|
186
187
|
)
|
|
187
188
|
if other_product_for_mapping:
|
|
188
189
|
other_product_type_def_params = self.get_product_type_def_params(
|
|
189
|
-
other_product_for_mapping,
|
|
190
|
+
other_product_for_mapping,
|
|
190
191
|
)
|
|
191
192
|
product_type_metadata_mapping.update(
|
|
192
193
|
other_product_type_def_params.get("metadata_mapping", {})
|
|
@@ -207,10 +208,10 @@ class DataRequestSearch(Search):
|
|
|
207
208
|
self.config.pagination["next_page_url_key_path"] = string_to_jsonpath(
|
|
208
209
|
self.config.pagination.get("next_page_url_key_path", None)
|
|
209
210
|
)
|
|
210
|
-
self.download_info:
|
|
211
|
+
self.download_info: dict[str, Any] = {}
|
|
211
212
|
self.data_request_id = None
|
|
212
213
|
|
|
213
|
-
def discover_product_types(self, **kwargs: Any) -> Optional[
|
|
214
|
+
def discover_product_types(self, **kwargs: Any) -> Optional[dict[str, Any]]:
|
|
214
215
|
"""Fetch product types is disabled for `DataRequestSearch`
|
|
215
216
|
|
|
216
217
|
:returns: empty dict
|
|
@@ -226,7 +227,7 @@ class DataRequestSearch(Search):
|
|
|
226
227
|
self,
|
|
227
228
|
prep: PreparedSearch = PreparedSearch(),
|
|
228
229
|
**kwargs: Any,
|
|
229
|
-
) ->
|
|
230
|
+
) -> tuple[list[EOProduct], Optional[int]]:
|
|
230
231
|
"""
|
|
231
232
|
performs the search for a provider where several steps are required to fetch the data
|
|
232
233
|
"""
|
|
@@ -252,7 +253,7 @@ class DataRequestSearch(Search):
|
|
|
252
253
|
|
|
253
254
|
# provider product type specific conf
|
|
254
255
|
self.product_type_def_params = self.get_product_type_def_params(
|
|
255
|
-
product_type,
|
|
256
|
+
product_type, format_variables=kwargs
|
|
256
257
|
)
|
|
257
258
|
|
|
258
259
|
# update config using provider product type definition metadata_mapping
|
|
@@ -262,7 +263,7 @@ class DataRequestSearch(Search):
|
|
|
262
263
|
)
|
|
263
264
|
if other_product_for_mapping:
|
|
264
265
|
other_product_type_def_params = self.get_product_type_def_params(
|
|
265
|
-
other_product_for_mapping,
|
|
266
|
+
other_product_for_mapping, format_variables=kwargs
|
|
266
267
|
)
|
|
267
268
|
self.config.metadata_mapping.update(
|
|
268
269
|
other_product_type_def_params.get("metadata_mapping", {})
|
|
@@ -308,7 +309,7 @@ class DataRequestSearch(Search):
|
|
|
308
309
|
request_finished = True
|
|
309
310
|
|
|
310
311
|
# loop to check search job status
|
|
311
|
-
search_timeout = int(getattr(self.config, "timeout",
|
|
312
|
+
search_timeout = int(getattr(self.config, "timeout", DEFAULT_SEARCH_TIMEOUT))
|
|
312
313
|
logger.info(
|
|
313
314
|
f"checking status of request job {data_request_id} (timeout={search_timeout}s)"
|
|
314
315
|
)
|
|
@@ -431,7 +432,7 @@ class DataRequestSearch(Search):
|
|
|
431
432
|
|
|
432
433
|
def _get_result_data(
|
|
433
434
|
self, data_request_id: str, items_per_page: int, page: int
|
|
434
|
-
) ->
|
|
435
|
+
) -> dict[str, Any]:
|
|
435
436
|
page = page - 1 + self.config.pagination.get("start_page", 1)
|
|
436
437
|
url = self.config.result_url.format(
|
|
437
438
|
jobId=data_request_id, items_per_page=items_per_page, page=page
|
|
@@ -450,18 +451,18 @@ class DataRequestSearch(Search):
|
|
|
450
451
|
|
|
451
452
|
def _convert_result_data(
|
|
452
453
|
self,
|
|
453
|
-
result_data:
|
|
454
|
+
result_data: dict[str, Any],
|
|
454
455
|
data_request_id: str,
|
|
455
456
|
product_type: str,
|
|
456
457
|
**kwargs: Any,
|
|
457
|
-
) ->
|
|
458
|
+
) -> tuple[list[EOProduct], int]:
|
|
458
459
|
"""Build EOProducts from provider results"""
|
|
459
460
|
results_entry = self.config.results_entry
|
|
460
461
|
results = result_data[results_entry]
|
|
461
462
|
logger.debug(
|
|
462
463
|
"Adapting %s plugin results to eodag product representation" % len(results)
|
|
463
464
|
)
|
|
464
|
-
products:
|
|
465
|
+
products: list[EOProduct] = []
|
|
465
466
|
for result in results:
|
|
466
467
|
product = EOProduct(
|
|
467
468
|
self.provider,
|
|
@@ -517,8 +518,8 @@ class DataRequestSearch(Search):
|
|
|
517
518
|
return False
|
|
518
519
|
|
|
519
520
|
def _apply_additional_filters(
|
|
520
|
-
self, result:
|
|
521
|
-
) ->
|
|
521
|
+
self, result: dict[str, Any], custom_filters: dict[str, str]
|
|
522
|
+
) -> dict[str, Any]:
|
|
522
523
|
filtered_result = []
|
|
523
524
|
results_entry = self.config.results_entry
|
|
524
525
|
results = result[results_entry]
|