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.
Files changed (85) hide show
  1. eodag/api/core.py +59 -52
  2. eodag/api/product/_assets.py +5 -5
  3. eodag/api/product/_product.py +27 -12
  4. eodag/api/product/drivers/__init__.py +81 -4
  5. eodag/api/product/drivers/base.py +65 -4
  6. eodag/api/product/drivers/generic.py +65 -0
  7. eodag/api/product/drivers/sentinel1.py +97 -0
  8. eodag/api/product/drivers/sentinel2.py +95 -0
  9. eodag/api/product/metadata_mapping.py +62 -74
  10. eodag/api/search_result.py +13 -23
  11. eodag/cli.py +4 -4
  12. eodag/config.py +66 -69
  13. eodag/plugins/apis/base.py +1 -1
  14. eodag/plugins/apis/ecmwf.py +10 -9
  15. eodag/plugins/apis/usgs.py +11 -10
  16. eodag/plugins/authentication/aws_auth.py +16 -13
  17. eodag/plugins/authentication/base.py +5 -3
  18. eodag/plugins/authentication/header.py +3 -3
  19. eodag/plugins/authentication/keycloak.py +4 -4
  20. eodag/plugins/authentication/oauth.py +7 -3
  21. eodag/plugins/authentication/openid_connect.py +14 -14
  22. eodag/plugins/authentication/sas_auth.py +4 -4
  23. eodag/plugins/authentication/token.py +7 -7
  24. eodag/plugins/authentication/token_exchange.py +1 -1
  25. eodag/plugins/base.py +4 -4
  26. eodag/plugins/crunch/base.py +4 -4
  27. eodag/plugins/crunch/filter_date.py +4 -4
  28. eodag/plugins/crunch/filter_latest_intersect.py +6 -6
  29. eodag/plugins/crunch/filter_latest_tpl_name.py +7 -7
  30. eodag/plugins/crunch/filter_overlap.py +4 -4
  31. eodag/plugins/crunch/filter_property.py +4 -4
  32. eodag/plugins/download/aws.py +47 -66
  33. eodag/plugins/download/base.py +8 -17
  34. eodag/plugins/download/creodias_s3.py +2 -2
  35. eodag/plugins/download/http.py +30 -32
  36. eodag/plugins/download/s3rest.py +5 -4
  37. eodag/plugins/manager.py +10 -20
  38. eodag/plugins/search/__init__.py +6 -5
  39. eodag/plugins/search/base.py +35 -40
  40. eodag/plugins/search/build_search_result.py +69 -68
  41. eodag/plugins/search/cop_marine.py +22 -12
  42. eodag/plugins/search/creodias_s3.py +8 -78
  43. eodag/plugins/search/csw.py +11 -11
  44. eodag/plugins/search/data_request_search.py +16 -15
  45. eodag/plugins/search/qssearch.py +56 -52
  46. eodag/plugins/search/stac_list_assets.py +85 -0
  47. eodag/plugins/search/static_stac_search.py +3 -3
  48. eodag/resources/ext_product_types.json +1 -1
  49. eodag/resources/product_types.yml +288 -288
  50. eodag/resources/providers.yml +146 -6
  51. eodag/resources/stac_api.yml +2 -2
  52. eodag/resources/user_conf_template.yml +11 -0
  53. eodag/rest/cache.py +2 -2
  54. eodag/rest/config.py +3 -3
  55. eodag/rest/core.py +24 -24
  56. eodag/rest/errors.py +5 -5
  57. eodag/rest/server.py +3 -11
  58. eodag/rest/stac.py +40 -38
  59. eodag/rest/types/collections_search.py +3 -3
  60. eodag/rest/types/eodag_search.py +23 -23
  61. eodag/rest/types/queryables.py +13 -13
  62. eodag/rest/types/stac_search.py +15 -25
  63. eodag/rest/utils/__init__.py +11 -21
  64. eodag/rest/utils/cql_evaluate.py +6 -6
  65. eodag/rest/utils/rfc3339.py +2 -2
  66. eodag/types/__init__.py +24 -18
  67. eodag/types/bbox.py +2 -2
  68. eodag/types/download_args.py +2 -2
  69. eodag/types/queryables.py +5 -2
  70. eodag/types/search_args.py +4 -4
  71. eodag/types/whoosh.py +1 -3
  72. eodag/utils/__init__.py +81 -40
  73. eodag/utils/exceptions.py +2 -2
  74. eodag/utils/import_system.py +2 -2
  75. eodag/utils/requests.py +2 -2
  76. eodag/utils/rest.py +2 -2
  77. eodag/utils/s3.py +208 -0
  78. eodag/utils/stac_reader.py +10 -10
  79. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/METADATA +5 -4
  80. eodag-3.1.0b2.dist-info/RECORD +113 -0
  81. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/entry_points.txt +1 -0
  82. eodag-3.1.0b1.dist-info/RECORD +0 -108
  83. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/LICENSE +0 -0
  84. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/WHEEL +0 -0
  85. {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, List[str]],
