eodag 3.4.2__py3-none-any.whl → 3.4.3__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 +12 -11
- eodag/api/product/_product.py +6 -6
- eodag/api/product/metadata_mapping.py +6 -6
- eodag/config.py +2 -2
- eodag/plugins/apis/ecmwf.py +5 -7
- eodag/plugins/apis/usgs.py +1 -1
- eodag/plugins/authentication/generic.py +5 -1
- eodag/plugins/authentication/openid_connect.py +68 -30
- eodag/plugins/authentication/sas_auth.py +1 -1
- eodag/plugins/crunch/filter_date.py +4 -8
- eodag/plugins/crunch/filter_property.py +1 -1
- eodag/plugins/download/aws.py +3 -3
- eodag/plugins/download/base.py +14 -7
- eodag/plugins/download/http.py +18 -12
- eodag/plugins/download/s3rest.py +9 -5
- eodag/plugins/search/base.py +3 -3
- eodag/plugins/search/build_search_result.py +4 -5
- eodag/plugins/search/data_request_search.py +4 -4
- eodag/plugins/search/qssearch.py +22 -29
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/providers.yml +2 -1
- eodag/rest/server.py +3 -3
- eodag/rest/stac.py +2 -2
- eodag/rest/types/queryables.py +2 -2
- eodag/types/__init__.py +27 -14
- eodag/types/queryables.py +23 -5
- eodag/utils/__init__.py +1 -1
- {eodag-3.4.2.dist-info → eodag-3.4.3.dist-info}/METADATA +2 -2
- {eodag-3.4.2.dist-info → eodag-3.4.3.dist-info}/RECORD +33 -33
- {eodag-3.4.2.dist-info → eodag-3.4.3.dist-info}/WHEEL +1 -1
- {eodag-3.4.2.dist-info → eodag-3.4.3.dist-info}/entry_points.txt +0 -0
- {eodag-3.4.2.dist-info → eodag-3.4.3.dist-info}/licenses/LICENSE +0 -0
- {eodag-3.4.2.dist-info → eodag-3.4.3.dist-info}/top_level.txt +0 -0
eodag/plugins/download/s3rest.py
CHANGED
|
@@ -142,7 +142,7 @@ class S3RestDownload(Download):
|
|
|
142
142
|
**kwargs: Unpack[DownloadConf],
|
|
143
143
|
):
|
|
144
144
|
# check order status
|
|
145
|
-
if product.properties.get("orderStatusLink"
|
|
145
|
+
if product.properties.get("orderStatusLink"):
|
|
146
146
|
self.http_download_plugin._order_status(product=product, auth=auth)
|
|
147
147
|
|
|
148
148
|
# get bucket urls
|
|
@@ -272,7 +272,7 @@ class S3RestDownload(Download):
|
|
|
272
272
|
|
|
273
273
|
# total size for progress_callback
|
|
274
274
|
size_list: list[int] = [
|
|
275
|
-
int(node.firstChild.nodeValue
|
|
275
|
+
int(node.firstChild.nodeValue or 0)
|
|
276
276
|
for node in xmldoc.getElementsByTagName("Size")
|
|
277
277
|
if node.firstChild is not None
|
|
278
278
|
]
|
|
@@ -281,9 +281,13 @@ class S3RestDownload(Download):
|
|
|
281
281
|
|
|
282
282
|
# download each node key
|
|
283
283
|
for node_xml in nodes_xml_list:
|
|
284
|
-
node_key =
|
|
285
|
-
|
|
286
|
-
|
|
284
|
+
node_key = node_xml.getElementsByTagName("Key")[0].firstChild.nodeValue # type: ignore[union-attr]
|
|
285
|
+
if node_key is None:
|
|
286
|
+
logger.debug(
|
|
287
|
+
"Node key is None, skipping this node: %s", node_xml.toxml()
|
|
288
|
+
)
|
|
289
|
+
continue
|
|
290
|
+
node_key = unquote(node_key)
|
|
287
291
|
# As "Key", "Size" and "ETag" (md5 hash) can also be retrieved from node_xml
|
|
288
292
|
node_url = urljoin(bucket_url.strip("/") + "/", node_key.strip("/"))
|
|
289
293
|
# output file location
|
eodag/plugins/search/base.py
CHANGED
|
@@ -224,7 +224,7 @@ class Search(PluginTopic):
|
|
|
224
224
|
# it will complete the query string or body once metadata mapping will be done
|
|
225
225
|
sort_by_arg_tmp = kwargs.pop("sort_by", None)
|
|
226
226
|
sort_by_arg = sort_by_arg_tmp or getattr(self.config, "sort", {}).get(
|
|
227
|
-
"sort_by_default"
|
|
227
|
+
"sort_by_default"
|
|
228
228
|
)
|
|
229
229
|
if not sort_by_arg_tmp and sort_by_arg:
|
|
230
230
|
logger.info(
|
|
@@ -255,7 +255,7 @@ class Search(PluginTopic):
|
|
|
255
255
|
for eodag_sort_by_tuple in sort_by_arg:
|
|
256
256
|
eodag_sort_param = eodag_sort_by_tuple[0]
|
|
257
257
|
provider_sort_param = self.config.sort["sort_param_mapping"].get(
|
|
258
|
-
eodag_sort_param
|
|
258
|
+
eodag_sort_param
|
|
259
259
|
)
|
|
260
260
|
if not provider_sort_param:
|
|
261
261
|
joined_eodag_params_to_map = ", ".join(
|
|
@@ -303,7 +303,7 @@ class Search(PluginTopic):
|
|
|
303
303
|
# TODO: move this code block to the top of this method when search args model validation is embeded
|
|
304
304
|
# check if the limit number of sorting parameter(s) is respected with this sorting parameter
|
|
305
305
|
if (
|
|
306
|
-
self.config.sort.get("max_sort_params"
|
|
306
|
+
self.config.sort.get("max_sort_params")
|
|
307
307
|
and len(provider_sort_by_tuples_used)
|
|
308
308
|
> self.config.sort["max_sort_params"]
|
|
309
309
|
):
|
|
@@ -403,8 +403,7 @@ def ecmwf_temporal_to_eodag(
|
|
|
403
403
|
if date := params.get("date"):
|
|
404
404
|
start, end = parse_date(date, params.get("time"))
|
|
405
405
|
|
|
406
|
-
elif year := params.get("year") or params.get("hyear"):
|
|
407
|
-
year = params.get("year") or params.get("hyear")
|
|
406
|
+
elif year := (params.get("year") or params.get("hyear")):
|
|
408
407
|
month = params.get("month") or params.get("hmonth")
|
|
409
408
|
day = params.get("day") or params.get("hday")
|
|
410
409
|
time = params.get("time")
|
|
@@ -499,7 +498,7 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
499
498
|
"""
|
|
500
499
|
product_type = prep.product_type
|
|
501
500
|
if not product_type:
|
|
502
|
-
product_type = kwargs.get("productType"
|
|
501
|
+
product_type = kwargs.get("productType")
|
|
503
502
|
kwargs = self._preprocess_search_params(kwargs, product_type)
|
|
504
503
|
result, num_items = super().query(prep, **kwargs)
|
|
505
504
|
if prep.count and not num_items:
|
|
@@ -547,7 +546,7 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
547
546
|
:param params: Search parameters to be preprocessed.
|
|
548
547
|
:param product_type: (optional) product type id
|
|
549
548
|
"""
|
|
550
|
-
_dc_qs = params.get("_dc_qs"
|
|
549
|
+
_dc_qs = params.get("_dc_qs")
|
|
551
550
|
if _dc_qs is not None:
|
|
552
551
|
# if available, update search params using datacube query-string
|
|
553
552
|
_dc_qp = geojson.loads(unquote_plus(unquote_plus(_dc_qs)))
|
|
@@ -557,7 +556,7 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
557
556
|
(params[START], params[END],) = _dc_qp[
|
|
558
557
|
"date"
|
|
559
558
|
].split("/")
|
|
560
|
-
elif _dc_qp.get("date"
|
|
559
|
+
elif _dc_qp.get("date"):
|
|
561
560
|
params[START] = params[END] = _dc_qp["date"]
|
|
562
561
|
|
|
563
562
|
if "/" in _dc_qp.get("area", ""):
|
|
@@ -206,7 +206,7 @@ class DataRequestSearch(Search):
|
|
|
206
206
|
and "next_page_url_key_path" in self.config.pagination
|
|
207
207
|
):
|
|
208
208
|
self.config.pagination["next_page_url_key_path"] = string_to_jsonpath(
|
|
209
|
-
self.config.pagination.get("next_page_url_key_path"
|
|
209
|
+
self.config.pagination.get("next_page_url_key_path")
|
|
210
210
|
)
|
|
211
211
|
self.download_info: dict[str, Any] = {}
|
|
212
212
|
self.data_request_id = None
|
|
@@ -234,7 +234,7 @@ class DataRequestSearch(Search):
|
|
|
234
234
|
if kwargs.get("sort_by"):
|
|
235
235
|
raise ValidationError(f"{self.provider} does not support sorting feature")
|
|
236
236
|
|
|
237
|
-
product_type = kwargs.get("productType"
|
|
237
|
+
product_type = kwargs.get("productType")
|
|
238
238
|
|
|
239
239
|
if product_type is None:
|
|
240
240
|
raise ValidationError("Required productType is missing")
|
|
@@ -288,11 +288,11 @@ class DataRequestSearch(Search):
|
|
|
288
288
|
|
|
289
289
|
# update dates if needed
|
|
290
290
|
if getattr(self.config, "dates_required", True) and "id" not in keywords:
|
|
291
|
-
if not keywords.get("startTimeFromAscendingNode"
|
|
291
|
+
if not keywords.get("startTimeFromAscendingNode"):
|
|
292
292
|
keywords["startTimeFromAscendingNode"] = getattr(
|
|
293
293
|
self.config, "product_type_config", {}
|
|
294
294
|
).get("missionStartDate", DEFAULT_MISSION_START_DATE)
|
|
295
|
-
if not keywords.get("completionTimeFromAscendingNode"
|
|
295
|
+
if not keywords.get("completionTimeFromAscendingNode"):
|
|
296
296
|
keywords["completionTimeFromAscendingNode"] = getattr(
|
|
297
297
|
self.config, "product_type_config", {}
|
|
298
298
|
).get("missionEndDate", datetime.now(timezone.utc).isoformat())
|
eodag/plugins/search/qssearch.py
CHANGED
|
@@ -315,31 +315,27 @@ class QueryStringSearch(Search):
|
|
|
315
315
|
and "next_page_url_key_path" in self.config.pagination
|
|
316
316
|
):
|
|
317
317
|
self.config.pagination["next_page_url_key_path"] = string_to_jsonpath(
|
|
318
|
-
self.config.pagination.get("next_page_url_key_path"
|
|
318
|
+
self.config.pagination.get("next_page_url_key_path")
|
|
319
319
|
)
|
|
320
320
|
if (
|
|
321
321
|
self.config.result_type == "json"
|
|
322
322
|
and "next_page_query_obj_key_path" in self.config.pagination
|
|
323
323
|
):
|
|
324
324
|
self.config.pagination["next_page_query_obj_key_path"] = string_to_jsonpath(
|
|
325
|
-
self.config.pagination.get("next_page_query_obj_key_path"
|
|
325
|
+
self.config.pagination.get("next_page_query_obj_key_path")
|
|
326
326
|
)
|
|
327
327
|
if (
|
|
328
328
|
self.config.result_type == "json"
|
|
329
329
|
and "next_page_merge_key_path" in self.config.pagination
|
|
330
330
|
):
|
|
331
331
|
self.config.pagination["next_page_merge_key_path"] = string_to_jsonpath(
|
|
332
|
-
self.config.pagination.get("next_page_merge_key_path"
|
|
332
|
+
self.config.pagination.get("next_page_merge_key_path")
|
|
333
333
|
)
|
|
334
334
|
|
|
335
335
|
# parse jsonpath on init: product types discovery
|
|
336
336
|
if (
|
|
337
|
-
getattr(self.config, "discover_product_types", {}).get(
|
|
338
|
-
|
|
339
|
-
)
|
|
340
|
-
and getattr(self.config, "discover_product_types", {}).get(
|
|
341
|
-
"result_type", None
|
|
342
|
-
)
|
|
337
|
+
getattr(self.config, "discover_product_types", {}).get("results_entry")
|
|
338
|
+
and getattr(self.config, "discover_product_types", {}).get("result_type")
|
|
343
339
|
== "json"
|
|
344
340
|
):
|
|
345
341
|
self.config.discover_product_types["results_entry"] = string_to_jsonpath(
|
|
@@ -380,8 +376,8 @@ class QueryStringSearch(Search):
|
|
|
380
376
|
|
|
381
377
|
# parse jsonpath on init: queryables discovery
|
|
382
378
|
if (
|
|
383
|
-
getattr(self.config, "discover_queryables", {}).get("results_entry"
|
|
384
|
-
and getattr(self.config, "discover_queryables", {}).get("result_type"
|
|
379
|
+
getattr(self.config, "discover_queryables", {}).get("results_entry")
|
|
380
|
+
and getattr(self.config, "discover_queryables", {}).get("result_type")
|
|
385
381
|
== "json"
|
|
386
382
|
):
|
|
387
383
|
self.config.discover_queryables["results_entry"] = string_to_jsonpath(
|
|
@@ -731,7 +727,7 @@ class QueryStringSearch(Search):
|
|
|
731
727
|
:param prep: Object collecting needed information for search.
|
|
732
728
|
"""
|
|
733
729
|
count = prep.count
|
|
734
|
-
product_type = kwargs.get("productType", prep.product_type)
|
|
730
|
+
product_type = cast(str, kwargs.get("productType", prep.product_type))
|
|
735
731
|
if product_type == GENERIC_PRODUCT_TYPE:
|
|
736
732
|
logger.warning(
|
|
737
733
|
"GENERIC_PRODUCT_TYPE is not a real product_type and should only be used internally as a template"
|
|
@@ -930,13 +926,13 @@ class QueryStringSearch(Search):
|
|
|
930
926
|
)
|
|
931
927
|
response = self._request(single_search_prep)
|
|
932
928
|
next_page_url_key_path = self.config.pagination.get(
|
|
933
|
-
"next_page_url_key_path"
|
|
929
|
+
"next_page_url_key_path"
|
|
934
930
|
)
|
|
935
931
|
next_page_query_obj_key_path = self.config.pagination.get(
|
|
936
|
-
"next_page_query_obj_key_path"
|
|
932
|
+
"next_page_query_obj_key_path"
|
|
937
933
|
)
|
|
938
934
|
next_page_merge_key_path = self.config.pagination.get(
|
|
939
|
-
"next_page_merge_key_path"
|
|
935
|
+
"next_page_merge_key_path"
|
|
940
936
|
)
|
|
941
937
|
if self.config.result_type == "xml":
|
|
942
938
|
root_node = etree.fromstring(response.content)
|
|
@@ -1174,9 +1170,7 @@ class QueryStringSearch(Search):
|
|
|
1174
1170
|
|
|
1175
1171
|
collection = getattr(self.config, "collection", None)
|
|
1176
1172
|
if collection is None:
|
|
1177
|
-
collection = (
|
|
1178
|
-
prep.product_type_def_params.get("collection", None) or product_type
|
|
1179
|
-
)
|
|
1173
|
+
collection = prep.product_type_def_params.get("collection") or product_type
|
|
1180
1174
|
|
|
1181
1175
|
if collection is None:
|
|
1182
1176
|
return ()
|
|
@@ -1332,9 +1326,9 @@ class ODataV4Search(QueryStringSearch):
|
|
|
1332
1326
|
|
|
1333
1327
|
# parse jsonpath on init
|
|
1334
1328
|
metadata_pre_mapping = getattr(self.config, "metadata_pre_mapping", {})
|
|
1335
|
-
metadata_path = metadata_pre_mapping.get("metadata_path"
|
|
1336
|
-
metadata_path_id = metadata_pre_mapping.get("metadata_path_id"
|
|
1337
|
-
metadata_path_value = metadata_pre_mapping.get("metadata_path_value"
|
|
1329
|
+
metadata_path = metadata_pre_mapping.get("metadata_path")
|
|
1330
|
+
metadata_path_id = metadata_pre_mapping.get("metadata_path_id")
|
|
1331
|
+
metadata_path_value = metadata_pre_mapping.get("metadata_path_value")
|
|
1338
1332
|
if metadata_path and metadata_path_id and metadata_path_value:
|
|
1339
1333
|
self.config.metadata_pre_mapping["metadata_path"] = string_to_jsonpath(
|
|
1340
1334
|
metadata_path
|
|
@@ -1392,9 +1386,9 @@ class ODataV4Search(QueryStringSearch):
|
|
|
1392
1386
|
For example, going from '$.Metadata[?(@.id="foo")].value' to '$.Metadata.foo.value'
|
|
1393
1387
|
"""
|
|
1394
1388
|
metadata_pre_mapping = getattr(self.config, "metadata_pre_mapping", {})
|
|
1395
|
-
metadata_path = metadata_pre_mapping.get("metadata_path"
|
|
1396
|
-
metadata_path_id = metadata_pre_mapping.get("metadata_path_id"
|
|
1397
|
-
metadata_path_value = metadata_pre_mapping.get("metadata_path_value"
|
|
1389
|
+
metadata_path = metadata_pre_mapping.get("metadata_path")
|
|
1390
|
+
metadata_path_id = metadata_pre_mapping.get("metadata_path_id")
|
|
1391
|
+
metadata_path_value = metadata_pre_mapping.get("metadata_path_value")
|
|
1398
1392
|
|
|
1399
1393
|
if metadata_path and metadata_path_id and metadata_path_value:
|
|
1400
1394
|
# metadata_path already parsed on init
|
|
@@ -1516,10 +1510,10 @@ class PostJsonSearch(QueryStringSearch):
|
|
|
1516
1510
|
]["results_entry"]
|
|
1517
1511
|
self.config.collection = self.config.products[product_type][
|
|
1518
1512
|
"specific_qssearch"
|
|
1519
|
-
].get("collection"
|
|
1513
|
+
].get("collection")
|
|
1520
1514
|
self.config.merge_responses = self.config.products[product_type][
|
|
1521
1515
|
"specific_qssearch"
|
|
1522
|
-
].get("merge_responses"
|
|
1516
|
+
].get("merge_responses")
|
|
1523
1517
|
|
|
1524
1518
|
def count_hits(self, *x, **y):
|
|
1525
1519
|
return 1
|
|
@@ -1814,7 +1808,7 @@ class StacSearch(PostJsonSearch):
|
|
|
1814
1808
|
):
|
|
1815
1809
|
raise NotImplementedError()
|
|
1816
1810
|
|
|
1817
|
-
product_type = kwargs.get("productType"
|
|
1811
|
+
product_type = kwargs.get("productType")
|
|
1818
1812
|
provider_product_type = (
|
|
1819
1813
|
self.config.products.get(product_type, {}).get("productType", product_type)
|
|
1820
1814
|
if product_type
|
|
@@ -1926,10 +1920,9 @@ class StacSearch(PostJsonSearch):
|
|
|
1926
1920
|
python_queryables = create_model("m", **field_definitions).model_fields
|
|
1927
1921
|
geom_queryable = python_queryables.pop("geometry", None)
|
|
1928
1922
|
if geom_queryable:
|
|
1929
|
-
python_queryables["geom"] =
|
|
1923
|
+
python_queryables["geom"] = Queryables.model_fields["geom"]
|
|
1930
1924
|
|
|
1931
1925
|
queryables_dict = model_fields_to_annotated(python_queryables)
|
|
1932
|
-
|
|
1933
1926
|
# append "datetime" as "start" & "end" if needed
|
|
1934
1927
|
if "datetime" in json_queryables:
|
|
1935
1928
|
eodag_queryables = copy_deepcopy(
|