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.
Files changed (87) hide show
  1. eodag/api/core.py +174 -138
  2. eodag/api/product/_assets.py +44 -15
  3. eodag/api/product/_product.py +58 -47
  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 +117 -90
  10. eodag/api/search_result.py +13 -23
  11. eodag/cli.py +26 -5
  12. eodag/config.py +86 -92
  13. eodag/plugins/apis/base.py +1 -1
  14. eodag/plugins/apis/ecmwf.py +42 -22
  15. eodag/plugins/apis/usgs.py +17 -16
  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 +22 -16
  22. eodag/plugins/authentication/sas_auth.py +4 -4
  23. eodag/plugins/authentication/token.py +41 -10
  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 +6 -7
  32. eodag/plugins/download/aws.py +146 -87
  33. eodag/plugins/download/base.py +38 -56
  34. eodag/plugins/download/creodias_s3.py +29 -0
  35. eodag/plugins/download/http.py +173 -183
  36. eodag/plugins/download/s3rest.py +10 -11
  37. eodag/plugins/manager.py +10 -20
  38. eodag/plugins/search/__init__.py +6 -5
  39. eodag/plugins/search/base.py +90 -46
  40. eodag/plugins/search/build_search_result.py +1048 -361
  41. eodag/plugins/search/cop_marine.py +22 -12
  42. eodag/plugins/search/creodias_s3.py +9 -73
  43. eodag/plugins/search/csw.py +11 -11
  44. eodag/plugins/search/data_request_search.py +19 -18
  45. eodag/plugins/search/qssearch.py +99 -258
  46. eodag/plugins/search/stac_list_assets.py +85 -0
  47. eodag/plugins/search/static_stac_search.py +4 -4
  48. eodag/resources/ext_product_types.json +1 -1
  49. eodag/resources/product_types.yml +1134 -325
  50. eodag/resources/providers.yml +906 -2006
  51. eodag/resources/stac_api.yml +2 -2
  52. eodag/resources/user_conf_template.yml +10 -9
  53. eodag/rest/cache.py +2 -2
  54. eodag/rest/config.py +3 -3
  55. eodag/rest/core.py +112 -82
  56. eodag/rest/errors.py +5 -5
  57. eodag/rest/server.py +33 -14
  58. eodag/rest/stac.py +41 -38
  59. eodag/rest/types/collections_search.py +3 -3
  60. eodag/rest/types/eodag_search.py +29 -23
  61. eodag/rest/types/queryables.py +42 -31
  62. eodag/rest/types/stac_search.py +15 -25
  63. eodag/rest/utils/__init__.py +14 -21
  64. eodag/rest/utils/cql_evaluate.py +6 -6
  65. eodag/rest/utils/rfc3339.py +2 -2
  66. eodag/types/__init__.py +141 -32
  67. eodag/types/bbox.py +2 -2
  68. eodag/types/download_args.py +3 -3
  69. eodag/types/queryables.py +183 -72
  70. eodag/types/search_args.py +4 -4
  71. eodag/types/whoosh.py +127 -3
  72. eodag/utils/__init__.py +153 -51
  73. eodag/utils/exceptions.py +28 -21
  74. eodag/utils/import_system.py +2 -2
  75. eodag/utils/repr.py +65 -6
  76. eodag/utils/requests.py +13 -13
  77. eodag/utils/rest.py +2 -2
  78. eodag/utils/s3.py +231 -0
  79. eodag/utils/stac_reader.py +10 -10
  80. {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/METADATA +77 -76
  81. eodag-3.1.0.dist-info/RECORD +113 -0
  82. {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/WHEEL +1 -1
  83. {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/entry_points.txt +4 -2
  84. eodag/utils/constraints.py +0 -244
  85. eodag-3.0.1.dist-info/RECORD +0 -109
  86. {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/LICENSE +0 -0
  87. {eodag-3.0.1.dist-info → eodag-3.1.0.dist-info}/top_level.txt +0 -0
@@ -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
 
@@ -57,6 +57,11 @@ from eodag.utils import DEFAULT_ITEMS_PER_PAGE, DEFAULT_PAGE, parse_qs
57
57
  from eodag.utils.exceptions import NoMatchingProductType, UnsupportedProvider
58
58
  from eodag.utils.logging import setup_logging
59
59
 
60
+ try:
61
+ from eodag.rest.utils import LIVENESS_PROBE_PATH
62
+ except ImportError:
63
+ pass
64
+
60
65
  if TYPE_CHECKING:
61
66
  from click import Context
62
67
 
@@ -70,6 +75,18 @@ CRUNCHERS = [
70
75
  ]
71
76
 
72
77
 
78
+ class LivenessFilter:
79
+ """
80
+ Filter out requests to the liveness probe endpoint
81
+ """
82
+
83
+ def filter(self, record):
84
+ """
85
+ Filter method required by the Python logging API.
86
+ """
87
+ return LIVENESS_PROBE_PATH not in record.getMessage()
88
+
89
+
73
90
  class MutuallyExclusiveOption(click.Option):
74
91
  """Mutually Exclusive Options for Click
75
92
  from https://gist.github.com/jacobtolar/fb80d5552a9a9dfc32b12a829fa21c0c
@@ -87,7 +104,7 @@ class MutuallyExclusiveOption(click.Option):
87
104
  super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
88
105
 
89
106
  def handle_parse_result(
90
- self, ctx: Context, opts: Mapping[str, Any], args: List[str]
107
+ self, ctx: Context, opts: Mapping[str, Any], args: list[str]
91
108
  ):
92
109
  """Raise error or use parent handle_parse_result()"""
93
110
  if self.mutually_exclusive.intersection(opts) and self.name in opts:
@@ -342,9 +359,9 @@ def search_crunch(ctx: Context, **kwargs: Any) -> None:
342
359
  count = kwargs.pop("count")
343
360
 
344
361
  # Process inputs for crunch
345
- cruncher_names: Set[Any] = set(kwargs.pop("cruncher") or [])
362
+ cruncher_names: set[Any] = set(kwargs.pop("cruncher") or [])
346
363
  cruncher_args = kwargs.pop("cruncher_args")
347
- cruncher_args_dict: Dict[str, Dict[str, Any]] = {}
364
+ cruncher_args_dict: dict[str, dict[str, Any]] = {}
348
365
  if cruncher_args:
349
366
  for cruncher, argname, argval in cruncher_args:
350
367
  cruncher_args_dict.setdefault(cruncher, {}).setdefault(argname, argval)
@@ -679,7 +696,9 @@ def serve_rest(
679
696
  try:
680
697
  pid = os.fork()
681
698
  except OSError as e:
682
- raise Exception("%s [%d]" % (e.strerror, e.errno))
699
+ raise Exception(
700
+ "%s [%d]" % (e.strerror, e.errno) if e.errno is not None else e.strerror
701
+ )
683
702
 
684
703
  if pid == 0:
685
704
  os.setsid()
@@ -691,8 +710,10 @@ def serve_rest(
691
710
 
692
711
  logging_config = uvicorn.config.LOGGING_CONFIG
693
712
  uvicorn_fmt = "%(asctime)-15s %(name)-32s [%(levelname)-8s] %(message)s"
713
+ logging_config["filters"] = {"liveness": {"()": LivenessFilter}}
694
714
  logging_config["formatters"]["access"]["fmt"] = uvicorn_fmt
695
715
  logging_config["formatters"]["default"]["fmt"] = uvicorn_fmt
716
+ logging_config["loggers"]["uvicorn.access"]["filters"] = ["liveness"]
696
717
 
697
718
  eodag_formatter = logging.Formatter(
698
719
  "%(asctime)-15s %(name)-32s [%(levelname)-8s] (tid=%(thread)d) %(message)s"