eodag 3.1.0b1__py3-none-any.whl → 3.1.0b2__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 +59 -52
- eodag/api/product/_assets.py +5 -5
- eodag/api/product/_product.py +27 -12
- 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 +62 -74
- eodag/api/search_result.py +13 -23
- eodag/cli.py +4 -4
- eodag/config.py +66 -69
- eodag/plugins/apis/base.py +1 -1
- eodag/plugins/apis/ecmwf.py +10 -9
- eodag/plugins/apis/usgs.py +11 -10
- 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 +14 -14
- eodag/plugins/authentication/sas_auth.py +4 -4
- eodag/plugins/authentication/token.py +7 -7
- 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 +4 -4
- eodag/plugins/download/aws.py +47 -66
- eodag/plugins/download/base.py +8 -17
- eodag/plugins/download/creodias_s3.py +2 -2
- eodag/plugins/download/http.py +30 -32
- eodag/plugins/download/s3rest.py +5 -4
- eodag/plugins/manager.py +10 -20
- eodag/plugins/search/__init__.py +6 -5
- eodag/plugins/search/base.py +35 -40
- eodag/plugins/search/build_search_result.py +69 -68
- eodag/plugins/search/cop_marine.py +22 -12
- eodag/plugins/search/creodias_s3.py +8 -78
- eodag/plugins/search/csw.py +11 -11
- eodag/plugins/search/data_request_search.py +16 -15
- eodag/plugins/search/qssearch.py +56 -52
- eodag/plugins/search/stac_list_assets.py +85 -0
- eodag/plugins/search/static_stac_search.py +3 -3
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +288 -288
- eodag/resources/providers.yml +146 -6
- eodag/resources/stac_api.yml +2 -2
- eodag/resources/user_conf_template.yml +11 -0
- eodag/rest/cache.py +2 -2
- eodag/rest/config.py +3 -3
- eodag/rest/core.py +24 -24
- eodag/rest/errors.py +5 -5
- eodag/rest/server.py +3 -11
- eodag/rest/stac.py +40 -38
- eodag/rest/types/collections_search.py +3 -3
- eodag/rest/types/eodag_search.py +23 -23
- eodag/rest/types/queryables.py +13 -13
- eodag/rest/types/stac_search.py +15 -25
- eodag/rest/utils/__init__.py +11 -21
- eodag/rest/utils/cql_evaluate.py +6 -6
- eodag/rest/utils/rfc3339.py +2 -2
- eodag/types/__init__.py +24 -18
- eodag/types/bbox.py +2 -2
- eodag/types/download_args.py +2 -2
- eodag/types/queryables.py +5 -2
- eodag/types/search_args.py +4 -4
- eodag/types/whoosh.py +1 -3
- eodag/utils/__init__.py +81 -40
- eodag/utils/exceptions.py +2 -2
- eodag/utils/import_system.py +2 -2
- eodag/utils/requests.py +2 -2
- eodag/utils/rest.py +2 -2
- eodag/utils/s3.py +208 -0
- eodag/utils/stac_reader.py +10 -10
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/METADATA +5 -4
- eodag-3.1.0b2.dist-info/RECORD +113 -0
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/entry_points.txt +1 -0
- eodag-3.1.0b1.dist-info/RECORD +0 -108
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/LICENSE +0 -0
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/WHEEL +0 -0
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/top_level.txt +0 -0
|
@@ -23,19 +23,7 @@ import logging
|
|
|
23
23
|
import re
|
|
24
24
|
from datetime import datetime, timedelta
|
|
25
25
|
from string import Formatter
|
|
26
|
-
from typing import
|
|
27
|
-
TYPE_CHECKING,
|
|
28
|
-
Any,
|
|
29
|
-
AnyStr,
|
|
30
|
-
Callable,
|
|
31
|
-
Dict,
|
|
32
|
-
Iterator,
|
|
33
|
-
List,
|
|
34
|
-
Optional,
|
|
35
|
-
Tuple,
|
|
36
|
-
Union,
|
|
37
|
-
cast,
|
|
38
|
-
)
|
|
26
|
+
from typing import TYPE_CHECKING, Any, AnyStr, Callable, Iterator, Optional, Union, cast
|
|
39
27
|
|
|
40
28
|
import geojson
|
|
41
29
|
import orjson
|
|
@@ -88,8 +76,8 @@ DEFAULT_GEOMETRY = "POLYGON((180 -90, 180 90, -180 90, -180 -90, 180 -90))"
|
|
|
88
76
|
|
|
89
77
|
|
|
90
78
|
def get_metadata_path(
|
|
91
|
-
map_value: Union[str,
|
|
92
|
-
) ->
|
|
79
|
+
map_value: Union[str, list[str]],
|
|
80
|
+
) -> tuple[Union[list[str], None], str]:
|
|
93
81
|
"""Return the jsonpath or xpath to the value of a EO product metadata in a provider
|
|
94
82
|
search result.
|
|
95
83
|
|
|
@@ -137,12 +125,12 @@ def get_metadata_path(
|
|
|
137
125
|
return None, path
|
|
138
126
|
|
|
139
127
|
|
|
140
|
-
def get_metadata_path_value(map_value: Union[str,
|
|
128
|
+
def get_metadata_path_value(map_value: Union[str, list[str]]) -> str:
|
|
141
129
|
"""Get raw metadata path without converter"""
|
|
142
130
|
return map_value[1] if isinstance(map_value, list) else map_value
|
|
143
131
|
|
|
144
132
|
|
|
145
|
-
def get_search_param(map_value:
|
|
133
|
+
def get_search_param(map_value: list[str]) -> str:
|
|
146
134
|
"""See :func:`~eodag.api.product.metadata_mapping.get_metadata_path`
|
|
147
135
|
|
|
148
136
|
:param map_value: The value originating from the definition of `metadata_mapping`
|
|
@@ -335,7 +323,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
335
323
|
return wkt_value
|
|
336
324
|
|
|
337
325
|
@staticmethod
|
|
338
|
-
def convert_to_bounds_lists(input_geom: BaseGeometry) ->
|
|
326
|
+
def convert_to_bounds_lists(input_geom: BaseGeometry) -> list[list[float]]:
|
|
339
327
|
if isinstance(input_geom, MultiPolygon):
|
|
340
328
|
geoms = [geom for geom in input_geom.geoms]
|
|
341
329
|
# sort with larger one at first (stac-browser only plots first one)
|
|
@@ -345,7 +333,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
345
333
|
return [list(input_geom.bounds[0:4])]
|
|
346
334
|
|
|
347
335
|
@staticmethod
|
|
348
|
-
def convert_to_bounds(input_geom_unformatted: Any) ->
|
|
336
|
+
def convert_to_bounds(input_geom_unformatted: Any) -> list[float]:
|
|
349
337
|
input_geom = get_geometry_from_various(geometry=input_geom_unformatted)
|
|
350
338
|
if isinstance(input_geom, MultiPolygon):
|
|
351
339
|
geoms = [geom for geom in input_geom.geoms]
|
|
@@ -356,16 +344,16 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
356
344
|
max_lon = -180
|
|
357
345
|
max_lat = -90
|
|
358
346
|
for geom in geoms:
|
|
359
|
-
min_lon = min(min_lon, geom.
|
|
360
|
-
min_lat = min(min_lat, geom.
|
|
361
|
-
max_lon = max(max_lon, geom.
|
|
362
|
-
max_lat = max(max_lat, geom.
|
|
347
|
+
min_lon = min(min_lon, geom.bounds[0])
|
|
348
|
+
min_lat = min(min_lat, geom.bounds[1])
|
|
349
|
+
max_lon = max(max_lon, geom.bounds[2])
|
|
350
|
+
max_lat = max(max_lat, geom.bounds[3])
|
|
363
351
|
return [min_lon, min_lat, max_lon, max_lat]
|
|
364
352
|
else:
|
|
365
353
|
return list(input_geom.bounds[0:4])
|
|
366
354
|
|
|
367
355
|
@staticmethod
|
|
368
|
-
def convert_to_nwse_bounds(input_geom: BaseGeometry) ->
|
|
356
|
+
def convert_to_nwse_bounds(input_geom: BaseGeometry) -> list[float]:
|
|
369
357
|
if isinstance(input_geom, str):
|
|
370
358
|
input_geom = shapely.wkt.loads(input_geom)
|
|
371
359
|
return list(input_geom.bounds[-1:] + input_geom.bounds[:-1])
|
|
@@ -449,7 +437,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
449
437
|
else:
|
|
450
438
|
yield e
|
|
451
439
|
|
|
452
|
-
polygons_list:
|
|
440
|
+
polygons_list: list[Polygon] = []
|
|
453
441
|
for elem in flatten_elements(georss[0]):
|
|
454
442
|
coords_list = elem.text.split()
|
|
455
443
|
polygon_args = [
|
|
@@ -474,7 +462,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
474
462
|
@staticmethod
|
|
475
463
|
def convert_to_longitude_latitude(
|
|
476
464
|
input_geom_unformatted: Any,
|
|
477
|
-
) ->
|
|
465
|
+
) -> dict[str, float]:
|
|
478
466
|
bounds = MetadataFormatter.convert_to_bounds(input_geom_unformatted)
|
|
479
467
|
lon = (bounds[0] + bounds[2]) / 2
|
|
480
468
|
lat = (bounds[1] + bounds[3]) / 2
|
|
@@ -514,8 +502,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
514
502
|
|
|
515
503
|
@staticmethod
|
|
516
504
|
def convert_recursive_sub_str(
|
|
517
|
-
input_obj: Union[
|
|
518
|
-
) -> Union[
|
|
505
|
+
input_obj: Union[dict[Any, Any], list[Any]], args: str
|
|
506
|
+
) -> Union[dict[Any, Any], list[Any]]:
|
|
519
507
|
old, new = ast.literal_eval(args)
|
|
520
508
|
return items_recursive_apply(
|
|
521
509
|
input_obj,
|
|
@@ -525,8 +513,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
525
513
|
|
|
526
514
|
@staticmethod
|
|
527
515
|
def convert_dict_update(
|
|
528
|
-
input_dict:
|
|
529
|
-
) ->
|
|
516
|
+
input_dict: dict[Any, Any], args: str
|
|
517
|
+
) -> dict[Any, Any]:
|
|
530
518
|
"""Converts"""
|
|
531
519
|
new_items_list = ast.literal_eval(args)
|
|
532
520
|
|
|
@@ -536,8 +524,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
536
524
|
|
|
537
525
|
@staticmethod
|
|
538
526
|
def convert_dict_filter(
|
|
539
|
-
input_dict:
|
|
540
|
-
) ->
|
|
527
|
+
input_dict: dict[Any, Any], jsonpath_filter_str: str
|
|
528
|
+
) -> dict[Any, Any]:
|
|
541
529
|
"""Fitlers dict items using jsonpath"""
|
|
542
530
|
|
|
543
531
|
jsonpath_filter = string_to_jsonpath(jsonpath_filter_str, force=True)
|
|
@@ -616,8 +604,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
616
604
|
return NOT_AVAILABLE
|
|
617
605
|
|
|
618
606
|
@staticmethod
|
|
619
|
-
def convert_split_id_into_s1_params(product_id: str) ->
|
|
620
|
-
parts:
|
|
607
|
+
def convert_split_id_into_s1_params(product_id: str) -> dict[str, str]:
|
|
608
|
+
parts: list[str] = re.split(r"_(?!_)", product_id)
|
|
621
609
|
if len(parts) < 9:
|
|
622
610
|
logger.error(
|
|
623
611
|
"id %s does not match expected Sentinel-1 id format", product_id
|
|
@@ -651,8 +639,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
651
639
|
return params
|
|
652
640
|
|
|
653
641
|
@staticmethod
|
|
654
|
-
def convert_split_id_into_s3_params(product_id: str) ->
|
|
655
|
-
parts:
|
|
642
|
+
def convert_split_id_into_s3_params(product_id: str) -> dict[str, str]:
|
|
643
|
+
parts: list[str] = re.split(r"_(?!_)", product_id)
|
|
656
644
|
params = {"productType": product_id[4:15]}
|
|
657
645
|
dates = re.findall("[0-9]{8}T[0-9]{6}", product_id)
|
|
658
646
|
start_date = datetime.strptime(dates[0], "%Y%m%dT%H%M%S") - timedelta(
|
|
@@ -668,8 +656,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
668
656
|
return params
|
|
669
657
|
|
|
670
658
|
@staticmethod
|
|
671
|
-
def convert_split_id_into_s5p_params(product_id: str) ->
|
|
672
|
-
parts:
|
|
659
|
+
def convert_split_id_into_s5p_params(product_id: str) -> dict[str, str]:
|
|
660
|
+
parts: list[str] = re.split(r"_(?!_)", product_id)
|
|
673
661
|
params = {
|
|
674
662
|
"productType": product_id[9:19],
|
|
675
663
|
"processingMode": parts[1],
|
|
@@ -686,7 +674,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
686
674
|
return params
|
|
687
675
|
|
|
688
676
|
@staticmethod
|
|
689
|
-
def convert_split_cop_dem_id(product_id: str) ->
|
|
677
|
+
def convert_split_cop_dem_id(product_id: str) -> list[int]:
|
|
690
678
|
parts = product_id.split("_")
|
|
691
679
|
lattitude = parts[3]
|
|
692
680
|
longitude = parts[5]
|
|
@@ -725,7 +713,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
725
713
|
@staticmethod
|
|
726
714
|
def convert_to_datetime_dict(
|
|
727
715
|
date: str, format: str
|
|
728
|
-
) ->
|
|
716
|
+
) -> dict[str, Union[list[str], str]]:
|
|
729
717
|
"""Convert a date (str) to a dictionary where values are in the format given in argument
|
|
730
718
|
|
|
731
719
|
date == "2021-04-21T18:27:19.123Z" and format == "list" => {
|
|
@@ -777,7 +765,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
777
765
|
@staticmethod
|
|
778
766
|
def convert_interval_to_datetime_dict(
|
|
779
767
|
date: str, separator: str = "/"
|
|
780
|
-
) ->
|
|
768
|
+
) -> dict[str, list[str]]:
|
|
781
769
|
"""Convert a date interval ('/' separated str) to a dictionary where values are lists
|
|
782
770
|
|
|
783
771
|
date == "2021-04-21/2021-04-22" => {
|
|
@@ -817,7 +805,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
817
805
|
}
|
|
818
806
|
|
|
819
807
|
@staticmethod
|
|
820
|
-
def convert_get_ecmwf_time(date: str) ->
|
|
808
|
+
def convert_get_ecmwf_time(date: str) -> list[str]:
|
|
821
809
|
"""Get the time of a date (str) in the ECMWF format (["HH:00"])
|
|
822
810
|
|
|
823
811
|
"2021-04-21T18:27:19.123Z" => ["18:00"]
|
|
@@ -861,8 +849,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
861
849
|
|
|
862
850
|
@staticmethod
|
|
863
851
|
def convert_assets_list_to_dict(
|
|
864
|
-
assets_list:
|
|
865
|
-
) ->
|
|
852
|
+
assets_list: list[dict[str, str]], asset_name_key: str = "title"
|
|
853
|
+
) -> dict[str, dict[str, str]]:
|
|
866
854
|
"""Convert a list of assets to a dictionary where keys represent
|
|
867
855
|
name of assets and are found among values of asset dictionaries.
|
|
868
856
|
|
|
@@ -889,8 +877,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
889
877
|
"asset3": {"href": "qux", "title": "qux-title", "name": "asset3"},
|
|
890
878
|
}
|
|
891
879
|
"""
|
|
892
|
-
asset_names:
|
|
893
|
-
assets_dict:
|
|
880
|
+
asset_names: list[str] = []
|
|
881
|
+
assets_dict: dict[str, dict[str, str]] = {}
|
|
894
882
|
|
|
895
883
|
for asset in assets_list:
|
|
896
884
|
asset_name = asset[asset_name_key]
|
|
@@ -899,7 +887,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
899
887
|
|
|
900
888
|
# we only keep the equivalent of the path basename in the case where the
|
|
901
889
|
# asset name has a path pattern and this basename is only found once
|
|
902
|
-
immutable_asset_indexes:
|
|
890
|
+
immutable_asset_indexes: list[int] = []
|
|
903
891
|
for i, asset_name in enumerate(asset_names):
|
|
904
892
|
if i in immutable_asset_indexes:
|
|
905
893
|
continue
|
|
@@ -925,10 +913,10 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
925
913
|
|
|
926
914
|
|
|
927
915
|
def properties_from_json(
|
|
928
|
-
json:
|
|
929
|
-
mapping:
|
|
930
|
-
discovery_config: Optional[
|
|
931
|
-
) ->
|
|
916
|
+
json: dict[str, Any],
|
|
917
|
+
mapping: dict[str, Any],
|
|
918
|
+
discovery_config: Optional[dict[str, Any]] = None,
|
|
919
|
+
) -> dict[str, Any]:
|
|
932
920
|
"""Extract properties from a provider json result.
|
|
933
921
|
|
|
934
922
|
:param json: The representation of a provider result as a json object
|
|
@@ -941,7 +929,7 @@ def properties_from_json(
|
|
|
941
929
|
`discovery_path` (String representation of jsonpath)
|
|
942
930
|
:returns: The metadata of the :class:`~eodag.api.product._product.EOProduct`
|
|
943
931
|
"""
|
|
944
|
-
properties:
|
|
932
|
+
properties: dict[str, Any] = {}
|
|
945
933
|
templates = {}
|
|
946
934
|
used_jsonpaths = []
|
|
947
935
|
for metadata, value in mapping.items():
|
|
@@ -1085,8 +1073,8 @@ def properties_from_xml(
|
|
|
1085
1073
|
xml_as_text: AnyStr,
|
|
1086
1074
|
mapping: Any,
|
|
1087
1075
|
empty_ns_prefix: str = "ns",
|
|
1088
|
-
discovery_config: Optional[
|
|
1089
|
-
) ->
|
|
1076
|
+
discovery_config: Optional[dict[str, Any]] = None,
|
|
1077
|
+
) -> dict[str, Any]:
|
|
1090
1078
|
"""Extract properties from a provider xml result.
|
|
1091
1079
|
|
|
1092
1080
|
:param xml_as_text: The representation of a provider result as xml
|
|
@@ -1104,7 +1092,7 @@ def properties_from_xml(
|
|
|
1104
1092
|
`discovery_path` (String representation of xpath)
|
|
1105
1093
|
:returns: the metadata of the :class:`~eodag.api.product._product.EOProduct`
|
|
1106
1094
|
"""
|
|
1107
|
-
properties:
|
|
1095
|
+
properties: dict[str, Any] = {}
|
|
1108
1096
|
templates = {}
|
|
1109
1097
|
used_xpaths = []
|
|
1110
1098
|
root = etree.XML(xml_as_text)
|
|
@@ -1232,10 +1220,10 @@ def properties_from_xml(
|
|
|
1232
1220
|
|
|
1233
1221
|
|
|
1234
1222
|
def mtd_cfg_as_conversion_and_querypath(
|
|
1235
|
-
src_dict:
|
|
1236
|
-
dest_dict:
|
|
1223
|
+
src_dict: dict[str, Any],
|
|
1224
|
+
dest_dict: dict[str, Any] = {},
|
|
1237
1225
|
result_type: str = "json",
|
|
1238
|
-
) ->
|
|
1226
|
+
) -> dict[str, Any]:
|
|
1239
1227
|
"""Metadata configuration dictionary to querypath with conversion dictionary
|
|
1240
1228
|
Transform every src_dict value from jsonpath_str to tuple `(conversion, jsonpath_object)`
|
|
1241
1229
|
or from xpath_str to tuple `(conversion, xpath_str)`
|
|
@@ -1283,8 +1271,8 @@ def mtd_cfg_as_conversion_and_querypath(
|
|
|
1283
1271
|
|
|
1284
1272
|
|
|
1285
1273
|
def format_query_params(
|
|
1286
|
-
product_type: str, config: PluginConfig, query_dict:
|
|
1287
|
-
) ->
|
|
1274
|
+
product_type: str, config: PluginConfig, query_dict: dict[str, Any]
|
|
1275
|
+
) -> dict[str, Any]:
|
|
1288
1276
|
"""format the search parameters to query parameters"""
|
|
1289
1277
|
if "raise_errors" in query_dict.keys():
|
|
1290
1278
|
del query_dict["raise_errors"]
|
|
@@ -1296,7 +1284,7 @@ def format_query_params(
|
|
|
1296
1284
|
**config.products.get(product_type, {}).get("metadata_mapping", {}),
|
|
1297
1285
|
)
|
|
1298
1286
|
|
|
1299
|
-
query_params:
|
|
1287
|
+
query_params: dict[str, Any] = {}
|
|
1300
1288
|
# Get all the search parameters that are recognised as queryables by the
|
|
1301
1289
|
# provider (they appear in the queryables dictionary)
|
|
1302
1290
|
queryables = _get_queryables(query_dict, config, product_type_metadata_mapping)
|
|
@@ -1326,8 +1314,8 @@ def format_query_params(
|
|
|
1326
1314
|
query_params[eodag_search_key] = formatted_query_param
|
|
1327
1315
|
else:
|
|
1328
1316
|
provider_search_key, provider_value = parts
|
|
1329
|
-
query_params
|
|
1330
|
-
|
|
1317
|
+
query_params[provider_search_key] = format_metadata(
|
|
1318
|
+
provider_value, product_type, **query_dict
|
|
1331
1319
|
)
|
|
1332
1320
|
else:
|
|
1333
1321
|
query_params[provider_search_key] = user_input
|
|
@@ -1386,10 +1374,10 @@ def _resolve_hashes(formatted_query_param: str) -> str:
|
|
|
1386
1374
|
|
|
1387
1375
|
|
|
1388
1376
|
def _format_free_text_search(
|
|
1389
|
-
config: PluginConfig, metadata_mapping:
|
|
1390
|
-
) ->
|
|
1377
|
+
config: PluginConfig, metadata_mapping: dict[str, Any], **kwargs: Any
|
|
1378
|
+
) -> dict[str, Any]:
|
|
1391
1379
|
"""Build the free text search parameter using the search parameters"""
|
|
1392
|
-
query_params:
|
|
1380
|
+
query_params: dict[str, Any] = {}
|
|
1393
1381
|
if not getattr(config, "free_text_search_operations", None):
|
|
1394
1382
|
return query_params
|
|
1395
1383
|
for param, operations_config in config.free_text_search_operations.items():
|
|
@@ -1428,13 +1416,13 @@ def _format_free_text_search(
|
|
|
1428
1416
|
|
|
1429
1417
|
|
|
1430
1418
|
def _get_queryables(
|
|
1431
|
-
search_params:
|
|
1419
|
+
search_params: dict[str, Any],
|
|
1432
1420
|
config: PluginConfig,
|
|
1433
|
-
metadata_mapping:
|
|
1434
|
-
) ->
|
|
1421
|
+
metadata_mapping: dict[str, Any],
|
|
1422
|
+
) -> dict[str, Any]:
|
|
1435
1423
|
"""Retrieve the metadata mappings that are query-able"""
|
|
1436
1424
|
logger.debug("Retrieving queryable metadata from metadata_mapping")
|
|
1437
|
-
queryables:
|
|
1425
|
+
queryables: dict[str, Any] = {}
|
|
1438
1426
|
for eodag_search_key, user_input in search_params.items():
|
|
1439
1427
|
if user_input is not None:
|
|
1440
1428
|
md_mapping = metadata_mapping.get(eodag_search_key, (None, NOT_MAPPED))
|
|
@@ -1481,7 +1469,7 @@ def _get_queryables(
|
|
|
1481
1469
|
|
|
1482
1470
|
|
|
1483
1471
|
def get_queryable_from_provider(
|
|
1484
|
-
provider_queryable: str, metadata_mapping:
|
|
1472
|
+
provider_queryable: str, metadata_mapping: dict[str, Union[str, list[str]]]
|
|
1485
1473
|
) -> Optional[str]:
|
|
1486
1474
|
"""Get EODAG configured queryable parameter from provider queryable parameter
|
|
1487
1475
|
|
|
@@ -1505,7 +1493,7 @@ def get_queryable_from_provider(
|
|
|
1505
1493
|
|
|
1506
1494
|
|
|
1507
1495
|
def get_provider_queryable_path(
|
|
1508
|
-
queryable: str, metadata_mapping:
|
|
1496
|
+
queryable: str, metadata_mapping: dict[str, Union[str, list[str]]]
|
|
1509
1497
|
) -> Optional[str]:
|
|
1510
1498
|
"""Get EODAG configured queryable path from its parameter
|
|
1511
1499
|
|
|
@@ -1522,8 +1510,8 @@ def get_provider_queryable_path(
|
|
|
1522
1510
|
|
|
1523
1511
|
def get_provider_queryable_key(
|
|
1524
1512
|
eodag_key: str,
|
|
1525
|
-
provider_queryables:
|
|
1526
|
-
metadata_mapping:
|
|
1513
|
+
provider_queryables: dict[str, Any],
|
|
1514
|
+
metadata_mapping: dict[str, Union[list[Any], str]],
|
|
1527
1515
|
) -> str:
|
|
1528
1516
|
"""Finds the provider queryable corresponding to the given eodag key based on the metadata mapping
|
|
1529
1517
|
|
eodag/api/search_result.py
CHANGED
|
@@ -18,17 +18,7 @@
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
from collections import UserList
|
|
21
|
-
from typing import
|
|
22
|
-
TYPE_CHECKING,
|
|
23
|
-
Annotated,
|
|
24
|
-
Any,
|
|
25
|
-
Dict,
|
|
26
|
-
Iterable,
|
|
27
|
-
List,
|
|
28
|
-
Optional,
|
|
29
|
-
Tuple,
|
|
30
|
-
Union,
|
|
31
|
-
)
|
|
21
|
+
from typing import TYPE_CHECKING, Annotated, Any, Iterable, Optional, Union
|
|
32
22
|
|
|
33
23
|
from shapely.geometry import GeometryCollection, shape
|
|
34
24
|
from typing_extensions import Doc
|
|
@@ -56,17 +46,17 @@ class SearchResult(UserList):
|
|
|
56
46
|
:ivar number_matched: Estimated total number of matching results
|
|
57
47
|
"""
|
|
58
48
|
|
|
59
|
-
data:
|
|
49
|
+
data: list[EOProduct]
|
|
60
50
|
|
|
61
51
|
errors: Annotated[
|
|
62
|
-
|
|
52
|
+
list[tuple[str, Exception]], Doc("Tuple of provider name, exception")
|
|
63
53
|
]
|
|
64
54
|
|
|
65
55
|
def __init__(
|
|
66
56
|
self,
|
|
67
|
-
products:
|
|
57
|
+
products: list[EOProduct],
|
|
68
58
|
number_matched: Optional[int] = None,
|
|
69
|
-
errors:
|
|
59
|
+
errors: list[tuple[str, Exception]] = [],
|
|
70
60
|
) -> None:
|
|
71
61
|
super().__init__(products)
|
|
72
62
|
self.number_matched = number_matched
|
|
@@ -92,7 +82,7 @@ class SearchResult(UserList):
|
|
|
92
82
|
return self.crunch(FilterDate(dict(start=start, end=end)))
|
|
93
83
|
|
|
94
84
|
def filter_latest_intersect(
|
|
95
|
-
self, geometry: Union[
|
|
85
|
+
self, geometry: Union[dict[str, Any], BaseGeometry, Any]
|
|
96
86
|
) -> SearchResult:
|
|
97
87
|
"""
|
|
98
88
|
Apply :class:`~eodag.plugins.crunch.filter_latest_intersect.FilterLatestIntersect` crunch,
|
|
@@ -148,7 +138,7 @@ class SearchResult(UserList):
|
|
|
148
138
|
return self.filter_property(storageStatus="ONLINE")
|
|
149
139
|
|
|
150
140
|
@staticmethod
|
|
151
|
-
def from_geojson(feature_collection:
|
|
141
|
+
def from_geojson(feature_collection: dict[str, Any]) -> SearchResult:
|
|
152
142
|
"""Builds an :class:`~eodag.api.search_result.SearchResult` object from its representation as geojson
|
|
153
143
|
|
|
154
144
|
:param feature_collection: A collection representing a search result.
|
|
@@ -161,7 +151,7 @@ class SearchResult(UserList):
|
|
|
161
151
|
]
|
|
162
152
|
)
|
|
163
153
|
|
|
164
|
-
def as_geojson_object(self) ->
|
|
154
|
+
def as_geojson_object(self) -> dict[str, Any]:
|
|
165
155
|
"""GeoJSON representation of SearchResult"""
|
|
166
156
|
return {
|
|
167
157
|
"type": "FeatureCollection",
|
|
@@ -182,7 +172,7 @@ class SearchResult(UserList):
|
|
|
182
172
|
return self.as_shapely_geometry_object().wkt
|
|
183
173
|
|
|
184
174
|
@property
|
|
185
|
-
def __geo_interface__(self) ->
|
|
175
|
+
def __geo_interface__(self) -> dict[str, Any]:
|
|
186
176
|
"""Implements the geo-interface protocol.
|
|
187
177
|
|
|
188
178
|
See https://gist.github.com/sgillies/2217756
|
|
@@ -230,9 +220,9 @@ class RawSearchResult(UserList):
|
|
|
230
220
|
:param results: A list of raw/unparsed search results
|
|
231
221
|
"""
|
|
232
222
|
|
|
233
|
-
data:
|
|
234
|
-
query_params:
|
|
235
|
-
product_type_def_params:
|
|
223
|
+
data: list[Any]
|
|
224
|
+
query_params: dict[str, Any]
|
|
225
|
+
product_type_def_params: dict[str, Any]
|
|
236
226
|
|
|
237
|
-
def __init__(self, results:
|
|
227
|
+
def __init__(self, results: list[Any]) -> None:
|
|
238
228
|
super(RawSearchResult, self).__init__(results)
|
eodag/cli.py
CHANGED
|
@@ -48,7 +48,7 @@ import shutil
|
|
|
48
48
|
import sys
|
|
49
49
|
import textwrap
|
|
50
50
|
from importlib.metadata import metadata
|
|
51
|
-
from typing import TYPE_CHECKING, Any,
|
|
51
|
+
from typing import TYPE_CHECKING, Any, Mapping
|
|
52
52
|
|
|
53
53
|
import click
|
|
54
54
|
|
|
@@ -104,7 +104,7 @@ class MutuallyExclusiveOption(click.Option):
|
|
|
104
104
|
super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
|
|
105
105
|
|
|
106
106
|
def handle_parse_result(
|
|
107
|
-
self, ctx: Context, opts: Mapping[str, Any], args:
|
|
107
|
+
self, ctx: Context, opts: Mapping[str, Any], args: list[str]
|
|
108
108
|
):
|
|
109
109
|
"""Raise error or use parent handle_parse_result()"""
|
|
110
110
|
if self.mutually_exclusive.intersection(opts) and self.name in opts:
|
|
@@ -359,9 +359,9 @@ def search_crunch(ctx: Context, **kwargs: Any) -> None:
|
|
|
359
359
|
count = kwargs.pop("count")
|
|
360
360
|
|
|
361
361
|
# Process inputs for crunch
|
|
362
|
-
cruncher_names:
|
|
362
|
+
cruncher_names: set[Any] = set(kwargs.pop("cruncher") or [])
|
|
363
363
|
cruncher_args = kwargs.pop("cruncher_args")
|
|
364
|
-
cruncher_args_dict:
|
|
364
|
+
cruncher_args_dict: dict[str, dict[str, Any]] = {}
|
|
365
365
|
if cruncher_args:
|
|
366
366
|
for cruncher, argname, argval in cruncher_args:
|
|
367
367
|
cruncher_args_dict.setdefault(cruncher, {}).setdefault(argname, argval)
|