92
- ) -> Tuple[Union[List[str], None], str]:
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, List[str]]) -> 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: List[str]) -> str:
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) -> List[List[float]]:
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) -> List[float]:
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.bound[0])
360
- min_lat = min(min_lat, geom.bound[1])
361
- max_lon = max(max_lon, geom.bound[2])
362
- max_lat = max(max_lat, geom.bound[3])
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) -> List[float]:
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: List[Polygon] = []
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
- ) -> Dict[str, float]:
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[Dict[Any, Any], List[Any]], args: str
518
- ) -> Union[Dict[Any, Any], List[Any]]:
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: Dict[Any, Any], args: str
529
- ) -> Dict[Any, Any]:
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: Dict[Any, Any], jsonpath_filter_str: str
540
- ) -> Dict[Any, Any]:
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) -> Dict[str, str]:
620
- parts: List[str] = re.split(r"_(?!_)", product_id)
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) -> Dict[str, str]:
655
- parts: List[str] = re.split(r"_(?!_)", product_id)
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) -> Dict[str, str]:
672
- parts: List[str] = re.split(r"_(?!_)", product_id)
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) -> List[int]:
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
- ) -> Dict[str, Union[List[str], str]]:
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
- ) -> Dict[str, List[str]]:
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) -> List[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: List[Dict[str, str]], asset_name_key: str = "title"
865
- ) -> Dict[str, Dict[str, str]]:
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: List[str] = []
893
- assets_dict: Dict[str, Dict[str, str]] = {}
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: List[int] = []
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: Dict[str, Any],
929
- mapping: Dict[str, Any],
930
- discovery_config: Optional[Dict[str, Any]] = None,
931
- ) -> Dict[str, Any]:
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: Dict[str, Any] = {}
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[Dict[str, Any]] = None,
1089
- ) -> Dict[str, Any]:
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: Dict[str, Any] = {}
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: Dict[str, Any],
1236
- dest_dict: Dict[str, Any] = {},
1223
+ src_dict: dict[str, Any],
1224
+ dest_dict: dict[str, Any] = {},
1237
1225
  result_type: str = "json",
1238
- ) -> Dict[str, Any]:
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: Dict[str, Any]
1287
- ) -> Dict[str, Any]:
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: Dict[str, Any] = {}
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.setdefault(provider_search_key, []).append(
1330
- format_metadata(provider_value, product_type, **query_dict)
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: Dict[str, Any], **kwargs: Any
1390
- ) -> Dict[str, Any]:
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: Dict[str, Any] = {}
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: Dict[str, Any],
1419
+ search_params: dict[str, Any],
1432
1420
  config: PluginConfig,
1433
- metadata_mapping: Dict[str, Any],
1434
- ) -> Dict[str, Any]:
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: Dict[str, Any] = {}
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: Dict[str, Union[str, List[str]]]
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: Dict[str, Union[str, List[str]]]
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: Dict[str, Any],
1526
- metadata_mapping: Dict[str, Union[List[Any], str]],
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
 
@@ -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: List[EOProduct]
49
+ data: list[EOProduct]
60
50
 
61
51
  errors: Annotated[
62
- List[Tuple[str, Exception]], Doc("Tuple of provider name, exception")
52
+ list[tuple[str, Exception]], Doc("Tuple of provider name, exception")
63
53
  ]
64
54
 
65
55
  def __init__(
66
56
  self,
67
- products: List[EOProduct],
57
+ products: list[EOProduct],
68
58
  number_matched: Optional[int] = None,
69
- errors: List[Tuple[str, Exception]] = [],
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[Dict[str, Any], BaseGeometry, Any]
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: Dict[str, Any]) -> SearchResult:
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) -> Dict[str, Any]:
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) -> Dict[str, Any]:
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: List[Any]
234
- query_params: Dict[str, Any]
235
- product_type_def_params: Dict[str, Any]
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: List[Any]) -> None:
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, Dict, List, Mapping, Set
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: List[str]
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: Set[Any] = set(kwargs.pop("cruncher") or [])
362
+ cruncher_names: set[Any] = set(kwargs.pop("cruncher") or [])
363
363
  cruncher_args = kwargs.pop("cruncher_args")
364
- cruncher_args_dict: Dict[str, Dict[str, Any]] = {}
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)