eodag 3.4.3__py3-none-any.whl → 3.5.1__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 +90 -27
- eodag/api/product/_product.py +33 -0
- eodag/api/product/metadata_mapping.py +31 -2
- eodag/config.py +56 -10
- eodag/plugins/authentication/keycloak.py +3 -1
- eodag/plugins/authentication/openid_connect.py +21 -3
- eodag/plugins/authentication/token.py +14 -2
- eodag/plugins/authentication/token_exchange.py +1 -0
- eodag/plugins/download/aws.py +1 -1
- eodag/plugins/manager.py +1 -1
- eodag/plugins/search/base.py +3 -2
- eodag/plugins/search/build_search_result.py +13 -6
- eodag/plugins/search/data_request_search.py +14 -1
- eodag/plugins/search/qssearch.py +8 -2
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/providers.yml +4 -0
- eodag/rest/core.py +3 -1
- eodag/rest/errors.py +9 -4
- eodag/rest/server.py +3 -1
- eodag/rest/stac.py +22 -1
- eodag/utils/__init__.py +3 -0
- eodag/utils/cache.py +68 -0
- eodag/utils/env.py +29 -0
- {eodag-3.4.3.dist-info → eodag-3.5.1.dist-info}/METADATA +3 -3
- {eodag-3.4.3.dist-info → eodag-3.5.1.dist-info}/RECORD +29 -27
- {eodag-3.4.3.dist-info → eodag-3.5.1.dist-info}/WHEEL +0 -0
- {eodag-3.4.3.dist-info → eodag-3.5.1.dist-info}/entry_points.txt +0 -0
- {eodag-3.4.3.dist-info → eodag-3.5.1.dist-info}/licenses/LICENSE +0 -0
- {eodag-3.4.3.dist-info → eodag-3.5.1.dist-info}/top_level.txt +0 -0
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
# limitations under the License.
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
|
-
import functools
|
|
21
20
|
import hashlib
|
|
22
21
|
import logging
|
|
23
22
|
import re
|
|
@@ -61,6 +60,7 @@ from eodag.utils import (
|
|
|
61
60
|
get_geometry_from_various,
|
|
62
61
|
is_range_in_range,
|
|
63
62
|
)
|
|
63
|
+
from eodag.utils.cache import instance_cached_method
|
|
64
64
|
from eodag.utils.exceptions import DownloadError, NotAvailableError, ValidationError
|
|
65
65
|
from eodag.utils.requests import fetch_json
|
|
66
66
|
|
|
@@ -722,7 +722,7 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
722
722
|
"geometry",
|
|
723
723
|
}:
|
|
724
724
|
raise ValidationError(
|
|
725
|
-
f"{key} is not a queryable parameter for {self.provider}"
|
|
725
|
+
f"'{key}' is not a queryable parameter for {self.provider}", {key}
|
|
726
726
|
)
|
|
727
727
|
|
|
728
728
|
formated_filters[key] = v
|
|
@@ -781,7 +781,9 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
781
781
|
and keyword.removeprefix(ECMWF_PREFIX)
|
|
782
782
|
not in set(list(available_values.keys()) + [f["name"] for f in form])
|
|
783
783
|
):
|
|
784
|
-
raise ValidationError(
|
|
784
|
+
raise ValidationError(
|
|
785
|
+
f"'{keyword}' is not a queryable parameter", {keyword}
|
|
786
|
+
)
|
|
785
787
|
|
|
786
788
|
# generate queryables
|
|
787
789
|
if form:
|
|
@@ -868,7 +870,8 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
868
870
|
# we only compare list of strings.
|
|
869
871
|
if isinstance(values, dict):
|
|
870
872
|
raise ValidationError(
|
|
871
|
-
f"Parameter value as object is not supported: {keyword}={values}"
|
|
873
|
+
f"Parameter value as object is not supported: {keyword}={values}",
|
|
874
|
+
{keyword},
|
|
872
875
|
)
|
|
873
876
|
|
|
874
877
|
# We convert every single value to a list of string
|
|
@@ -934,7 +937,10 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
934
937
|
raise ValidationError(
|
|
935
938
|
f"{keyword}={values} is not available"
|
|
936
939
|
f"{all_keywords_str}."
|
|
937
|
-
f" Allowed values are {', '.join(allowed_values)}."
|
|
940
|
+
f" Allowed values are {', '.join(allowed_values)}.",
|
|
941
|
+
set(
|
|
942
|
+
[keyword] + [k for k in parsed_keywords if k in input_keywords]
|
|
943
|
+
),
|
|
938
944
|
)
|
|
939
945
|
|
|
940
946
|
parsed_keywords.append(keyword)
|
|
@@ -1093,6 +1099,7 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
1093
1099
|
|
|
1094
1100
|
return qp
|
|
1095
1101
|
|
|
1102
|
+
@instance_cached_method()
|
|
1096
1103
|
def _fetch_data(self, url: str) -> Any:
|
|
1097
1104
|
"""
|
|
1098
1105
|
fetches from a provider elements like constraints or forms.
|
|
@@ -1109,7 +1116,7 @@ class ECMWFSearch(PostJsonSearch):
|
|
|
1109
1116
|
else None
|
|
1110
1117
|
)
|
|
1111
1118
|
timeout = getattr(self.config, "timeout", DEFAULT_SEARCH_TIMEOUT)
|
|
1112
|
-
return
|
|
1119
|
+
return fetch_json(url, auth=auth, timeout=timeout)
|
|
1113
1120
|
|
|
1114
1121
|
def normalize_results(
|
|
1115
1122
|
self, results: RawSearchResult, **kwargs: Any
|
|
@@ -32,6 +32,7 @@ from eodag.api.product.metadata_mapping import (
|
|
|
32
32
|
)
|
|
33
33
|
from eodag.plugins.search import PreparedSearch
|
|
34
34
|
from eodag.plugins.search.base import Search
|
|
35
|
+
from eodag.types.queryables import Queryables
|
|
35
36
|
from eodag.utils import (
|
|
36
37
|
DEFAULT_ITEMS_PER_PAGE,
|
|
37
38
|
DEFAULT_MISSION_START_DATE,
|
|
@@ -359,7 +360,19 @@ class DataRequestSearch(Search):
|
|
|
359
360
|
ssl_verify = getattr(self.config.ssl_verify, "ssl_verify", True)
|
|
360
361
|
try:
|
|
361
362
|
url = self.config.data_request_url
|
|
362
|
-
|
|
363
|
+
try:
|
|
364
|
+
request_body = format_query_params(
|
|
365
|
+
eodag_product_type, self.config, kwargs
|
|
366
|
+
)
|
|
367
|
+
except ValidationError as err:
|
|
368
|
+
not_queryable_search_param = Queryables.get_queryable_from_alias(
|
|
369
|
+
str(err.message).split(":")[-1].strip()
|
|
370
|
+
)
|
|
371
|
+
raise ValidationError(
|
|
372
|
+
f"Search parameters which are not queryable are disallowed for {product_type} on "
|
|
373
|
+
f"{self.provider}: please remove '{not_queryable_search_param}' from your search parameters",
|
|
374
|
+
{not_queryable_search_param},
|
|
375
|
+
) from err
|
|
363
376
|
logger.debug(
|
|
364
377
|
f"Sending search job request to {url} with {str(request_body)}"
|
|
365
378
|
)
|
eodag/plugins/search/qssearch.py
CHANGED
|
@@ -811,7 +811,10 @@ class QueryStringSearch(Search):
|
|
|
811
811
|
) -> tuple[dict[str, Any], str]:
|
|
812
812
|
"""Build The query string using the search parameters"""
|
|
813
813
|
logger.debug("Building the query string that will be used for search")
|
|
814
|
-
|
|
814
|
+
error_context = f"Product type: {product_type} / provider : {self.provider}"
|
|
815
|
+
query_params = format_query_params(
|
|
816
|
+
product_type, self.config, query_dict, error_context
|
|
817
|
+
)
|
|
815
818
|
|
|
816
819
|
# Build the final query string, in one go without quoting it
|
|
817
820
|
# (some providers do not operate well with urlencoded and quoted query strings)
|
|
@@ -1781,7 +1784,10 @@ class StacSearch(PostJsonSearch):
|
|
|
1781
1784
|
query_dict.setdefault("startTimeFromAscendingNode", "..")
|
|
1782
1785
|
query_dict.setdefault("completionTimeFromAscendingNode", "..")
|
|
1783
1786
|
|
|
1784
|
-
|
|
1787
|
+
error_context = f"Product type: {product_type} / provider : {self.provider}"
|
|
1788
|
+
query_params = format_query_params(
|
|
1789
|
+
product_type, self.config, query_dict, error_context
|
|
1790
|
+
)
|
|
1785
1791
|
|
|
1786
1792
|
# Build the final query string, in one go without quoting it
|
|
1787
1793
|
# (some providers do not operate well with urlencoded and quoted query strings)
|