eodag 2.12.0__py3-none-any.whl → 3.0.0b1__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 +434 -319
- eodag/api/product/__init__.py +5 -1
- eodag/api/product/_assets.py +7 -2
- eodag/api/product/_product.py +46 -68
- eodag/api/product/metadata_mapping.py +181 -66
- eodag/api/search_result.py +21 -1
- eodag/cli.py +20 -6
- eodag/config.py +95 -6
- eodag/plugins/apis/base.py +8 -162
- eodag/plugins/apis/ecmwf.py +36 -24
- eodag/plugins/apis/usgs.py +40 -24
- eodag/plugins/authentication/aws_auth.py +2 -2
- eodag/plugins/authentication/header.py +31 -6
- eodag/plugins/authentication/keycloak.py +13 -84
- eodag/plugins/authentication/oauth.py +3 -3
- eodag/plugins/authentication/openid_connect.py +256 -46
- eodag/plugins/authentication/qsauth.py +3 -0
- eodag/plugins/authentication/sas_auth.py +8 -1
- eodag/plugins/authentication/token.py +92 -46
- eodag/plugins/authentication/token_exchange.py +120 -0
- eodag/plugins/download/aws.py +86 -91
- eodag/plugins/download/base.py +72 -40
- eodag/plugins/download/http.py +607 -264
- eodag/plugins/download/s3rest.py +28 -15
- eodag/plugins/manager.py +73 -57
- eodag/plugins/search/__init__.py +36 -0
- eodag/plugins/search/base.py +225 -18
- eodag/plugins/search/build_search_result.py +389 -32
- eodag/plugins/search/cop_marine.py +378 -0
- eodag/plugins/search/creodias_s3.py +15 -14
- eodag/plugins/search/csw.py +5 -7
- eodag/plugins/search/data_request_search.py +44 -20
- eodag/plugins/search/qssearch.py +508 -203
- eodag/plugins/search/static_stac_search.py +99 -36
- eodag/resources/constraints/climate-dt.json +13 -0
- eodag/resources/constraints/extremes-dt.json +8 -0
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +1897 -34
- eodag/resources/providers.yml +3539 -3277
- eodag/resources/stac.yml +48 -54
- eodag/resources/stac_api.yml +71 -25
- eodag/resources/stac_provider.yml +5 -0
- eodag/resources/user_conf_template.yml +51 -3
- eodag/rest/__init__.py +6 -0
- eodag/rest/cache.py +70 -0
- eodag/rest/config.py +68 -0
- eodag/rest/constants.py +27 -0
- eodag/rest/core.py +757 -0
- eodag/rest/server.py +397 -258
- eodag/rest/stac.py +438 -307
- eodag/rest/types/collections_search.py +44 -0
- eodag/rest/types/eodag_search.py +232 -43
- eodag/rest/types/{stac_queryables.py → queryables.py} +81 -43
- eodag/rest/types/stac_search.py +277 -0
- eodag/rest/utils/__init__.py +216 -0
- eodag/rest/utils/cql_evaluate.py +119 -0
- eodag/rest/utils/rfc3339.py +65 -0
- eodag/types/__init__.py +99 -9
- eodag/types/bbox.py +15 -14
- eodag/types/download_args.py +31 -0
- eodag/types/search_args.py +58 -7
- eodag/types/whoosh.py +81 -0
- eodag/utils/__init__.py +72 -9
- eodag/utils/constraints.py +37 -37
- eodag/utils/exceptions.py +23 -17
- eodag/utils/requests.py +138 -0
- eodag/utils/rest.py +104 -0
- eodag/utils/stac_reader.py +100 -16
- {eodag-2.12.0.dist-info → eodag-3.0.0b1.dist-info}/METADATA +64 -44
- eodag-3.0.0b1.dist-info/RECORD +109 -0
- {eodag-2.12.0.dist-info → eodag-3.0.0b1.dist-info}/WHEEL +1 -1
- {eodag-2.12.0.dist-info → eodag-3.0.0b1.dist-info}/entry_points.txt +6 -5
- eodag/plugins/apis/cds.py +0 -540
- eodag/rest/utils.py +0 -1133
- eodag-2.12.0.dist-info/RECORD +0 -94
- {eodag-2.12.0.dist-info → eodag-3.0.0b1.dist-info}/LICENSE +0 -0
- {eodag-2.12.0.dist-info → eodag-3.0.0b1.dist-info}/top_level.txt +0 -0
|
@@ -18,22 +18,20 @@
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
import logging
|
|
21
|
-
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
|
21
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, cast
|
|
22
|
+
from unittest import mock
|
|
22
23
|
|
|
23
24
|
import geojson
|
|
24
25
|
|
|
26
|
+
from eodag.api.product.metadata_mapping import get_metadata_path_value
|
|
25
27
|
from eodag.api.search_result import SearchResult
|
|
26
28
|
from eodag.plugins.crunch.filter_date import FilterDate
|
|
27
29
|
from eodag.plugins.crunch.filter_overlap import FilterOverlap
|
|
28
30
|
from eodag.plugins.crunch.filter_property import FilterProperty
|
|
31
|
+
from eodag.plugins.search import PreparedSearch
|
|
29
32
|
from eodag.plugins.search.qssearch import StacSearch
|
|
30
|
-
from eodag.utils import
|
|
31
|
-
|
|
32
|
-
DEFAULT_PAGE,
|
|
33
|
-
HTTP_REQ_TIMEOUT,
|
|
34
|
-
MockResponse,
|
|
35
|
-
)
|
|
36
|
-
from eodag.utils.stac_reader import fetch_stac_items
|
|
33
|
+
from eodag.utils import HTTP_REQ_TIMEOUT, MockResponse
|
|
34
|
+
from eodag.utils.stac_reader import fetch_stac_collections, fetch_stac_items
|
|
37
35
|
|
|
38
36
|
if TYPE_CHECKING:
|
|
39
37
|
from eodag.api.product import EOProduct
|
|
@@ -68,49 +66,112 @@ class StaticStacSearch(StacSearch):
|
|
|
68
66
|
"""
|
|
69
67
|
|
|
70
68
|
def __init__(self, provider: str, config: PluginConfig) -> None:
|
|
69
|
+
# prevent search parameters from being queried when they are known in the configuration or not
|
|
70
|
+
for param, mapping in config.metadata_mapping.items():
|
|
71
|
+
# only keep one queryable to allow the mock search request
|
|
72
|
+
if param != "productType":
|
|
73
|
+
config.metadata_mapping[param] = get_metadata_path_value(mapping)
|
|
74
|
+
config.discover_metadata["auto_discovery"] = False
|
|
75
|
+
# there is no endpoint for fetching queryables with a static search
|
|
76
|
+
config.discover_queryables["fetch_url"] = None
|
|
77
|
+
config.discover_queryables["product_type_fetch_url"] = None
|
|
78
|
+
|
|
71
79
|
super(StaticStacSearch, self).__init__(provider, config)
|
|
72
80
|
self.config.__dict__.setdefault("max_connections", 100)
|
|
73
81
|
self.config.__dict__.setdefault("timeout", HTTP_REQ_TIMEOUT)
|
|
82
|
+
self.config.__dict__.setdefault("ssl_verify", True)
|
|
83
|
+
self.config.__dict__.setdefault("pagination", {})
|
|
84
|
+
self.config.__dict__["pagination"].setdefault(
|
|
85
|
+
"total_items_nb_key_path", "$.null"
|
|
86
|
+
)
|
|
87
|
+
self.config.__dict__["pagination"].setdefault("max_items_per_page", -1)
|
|
74
88
|
|
|
75
|
-
def discover_product_types(self) -> Dict[str, Any]:
|
|
76
|
-
"""Fetch product types
|
|
89
|
+
def discover_product_types(self, **kwargs: Any) -> Optional[Dict[str, Any]]:
|
|
90
|
+
"""Fetch product types list from a static STAC Catalog provider using `discover_product_types` conf
|
|
77
91
|
|
|
78
|
-
:returns:
|
|
79
|
-
:rtype:
|
|
92
|
+
:returns: configuration dict containing fetched product types information
|
|
93
|
+
:rtype: Optional[Dict[str, Any]]
|
|
80
94
|
"""
|
|
81
|
-
|
|
95
|
+
fetch_url = cast(
|
|
96
|
+
str,
|
|
97
|
+
self.config.discover_product_types["fetch_url"].format(
|
|
98
|
+
**self.config.__dict__
|
|
99
|
+
),
|
|
100
|
+
)
|
|
101
|
+
collections = fetch_stac_collections(
|
|
102
|
+
fetch_url,
|
|
103
|
+
collection=kwargs.get("q"),
|
|
104
|
+
max_connections=self.config.max_connections,
|
|
105
|
+
timeout=int(self.config.timeout),
|
|
106
|
+
ssl_verify=self.config.ssl_verify,
|
|
107
|
+
)
|
|
108
|
+
if "q" in kwargs:
|
|
109
|
+
collections = [c for c in collections if c["id"] == kwargs["q"]]
|
|
110
|
+
collections_mock_response = {"collections": collections}
|
|
111
|
+
|
|
112
|
+
# discover_product_types on mocked QueryStringSearch._request
|
|
113
|
+
with mock.patch(
|
|
114
|
+
"eodag.plugins.search.qssearch.QueryStringSearch._request",
|
|
115
|
+
autospec=True,
|
|
116
|
+
return_value=MockResponse(collections_mock_response, 200),
|
|
117
|
+
):
|
|
118
|
+
conf_update_dict = super(StaticStacSearch, self).discover_product_types(
|
|
119
|
+
**kwargs
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
return conf_update_dict
|
|
82
123
|
|
|
83
124
|
def query(
|
|
84
125
|
self,
|
|
85
|
-
|
|
86
|
-
items_per_page: int = DEFAULT_ITEMS_PER_PAGE,
|
|
87
|
-
page: int = DEFAULT_PAGE,
|
|
88
|
-
count: bool = True,
|
|
126
|
+
prep: PreparedSearch = PreparedSearch(),
|
|
89
127
|
**kwargs: Any,
|
|
90
128
|
) -> Tuple[List[EOProduct], Optional[int]]:
|
|
91
129
|
"""Perform a search on a static STAC Catalog"""
|
|
92
130
|
|
|
131
|
+
# only return 1 page if pagination is disabled
|
|
132
|
+
if (
|
|
133
|
+
prep.page
|
|
134
|
+
and prep.page > 1
|
|
135
|
+
and prep.items_per_page is not None
|
|
136
|
+
and prep.items_per_page <= 0
|
|
137
|
+
):
|
|
138
|
+
return ([], 0) if prep.count else ([], None)
|
|
139
|
+
|
|
140
|
+
product_type = kwargs.get("productType", prep.product_type)
|
|
141
|
+
# provider product type specific conf
|
|
142
|
+
self.product_type_def_params = (
|
|
143
|
+
self.get_product_type_def_params(product_type, **kwargs)
|
|
144
|
+
if product_type is not None
|
|
145
|
+
else {}
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
for collection in self.get_collections(prep, **kwargs):
|
|
149
|
+
# skip empty collection if one is required in api_endpoint
|
|
150
|
+
if "{collection}" in self.config.api_endpoint and not collection:
|
|
151
|
+
continue
|
|
152
|
+
search_endpoint = self.config.api_endpoint.rstrip("/").format(
|
|
153
|
+
collection=collection
|
|
154
|
+
)
|
|
155
|
+
|
|
93
156
|
features = fetch_stac_items(
|
|
94
|
-
|
|
157
|
+
search_endpoint,
|
|
95
158
|
recursive=True,
|
|
96
159
|
max_connections=self.config.max_connections,
|
|
97
|
-
timeout=self.config.timeout,
|
|
160
|
+
timeout=int(self.config.timeout),
|
|
161
|
+
ssl_verify=self.config.ssl_verify,
|
|
98
162
|
)
|
|
99
163
|
nb_features = len(features)
|
|
100
164
|
feature_collection = geojson.FeatureCollection(features)
|
|
101
165
|
|
|
102
|
-
#
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
166
|
+
# query on mocked StacSearch._request
|
|
167
|
+
with mock.patch(
|
|
168
|
+
"eodag.plugins.search.qssearch.StacSearch._request",
|
|
169
|
+
autospec=True,
|
|
170
|
+
return_value=MockResponse(feature_collection, 200),
|
|
171
|
+
):
|
|
172
|
+
eo_products, _ = super(StaticStacSearch, self).query(
|
|
173
|
+
PreparedSearch(items_per_page=nb_features, page=1, count=True), **kwargs
|
|
107
174
|
)
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
# query on mocked StacSearch
|
|
111
|
-
eo_products, _ = super(StaticStacSearch, self).query(
|
|
112
|
-
items_per_page=nb_features, page=1, count=True, **kwargs
|
|
113
|
-
)
|
|
114
175
|
# filter using query params
|
|
115
176
|
search_result = SearchResult(eo_products)
|
|
116
177
|
# Filter by date
|
|
@@ -124,9 +185,10 @@ class StaticStacSearch(StacSearch):
|
|
|
124
185
|
)
|
|
125
186
|
|
|
126
187
|
# Filter by geometry
|
|
127
|
-
|
|
188
|
+
geometry = kwargs.pop("geometry", None)
|
|
189
|
+
if geometry:
|
|
128
190
|
search_result = search_result.crunch(
|
|
129
|
-
FilterOverlap({"intersects": True}), geometry=
|
|
191
|
+
FilterOverlap({"intersects": True}), geometry=geometry
|
|
130
192
|
)
|
|
131
193
|
# Filter by cloudCover
|
|
132
194
|
if "cloudCover" in kwargs.keys():
|
|
@@ -151,7 +213,8 @@ class StaticStacSearch(StacSearch):
|
|
|
151
213
|
FilterProperty({property_key: property_value, "operator": "eq"})
|
|
152
214
|
)
|
|
153
215
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
216
|
+
return (
|
|
217
|
+
(search_result.data, len(search_result))
|
|
218
|
+
if prep.count
|
|
219
|
+
else (search_result.data, None)
|
|
220
|
+
)
|