eodag 2.12.0__py3-none-any.whl → 3.0.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/__init__.py +6 -8
- eodag/api/core.py +654 -538
- eodag/api/product/__init__.py +12 -2
- eodag/api/product/_assets.py +59 -16
- eodag/api/product/_product.py +100 -93
- eodag/api/product/drivers/__init__.py +7 -2
- eodag/api/product/drivers/base.py +0 -3
- eodag/api/product/metadata_mapping.py +192 -96
- eodag/api/search_result.py +69 -10
- eodag/cli.py +55 -25
- eodag/config.py +391 -116
- eodag/plugins/apis/base.py +11 -165
- eodag/plugins/apis/ecmwf.py +36 -25
- eodag/plugins/apis/usgs.py +80 -35
- eodag/plugins/authentication/aws_auth.py +13 -4
- eodag/plugins/authentication/base.py +10 -1
- eodag/plugins/authentication/generic.py +2 -2
- eodag/plugins/authentication/header.py +31 -6
- eodag/plugins/authentication/keycloak.py +17 -84
- eodag/plugins/authentication/oauth.py +3 -3
- eodag/plugins/authentication/openid_connect.py +268 -49
- eodag/plugins/authentication/qsauth.py +4 -1
- eodag/plugins/authentication/sas_auth.py +9 -2
- eodag/plugins/authentication/token.py +98 -47
- eodag/plugins/authentication/token_exchange.py +122 -0
- eodag/plugins/crunch/base.py +3 -1
- eodag/plugins/crunch/filter_date.py +3 -9
- eodag/plugins/crunch/filter_latest_intersect.py +0 -3
- eodag/plugins/crunch/filter_latest_tpl_name.py +1 -4
- eodag/plugins/crunch/filter_overlap.py +4 -8
- eodag/plugins/crunch/filter_property.py +5 -11
- eodag/plugins/download/aws.py +149 -185
- eodag/plugins/download/base.py +88 -97
- eodag/plugins/download/creodias_s3.py +1 -1
- eodag/plugins/download/http.py +638 -310
- eodag/plugins/download/s3rest.py +47 -45
- eodag/plugins/manager.py +228 -88
- eodag/plugins/search/__init__.py +36 -0
- eodag/plugins/search/base.py +239 -30
- eodag/plugins/search/build_search_result.py +382 -37
- eodag/plugins/search/cop_marine.py +441 -0
- eodag/plugins/search/creodias_s3.py +25 -20
- eodag/plugins/search/csw.py +5 -7
- eodag/plugins/search/data_request_search.py +61 -30
- eodag/plugins/search/qssearch.py +713 -255
- eodag/plugins/search/static_stac_search.py +106 -40
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +1921 -34
- eodag/resources/providers.yml +4091 -3655
- eodag/resources/stac.yml +50 -216
- eodag/resources/stac_api.yml +71 -25
- eodag/resources/stac_provider.yml +5 -0
- eodag/resources/user_conf_template.yml +89 -32
- eodag/rest/__init__.py +6 -0
- eodag/rest/cache.py +70 -0
- eodag/rest/config.py +68 -0
- eodag/rest/constants.py +26 -0
- eodag/rest/core.py +735 -0
- eodag/rest/errors.py +178 -0
- eodag/rest/server.py +264 -431
- eodag/rest/stac.py +442 -836
- eodag/rest/types/collections_search.py +44 -0
- eodag/rest/types/eodag_search.py +238 -47
- eodag/rest/types/queryables.py +164 -0
- eodag/rest/types/stac_search.py +273 -0
- eodag/rest/utils/__init__.py +216 -0
- eodag/rest/utils/cql_evaluate.py +119 -0
- eodag/rest/utils/rfc3339.py +64 -0
- eodag/types/__init__.py +106 -10
- eodag/types/bbox.py +15 -14
- eodag/types/download_args.py +40 -0
- eodag/types/search_args.py +57 -7
- eodag/types/whoosh.py +79 -0
- eodag/utils/__init__.py +110 -91
- eodag/utils/constraints.py +37 -45
- eodag/utils/exceptions.py +39 -22
- eodag/utils/import_system.py +0 -4
- eodag/utils/logging.py +37 -80
- eodag/utils/notebook.py +4 -4
- eodag/utils/repr.py +113 -0
- eodag/utils/requests.py +128 -0
- eodag/utils/rest.py +100 -0
- eodag/utils/stac_reader.py +93 -21
- {eodag-2.12.0.dist-info → eodag-3.0.0.dist-info}/METADATA +88 -53
- eodag-3.0.0.dist-info/RECORD +109 -0
- {eodag-2.12.0.dist-info → eodag-3.0.0.dist-info}/WHEEL +1 -1
- {eodag-2.12.0.dist-info → eodag-3.0.0.dist-info}/entry_points.txt +7 -5
- eodag/plugins/apis/cds.py +0 -540
- eodag/rest/types/stac_queryables.py +0 -134
- eodag/rest/utils.py +0 -1133
- eodag-2.12.0.dist-info/RECORD +0 -94
- {eodag-2.12.0.dist-info → eodag-3.0.0.dist-info}/LICENSE +0 -0
- {eodag-2.12.0.dist-info → eodag-3.0.0.dist-info}/top_level.txt +0 -0
eodag/plugins/search/base.py
CHANGED
|
@@ -18,24 +18,37 @@
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
import logging
|
|
21
|
-
from typing import TYPE_CHECKING
|
|
21
|
+
from typing import TYPE_CHECKING
|
|
22
22
|
|
|
23
|
+
import orjson
|
|
23
24
|
from pydantic.fields import Field, FieldInfo
|
|
24
25
|
|
|
25
26
|
from eodag.api.product.metadata_mapping import (
|
|
26
27
|
DEFAULT_METADATA_MAPPING,
|
|
28
|
+
NOT_MAPPED,
|
|
27
29
|
mtd_cfg_as_conversion_and_querypath,
|
|
28
30
|
)
|
|
29
31
|
from eodag.plugins.base import PluginTopic
|
|
32
|
+
from eodag.plugins.search import PreparedSearch
|
|
33
|
+
from eodag.types import model_fields_to_annotated
|
|
34
|
+
from eodag.types.queryables import Queryables
|
|
35
|
+
from eodag.types.search_args import SortByList
|
|
30
36
|
from eodag.utils import (
|
|
31
|
-
DEFAULT_ITEMS_PER_PAGE,
|
|
32
|
-
DEFAULT_PAGE,
|
|
33
37
|
GENERIC_PRODUCT_TYPE,
|
|
34
38
|
Annotated,
|
|
39
|
+
copy_deepcopy,
|
|
40
|
+
deepcopy,
|
|
35
41
|
format_dict_items,
|
|
42
|
+
get_args,
|
|
43
|
+
update_nested_dict,
|
|
36
44
|
)
|
|
45
|
+
from eodag.utils.exceptions import ValidationError
|
|
37
46
|
|
|
38
47
|
if TYPE_CHECKING:
|
|
48
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
49
|
+
|
|
50
|
+
from requests.auth import AuthBase
|
|
51
|
+
|
|
39
52
|
from eodag.api.product import EOProduct
|
|
40
53
|
from eodag.config import PluginConfig
|
|
41
54
|
|
|
@@ -46,16 +59,21 @@ class Search(PluginTopic):
|
|
|
46
59
|
"""Base Search Plugin.
|
|
47
60
|
|
|
48
61
|
:param provider: An EODAG provider name
|
|
49
|
-
:type provider: str
|
|
50
62
|
:param config: An EODAG plugin configuration
|
|
51
|
-
:type config: :class:`~eodag.config.PluginConfig`
|
|
52
63
|
"""
|
|
53
64
|
|
|
65
|
+
auth: Union[AuthBase, Dict[str, str]]
|
|
66
|
+
next_page_url: Optional[str]
|
|
67
|
+
next_page_query_obj: Optional[Dict[str, Any]]
|
|
68
|
+
total_items_nb: int
|
|
69
|
+
need_count: bool
|
|
70
|
+
_request: Any # needed by deprecated load_stac_items
|
|
71
|
+
|
|
54
72
|
def __init__(self, provider: str, config: PluginConfig) -> None:
|
|
55
73
|
super(Search, self).__init__(provider, config)
|
|
56
74
|
# Prepare the metadata mapping
|
|
57
75
|
# Do a shallow copy, the structure is flat enough for this to be sufficient
|
|
58
|
-
metas = DEFAULT_METADATA_MAPPING.copy()
|
|
76
|
+
metas: Dict[str, Any] = DEFAULT_METADATA_MAPPING.copy()
|
|
59
77
|
# Update the defaults with the mapping value. This will add any new key
|
|
60
78
|
# added by the provider mapping that is not in the default metadata
|
|
61
79
|
if self.config.metadata_mapping:
|
|
@@ -72,21 +90,18 @@ class Search(PluginTopic):
|
|
|
72
90
|
|
|
73
91
|
def query(
|
|
74
92
|
self,
|
|
75
|
-
|
|
76
|
-
items_per_page: int = DEFAULT_ITEMS_PER_PAGE,
|
|
77
|
-
page: int = DEFAULT_PAGE,
|
|
78
|
-
count: bool = True,
|
|
93
|
+
prep: PreparedSearch = PreparedSearch(),
|
|
79
94
|
**kwargs: Any,
|
|
80
95
|
) -> Tuple[List[EOProduct], Optional[int]]:
|
|
81
96
|
"""Implementation of how the products must be searched goes here.
|
|
82
97
|
|
|
83
98
|
This method must return a tuple with (1) a list of EOProduct instances (see eodag.api.product module)
|
|
84
99
|
which will be processed by a Download plugin (2) and the total number of products matching
|
|
85
|
-
the search criteria. If ``count`` is False, the second element returned must be ``None``.
|
|
100
|
+
the search criteria. If ``prep.count`` is False, the second element returned must be ``None``.
|
|
86
101
|
"""
|
|
87
102
|
raise NotImplementedError("A Search plugin must implement a method named query")
|
|
88
103
|
|
|
89
|
-
def discover_product_types(self) -> Optional[Dict[str, Any]]:
|
|
104
|
+
def discover_product_types(self, **kwargs: Any) -> Optional[Dict[str, Any]]:
|
|
90
105
|
"""Fetch product types list from provider using `discover_product_types` conf"""
|
|
91
106
|
return None
|
|
92
107
|
|
|
@@ -97,25 +112,25 @@ class Search(PluginTopic):
|
|
|
97
112
|
|
|
98
113
|
:param kwargs: additional filters for queryables (`productType` and other search
|
|
99
114
|
arguments)
|
|
100
|
-
:type kwargs: Any
|
|
101
115
|
:returns: fetched queryable parameters dict
|
|
102
|
-
:rtype: Optional[Dict[str, Annotated[Any, FieldInfo]]]
|
|
103
116
|
"""
|
|
104
|
-
|
|
117
|
+
raise NotImplementedError(
|
|
118
|
+
f"discover_queryables is not implemeted for plugin {self.__class__.__name__}"
|
|
119
|
+
)
|
|
105
120
|
|
|
106
|
-
def
|
|
121
|
+
def _get_defaults_as_queryables(
|
|
107
122
|
self, product_type: str
|
|
108
123
|
) -> Dict[str, Annotated[Any, FieldInfo]]:
|
|
109
124
|
"""
|
|
110
|
-
Return given product type
|
|
125
|
+
Return given product type default settings as queryables
|
|
111
126
|
|
|
112
127
|
:param product_type: given product type
|
|
113
|
-
:type product_type: str
|
|
114
128
|
:returns: queryable parameters dict
|
|
115
|
-
:rtype: Dict[str, Annotated[Any, FieldInfo]]
|
|
116
129
|
"""
|
|
117
|
-
defaults = self.config.products.get(product_type, {})
|
|
118
|
-
|
|
130
|
+
defaults = deepcopy(self.config.products.get(product_type, {}))
|
|
131
|
+
defaults.pop("metadata_mapping", None)
|
|
132
|
+
|
|
133
|
+
queryables: Dict[str, Annotated[Any, FieldInfo]] = {}
|
|
119
134
|
for parameter, value in defaults.items():
|
|
120
135
|
queryables[parameter] = Annotated[type(value), Field(default=value)]
|
|
121
136
|
return queryables
|
|
@@ -126,9 +141,7 @@ class Search(PluginTopic):
|
|
|
126
141
|
"""Get the provider product type from eodag product type
|
|
127
142
|
|
|
128
143
|
:param product_type: eodag product type
|
|
129
|
-
:type product_type: str
|
|
130
144
|
:returns: provider product type
|
|
131
|
-
:rtype: str
|
|
132
145
|
"""
|
|
133
146
|
if product_type is None:
|
|
134
147
|
return None
|
|
@@ -143,9 +156,7 @@ class Search(PluginTopic):
|
|
|
143
156
|
"""Get the provider product type definition parameters and specific settings
|
|
144
157
|
|
|
145
158
|
:param product_type: the desired product type
|
|
146
|
-
:type product_type: str
|
|
147
159
|
:returns: The product type definition parameters
|
|
148
|
-
:rtype: dict
|
|
149
160
|
"""
|
|
150
161
|
if product_type in self.config.products.keys():
|
|
151
162
|
logger.debug(
|
|
@@ -168,16 +179,214 @@ class Search(PluginTopic):
|
|
|
168
179
|
else:
|
|
169
180
|
return {}
|
|
170
181
|
|
|
182
|
+
def get_product_type_cfg_value(self, key: str, default: Any = None) -> Any:
|
|
183
|
+
"""
|
|
184
|
+
Get the value of a configuration option specific to the current product type.
|
|
185
|
+
|
|
186
|
+
This method retrieves the value of a configuration option from the
|
|
187
|
+
`product_type_config` attribute. If the option is not found, the provided
|
|
188
|
+
default value is returned.
|
|
189
|
+
|
|
190
|
+
:param key: The configuration option key.
|
|
191
|
+
:type key: str
|
|
192
|
+
:param default: The default value to be returned if the option is not found (default is None).
|
|
193
|
+
:type default: Any
|
|
194
|
+
|
|
195
|
+
:return: The value of the specified configuration option or the default value.
|
|
196
|
+
:rtype: Any
|
|
197
|
+
"""
|
|
198
|
+
product_type_cfg = getattr(self.config, "product_type_config", {})
|
|
199
|
+
non_none_cfg = {k: v for k, v in product_type_cfg.items() if v}
|
|
200
|
+
|
|
201
|
+
return non_none_cfg.get(key, default)
|
|
202
|
+
|
|
171
203
|
def get_metadata_mapping(
|
|
172
204
|
self, product_type: Optional[str] = None
|
|
173
|
-
) -> Dict[str, str]:
|
|
205
|
+
) -> Dict[str, Union[str, List[str]]]:
|
|
174
206
|
"""Get the plugin metadata mapping configuration (product type specific if exists)
|
|
175
207
|
|
|
176
208
|
:param product_type: the desired product type
|
|
177
|
-
:type product_type: str
|
|
178
209
|
:returns: The product type specific metadata-mapping
|
|
179
|
-
:rtype: dict
|
|
180
210
|
"""
|
|
181
|
-
|
|
182
|
-
|
|
211
|
+
if product_type:
|
|
212
|
+
return self.config.products.get(product_type, {}).get(
|
|
213
|
+
"metadata_mapping", self.config.metadata_mapping
|
|
214
|
+
)
|
|
215
|
+
return self.config.metadata_mapping
|
|
216
|
+
|
|
217
|
+
def get_sort_by_arg(self, kwargs: Dict[str, Any]) -> Optional[SortByList]:
|
|
218
|
+
"""Extract the "sort_by" argument from the kwargs or the provider default sort configuration
|
|
219
|
+
|
|
220
|
+
:param kwargs: Search arguments
|
|
221
|
+
:returns: The "sort_by" argument from the kwargs or the provider default sort configuration
|
|
222
|
+
"""
|
|
223
|
+
# remove "sort_by" from search args if exists because it is not part of metadata mapping,
|
|
224
|
+
# it will complete the query string or body once metadata mapping will be done
|
|
225
|
+
sort_by_arg_tmp = kwargs.pop("sort_by", None)
|
|
226
|
+
sort_by_arg = sort_by_arg_tmp or getattr(self.config, "sort", {}).get(
|
|
227
|
+
"sort_by_default", None
|
|
228
|
+
)
|
|
229
|
+
if not sort_by_arg_tmp and sort_by_arg:
|
|
230
|
+
logger.info(
|
|
231
|
+
f"{self.provider} is configured with default sorting by '{sort_by_arg[0][0]}' "
|
|
232
|
+
f"in {'ascending' if sort_by_arg[0][1] == 'ASC' else 'descending'} order"
|
|
233
|
+
)
|
|
234
|
+
return sort_by_arg
|
|
235
|
+
|
|
236
|
+
def build_sort_by(
|
|
237
|
+
self, sort_by_arg: SortByList
|
|
238
|
+
) -> Tuple[str, Dict[str, List[Dict[str, str]]]]:
|
|
239
|
+
"""Build the sorting part of the query string or body by transforming
|
|
240
|
+
the "sort_by" argument into a provider-specific string or dictionary
|
|
241
|
+
|
|
242
|
+
:param sort_by_arg: the "sort_by" argument in EODAG format
|
|
243
|
+
:returns: The "sort_by" argument in provider-specific format
|
|
244
|
+
"""
|
|
245
|
+
if not hasattr(self.config, "sort"):
|
|
246
|
+
raise ValidationError(f"{self.provider} does not support sorting feature")
|
|
247
|
+
# TODO: remove this code block when search args model validation is embeded
|
|
248
|
+
# remove duplicates
|
|
249
|
+
sort_by_arg = list(dict.fromkeys(sort_by_arg))
|
|
250
|
+
|
|
251
|
+
sort_by_qs: str = ""
|
|
252
|
+
sort_by_qp: Dict[str, Any] = {}
|
|
253
|
+
|
|
254
|
+
provider_sort_by_tuples_used: List[Tuple[str, str]] = []
|
|
255
|
+
for eodag_sort_by_tuple in sort_by_arg:
|
|
256
|
+
eodag_sort_param = eodag_sort_by_tuple[0]
|
|
257
|
+
provider_sort_param = self.config.sort["sort_param_mapping"].get(
|
|
258
|
+
eodag_sort_param, None
|
|
259
|
+
)
|
|
260
|
+
if not provider_sort_param:
|
|
261
|
+
joined_eodag_params_to_map = ", ".join(
|
|
262
|
+
k for k in self.config.sort["sort_param_mapping"].keys()
|
|
263
|
+
)
|
|
264
|
+
params = set(self.config.sort["sort_param_mapping"].keys())
|
|
265
|
+
params.add(eodag_sort_param)
|
|
266
|
+
raise ValidationError(
|
|
267
|
+
f"'{eodag_sort_param}' parameter is not sortable with {self.provider}. "
|
|
268
|
+
f"Here is the list of sortable parameter(s) with {self.provider}: {joined_eodag_params_to_map}",
|
|
269
|
+
params,
|
|
270
|
+
)
|
|
271
|
+
eodag_sort_order = eodag_sort_by_tuple[1]
|
|
272
|
+
# TODO: remove this code block when search args model validation is embeded
|
|
273
|
+
# Remove leading and trailing whitespace(s) if exist
|
|
274
|
+
eodag_sort_order = eodag_sort_order.strip().upper()
|
|
275
|
+
if eodag_sort_order[:3] != "ASC" and eodag_sort_order[:3] != "DES":
|
|
276
|
+
raise ValidationError(
|
|
277
|
+
"Sorting order is invalid: it must be set to 'ASC' (ASCENDING) or "
|
|
278
|
+
f"'DESC' (DESCENDING), got '{eodag_sort_order}' with '{eodag_sort_param}' instead"
|
|
279
|
+
)
|
|
280
|
+
eodag_sort_order = eodag_sort_order[:3]
|
|
281
|
+
|
|
282
|
+
provider_sort_order = (
|
|
283
|
+
self.config.sort["sort_order_mapping"]["ascending"]
|
|
284
|
+
if eodag_sort_order == "ASC"
|
|
285
|
+
else self.config.sort["sort_order_mapping"]["descending"]
|
|
286
|
+
)
|
|
287
|
+
provider_sort_by_tuple: Tuple[str, str] = (
|
|
288
|
+
provider_sort_param,
|
|
289
|
+
provider_sort_order,
|
|
290
|
+
)
|
|
291
|
+
# TODO: remove this code block when search args model validation is embeded
|
|
292
|
+
for provider_sort_by_tuple_used in provider_sort_by_tuples_used:
|
|
293
|
+
# since duplicated tuples or dictionnaries have been removed, if two sorting parameters are equal,
|
|
294
|
+
# then their sorting order is different and there is a contradiction that would raise an error
|
|
295
|
+
if provider_sort_by_tuple[0] == provider_sort_by_tuple_used[0]:
|
|
296
|
+
raise ValidationError(
|
|
297
|
+
f"'{eodag_sort_param}' parameter is called several times to sort results with different "
|
|
298
|
+
"sorting orders. Please set it to only one ('ASC' (ASCENDING) or 'DESC' (DESCENDING))",
|
|
299
|
+
set([eodag_sort_param]),
|
|
300
|
+
)
|
|
301
|
+
provider_sort_by_tuples_used.append(provider_sort_by_tuple)
|
|
302
|
+
|
|
303
|
+
# TODO: move this code block to the top of this method when search args model validation is embeded
|
|
304
|
+
# check if the limit number of sorting parameter(s) is respected with this sorting parameter
|
|
305
|
+
if (
|
|
306
|
+
self.config.sort.get("max_sort_params", None)
|
|
307
|
+
and len(provider_sort_by_tuples_used)
|
|
308
|
+
> self.config.sort["max_sort_params"]
|
|
309
|
+
):
|
|
310
|
+
raise ValidationError(
|
|
311
|
+
f"Search results can be sorted by only {self.config.sort['max_sort_params']} "
|
|
312
|
+
f"parameter(s) with {self.provider}"
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
parsed_sort_by_tpl: str = self.config.sort["sort_by_tpl"].format(
|
|
316
|
+
sort_param=provider_sort_by_tuple[0],
|
|
317
|
+
sort_order=provider_sort_by_tuple[1],
|
|
318
|
+
)
|
|
319
|
+
try:
|
|
320
|
+
parsed_sort_by_tpl_dict: Dict[str, Any] = orjson.loads(
|
|
321
|
+
parsed_sort_by_tpl
|
|
322
|
+
)
|
|
323
|
+
sort_by_qp = update_nested_dict(
|
|
324
|
+
sort_by_qp, parsed_sort_by_tpl_dict, extend_list_values=True
|
|
325
|
+
)
|
|
326
|
+
except orjson.JSONDecodeError:
|
|
327
|
+
sort_by_qs += parsed_sort_by_tpl
|
|
328
|
+
return (sort_by_qs, sort_by_qp)
|
|
329
|
+
|
|
330
|
+
def list_queryables(
|
|
331
|
+
self,
|
|
332
|
+
filters: Dict[str, Any],
|
|
333
|
+
product_type: Optional[str] = None,
|
|
334
|
+
) -> Dict[str, Annotated[Any, FieldInfo]]:
|
|
335
|
+
"""
|
|
336
|
+
Get queryables
|
|
337
|
+
|
|
338
|
+
:param filters: Additional filters for queryables.
|
|
339
|
+
:param product_type: (optional) The product type.
|
|
340
|
+
|
|
341
|
+
:return: A dictionary containing the queryable properties, associating parameters to their
|
|
342
|
+
annotated type.
|
|
343
|
+
"""
|
|
344
|
+
default_values: Dict[str, Any] = deepcopy(
|
|
345
|
+
getattr(self.config, "products", {}).get(product_type, {})
|
|
346
|
+
)
|
|
347
|
+
default_values.pop("metadata_mapping", None)
|
|
348
|
+
|
|
349
|
+
queryables: Dict[str, Annotated[Any, FieldInfo]] = {}
|
|
350
|
+
try:
|
|
351
|
+
queryables = self.discover_queryables(**{**default_values, **filters}) or {}
|
|
352
|
+
except NotImplementedError:
|
|
353
|
+
pass
|
|
354
|
+
|
|
355
|
+
metadata_mapping: Dict[str, Any] = deepcopy(
|
|
356
|
+
self.get_metadata_mapping(product_type)
|
|
183
357
|
)
|
|
358
|
+
|
|
359
|
+
for param in list(metadata_mapping.keys()):
|
|
360
|
+
if NOT_MAPPED in metadata_mapping[param] or not isinstance(
|
|
361
|
+
metadata_mapping[param], list
|
|
362
|
+
):
|
|
363
|
+
del metadata_mapping[param]
|
|
364
|
+
|
|
365
|
+
eodag_queryables = copy_deepcopy(
|
|
366
|
+
model_fields_to_annotated(Queryables.model_fields)
|
|
367
|
+
)
|
|
368
|
+
for k, v in eodag_queryables.items():
|
|
369
|
+
eodag_queryable_field_info = (
|
|
370
|
+
get_args(v)[1] if len(get_args(v)) > 1 else None
|
|
371
|
+
)
|
|
372
|
+
if not isinstance(eodag_queryable_field_info, FieldInfo):
|
|
373
|
+
continue
|
|
374
|
+
# keep default field info of eodag queryables
|
|
375
|
+
if k in filters and k in queryables:
|
|
376
|
+
queryable_field_info = (
|
|
377
|
+
get_args(queryables[k])[1]
|
|
378
|
+
if len(get_args(queryables[k])) > 1
|
|
379
|
+
else None
|
|
380
|
+
)
|
|
381
|
+
if not isinstance(queryable_field_info, FieldInfo):
|
|
382
|
+
continue
|
|
383
|
+
queryable_field_info.default = filters[k]
|
|
384
|
+
continue
|
|
385
|
+
if k in queryables:
|
|
386
|
+
continue
|
|
387
|
+
if eodag_queryable_field_info.is_required() or (
|
|
388
|
+
(eodag_queryable_field_info.alias or k) in metadata_mapping
|
|
389
|
+
):
|
|
390
|
+
queryables[k] = v
|
|
391
|
+
|
|
392
|
+
return queryables
|