eodag 3.0.1__py3-none-any.whl → 3.1.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 +116 -86
- eodag/api/product/_assets.py +6 -6
- eodag/api/product/_product.py +18 -18
- eodag/api/product/metadata_mapping.py +39 -11
- eodag/cli.py +22 -1
- eodag/config.py +14 -14
- eodag/plugins/apis/ecmwf.py +37 -14
- eodag/plugins/apis/usgs.py +5 -5
- eodag/plugins/authentication/openid_connect.py +2 -2
- eodag/plugins/authentication/token.py +37 -6
- eodag/plugins/crunch/filter_property.py +2 -3
- eodag/plugins/download/aws.py +11 -12
- eodag/plugins/download/base.py +30 -39
- eodag/plugins/download/creodias_s3.py +29 -0
- eodag/plugins/download/http.py +144 -152
- eodag/plugins/download/s3rest.py +5 -7
- eodag/plugins/search/base.py +73 -25
- eodag/plugins/search/build_search_result.py +1047 -310
- eodag/plugins/search/creodias_s3.py +25 -19
- eodag/plugins/search/data_request_search.py +1 -1
- eodag/plugins/search/qssearch.py +51 -139
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +391 -32
- eodag/resources/providers.yml +678 -1744
- eodag/rest/core.py +92 -62
- eodag/rest/server.py +31 -4
- eodag/rest/types/eodag_search.py +6 -0
- eodag/rest/types/queryables.py +5 -6
- eodag/rest/utils/__init__.py +3 -0
- eodag/types/__init__.py +56 -15
- eodag/types/download_args.py +2 -2
- eodag/types/queryables.py +180 -72
- eodag/types/whoosh.py +126 -0
- eodag/utils/__init__.py +71 -10
- eodag/utils/exceptions.py +27 -20
- eodag/utils/repr.py +65 -6
- eodag/utils/requests.py +11 -11
- {eodag-3.0.1.dist-info → eodag-3.1.0b1.dist-info}/METADATA +76 -76
- {eodag-3.0.1.dist-info → eodag-3.1.0b1.dist-info}/RECORD +43 -44
- {eodag-3.0.1.dist-info → eodag-3.1.0b1.dist-info}/WHEEL +1 -1
- {eodag-3.0.1.dist-info → eodag-3.1.0b1.dist-info}/entry_points.txt +3 -2
- eodag/utils/constraints.py +0 -244
- {eodag-3.0.1.dist-info → eodag-3.1.0b1.dist-info}/LICENSE +0 -0
- {eodag-3.0.1.dist-info → eodag-3.1.0b1.dist-info}/top_level.txt +0 -0
|
@@ -42,6 +42,7 @@ logger = logging.getLogger("eodag.search.creodiass3")
|
|
|
42
42
|
|
|
43
43
|
def patched_register_downloader(self, downloader, authenticator):
|
|
44
44
|
"""Add the download information to the product.
|
|
45
|
+
|
|
45
46
|
:param self: product to which information should be added
|
|
46
47
|
:param downloader: The download method that it can use
|
|
47
48
|
:class:`~eodag.plugins.download.base.Download` or
|
|
@@ -59,7 +60,7 @@ def patched_register_downloader(self, downloader, authenticator):
|
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
def _update_assets(product: EOProduct, config: PluginConfig, auth: AwsAuth):
|
|
62
|
-
product.assets =
|
|
63
|
+
product.assets = AssetsDict(product)
|
|
63
64
|
prefix = (
|
|
64
65
|
product.properties.get("productIdentifier", None).replace("/eodata/", "") + "/"
|
|
65
66
|
)
|
|
@@ -81,27 +82,32 @@ def _update_assets(product: EOProduct, config: PluginConfig, auth: AwsAuth):
|
|
|
81
82
|
)
|
|
82
83
|
logger.debug("Listing assets in %s", prefix)
|
|
83
84
|
product.assets = AssetsDict(product)
|
|
84
|
-
|
|
85
|
+
s3_res = auth.s3_client.list_objects(
|
|
85
86
|
Bucket=config.s3_bucket, Prefix=prefix, MaxKeys=300
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"
|
|
94
|
-
if asset_basename.split(".")[-1] in DATA_EXTENSIONS
|
|
95
|
-
else "metadata"
|
|
87
|
+
)
|
|
88
|
+
# check if product path has assets or is already a file
|
|
89
|
+
if "Contents" in s3_res:
|
|
90
|
+
for asset in s3_res["Contents"]:
|
|
91
|
+
asset_basename = (
|
|
92
|
+
asset["Key"].split("/")[-1]
|
|
93
|
+
if "/" in asset["Key"]
|
|
94
|
+
else asset["Key"]
|
|
96
95
|
)
|
|
97
96
|
|
|
98
|
-
product.assets
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
if len(asset_basename) > 0 and asset_basename not in product.assets:
|
|
98
|
+
role = (
|
|
99
|
+
"data"
|
|
100
|
+
if asset_basename.split(".")[-1] in DATA_EXTENSIONS
|
|
101
|
+
else "metadata"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
product.assets[asset_basename] = {
|
|
105
|
+
"title": asset_basename,
|
|
106
|
+
"roles": [role],
|
|
107
|
+
"href": f"s3://{config.s3_bucket}/{asset['Key']}",
|
|
108
|
+
}
|
|
109
|
+
if mime_type := guess_file_type(asset["Key"]):
|
|
110
|
+
product.assets[asset_basename]["type"] = mime_type
|
|
105
111
|
# update driver
|
|
106
112
|
product.driver = product.get_driver()
|
|
107
113
|
|
|
@@ -116,7 +116,7 @@ class DataRequestSearch(Search):
|
|
|
116
116
|
(``Dict[str, str]``): mapping for product type metadata (e.g. ``abstract``, ``licence``) which can be parsed
|
|
117
117
|
from the provider result
|
|
118
118
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.generic_product_type_parsable_properties`
|
|
119
|
-
(``Dict[str, str]``): mapping for product type properties which can be parsed from the result
|
|
119
|
+
(``Dict[str, str]``): mapping for product type properties which can be parsed from the result and are not
|
|
120
120
|
product type metadata
|
|
121
121
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.single_collection_fetch_url` (``str``): url to fetch
|
|
122
122
|
data for a single collection; used if product type metadata is not available from the endpoint given in
|
eodag/plugins/search/qssearch.py
CHANGED
|
@@ -20,7 +20,7 @@ from __future__ import annotations
|
|
|
20
20
|
import logging
|
|
21
21
|
import re
|
|
22
22
|
from copy import copy as copy_copy
|
|
23
|
-
from datetime import datetime
|
|
23
|
+
from datetime import datetime, timedelta
|
|
24
24
|
from typing import (
|
|
25
25
|
TYPE_CHECKING,
|
|
26
26
|
Annotated,
|
|
@@ -75,9 +75,9 @@ from eodag.api.search_result import RawSearchResult
|
|
|
75
75
|
from eodag.plugins.search import PreparedSearch
|
|
76
76
|
from eodag.plugins.search.base import Search
|
|
77
77
|
from eodag.types import json_field_definition_to_python, model_fields_to_annotated
|
|
78
|
-
from eodag.types.queryables import CommonQueryables
|
|
79
78
|
from eodag.types.search_args import SortByList
|
|
80
79
|
from eodag.utils import (
|
|
80
|
+
DEFAULT_MISSION_START_DATE,
|
|
81
81
|
GENERIC_PRODUCT_TYPE,
|
|
82
82
|
HTTP_REQ_TIMEOUT,
|
|
83
83
|
REQ_RETRY_BACKOFF_FACTOR,
|
|
@@ -94,10 +94,6 @@ from eodag.utils import (
|
|
|
94
94
|
update_nested_dict,
|
|
95
95
|
urlencode,
|
|
96
96
|
)
|
|
97
|
-
from eodag.utils.constraints import (
|
|
98
|
-
fetch_constraints,
|
|
99
|
-
get_constraint_queryables_with_additional_params,
|
|
100
|
-
)
|
|
101
97
|
from eodag.utils.exceptions import (
|
|
102
98
|
AuthenticationError,
|
|
103
99
|
MisconfiguredError,
|
|
@@ -190,7 +186,10 @@ class QueryStringSearch(Search):
|
|
|
190
186
|
(``Dict[str, str]``): mapping for product type metadata (e.g. ``abstract``, ``licence``) which can be parsed
|
|
191
187
|
from the provider result
|
|
192
188
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.generic_product_type_parsable_properties`
|
|
193
|
-
(``Dict[str, str]``): mapping for product type properties which can be parsed from the result
|
|
189
|
+
(``Dict[str, str]``): mapping for product type properties which can be parsed from the result and are not
|
|
190
|
+
product type metadata
|
|
191
|
+
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.generic_product_type_unparsable_properties`
|
|
192
|
+
(``Dict[str, str]``): mapping for product type properties which cannot be parsed from the result and are not
|
|
194
193
|
product type metadata
|
|
195
194
|
* :attr:`~eodag.config.PluginConfig.DiscoverProductTypes.single_collection_fetch_url` (``str``): url to fetch
|
|
196
195
|
data for a single collection; used if product type metadata is not available from the endpoint given in
|
|
@@ -282,13 +281,9 @@ class QueryStringSearch(Search):
|
|
|
282
281
|
|
|
283
282
|
* :attr:`~eodag.config.PluginConfig.constraints_file_url` (``str``): url to fetch the constraints for a specific
|
|
284
283
|
product type, can be an http url or a path to a file; the constraints are used to build queryables
|
|
285
|
-
* :attr:`~eodag.config.PluginConfig.constraints_file_dataset_key` (``str``): key which is used in the eodag
|
|
286
|
-
configuration to map the eodag product type to the provider product type; default: ``dataset``
|
|
287
284
|
* :attr:`~eodag.config.PluginConfig.constraints_entry` (``str``): key in the json result where the constraints
|
|
288
285
|
can be found; if not given, it is assumed that the constraints are on top level of the result, i.e.
|
|
289
286
|
the result is an array of constraints
|
|
290
|
-
* :attr:`~eodag.config.PluginConfig.stop_without_constraints_entry_key` (``bool``): if true only a provider
|
|
291
|
-
result containing `constraints_entry` is accepted as valid and used to create constraints; default: ``False``
|
|
292
287
|
"""
|
|
293
288
|
|
|
294
289
|
extract_properties: Dict[str, Callable[..., Dict[str, Any]]] = {
|
|
@@ -641,7 +636,11 @@ class QueryStringSearch(Search):
|
|
|
641
636
|
][kf]
|
|
642
637
|
)
|
|
643
638
|
for kf in keywords_fields
|
|
644
|
-
if
|
|
639
|
+
if kf
|
|
640
|
+
in conf_update_dict["product_types_config"][
|
|
641
|
+
generic_product_type_id
|
|
642
|
+
]
|
|
643
|
+
and conf_update_dict["product_types_config"][
|
|
645
644
|
generic_product_type_id
|
|
646
645
|
][kf]
|
|
647
646
|
!= NOT_AVAILABLE
|
|
@@ -723,102 +722,6 @@ class QueryStringSearch(Search):
|
|
|
723
722
|
self.config.discover_product_types["single_product_type_parsable_metadata"],
|
|
724
723
|
)
|
|
725
724
|
|
|
726
|
-
def discover_queryables(
|
|
727
|
-
self, **kwargs: Any
|
|
728
|
-
) -> Optional[Dict[str, Annotated[Any, FieldInfo]]]:
|
|
729
|
-
"""Fetch queryables list from provider using its constraints file
|
|
730
|
-
|
|
731
|
-
:param kwargs: additional filters for queryables (`productType` and other search
|
|
732
|
-
arguments)
|
|
733
|
-
:returns: fetched queryable parameters dict
|
|
734
|
-
"""
|
|
735
|
-
product_type = kwargs.pop("productType", None)
|
|
736
|
-
if not product_type:
|
|
737
|
-
return {}
|
|
738
|
-
constraints_file_url = getattr(self.config, "constraints_file_url", "")
|
|
739
|
-
if not constraints_file_url:
|
|
740
|
-
return {}
|
|
741
|
-
|
|
742
|
-
constraints_file_dataset_key = getattr(
|
|
743
|
-
self.config, "constraints_file_dataset_key", "dataset"
|
|
744
|
-
)
|
|
745
|
-
provider_product_type = self.config.products.get(product_type, {}).get(
|
|
746
|
-
constraints_file_dataset_key, None
|
|
747
|
-
)
|
|
748
|
-
|
|
749
|
-
# defaults
|
|
750
|
-
default_queryables = self._get_defaults_as_queryables(product_type)
|
|
751
|
-
# remove unwanted queryables
|
|
752
|
-
for param in getattr(self.config, "remove_from_queryables", []):
|
|
753
|
-
default_queryables.pop(param, None)
|
|
754
|
-
|
|
755
|
-
non_empty_kwargs = {k: v for k, v in kwargs.items() if v}
|
|
756
|
-
|
|
757
|
-
if "{" in constraints_file_url:
|
|
758
|
-
constraints_file_url = constraints_file_url.format(
|
|
759
|
-
dataset=provider_product_type
|
|
760
|
-
)
|
|
761
|
-
constraints = fetch_constraints(constraints_file_url, self)
|
|
762
|
-
if not constraints:
|
|
763
|
-
return default_queryables
|
|
764
|
-
|
|
765
|
-
constraint_params: Dict[str, Dict[str, Set[Any]]] = {}
|
|
766
|
-
if len(kwargs) == 0:
|
|
767
|
-
# get values from constraints without additional filters
|
|
768
|
-
for constraint in constraints:
|
|
769
|
-
for key in constraint.keys():
|
|
770
|
-
if key in constraint_params:
|
|
771
|
-
constraint_params[key]["enum"].update(constraint[key])
|
|
772
|
-
else:
|
|
773
|
-
constraint_params[key] = {"enum": set(constraint[key])}
|
|
774
|
-
else:
|
|
775
|
-
# get values from constraints with additional filters
|
|
776
|
-
constraints_input_params = {k: v for k, v in non_empty_kwargs.items()}
|
|
777
|
-
constraint_params = get_constraint_queryables_with_additional_params(
|
|
778
|
-
constraints, constraints_input_params, self, product_type
|
|
779
|
-
)
|
|
780
|
-
# query params that are not in constraints but might be default queryables
|
|
781
|
-
if len(constraint_params) == 1 and "not_available" in constraint_params:
|
|
782
|
-
not_queryables = set()
|
|
783
|
-
for constraint_param in constraint_params["not_available"]["enum"]:
|
|
784
|
-
param = CommonQueryables.get_queryable_from_alias(constraint_param)
|
|
785
|
-
if param in dict(
|
|
786
|
-
CommonQueryables.model_fields, **default_queryables
|
|
787
|
-
):
|
|
788
|
-
non_empty_kwargs.pop(constraint_param)
|
|
789
|
-
else:
|
|
790
|
-
not_queryables.add(constraint_param)
|
|
791
|
-
if not_queryables:
|
|
792
|
-
raise ValidationError(
|
|
793
|
-
f"parameter(s) {str(not_queryables)} not queryable"
|
|
794
|
-
)
|
|
795
|
-
else:
|
|
796
|
-
# get constraints again without common queryables
|
|
797
|
-
constraint_params = (
|
|
798
|
-
get_constraint_queryables_with_additional_params(
|
|
799
|
-
constraints, non_empty_kwargs, self, product_type
|
|
800
|
-
)
|
|
801
|
-
)
|
|
802
|
-
|
|
803
|
-
field_definitions: Dict[str, Any] = dict()
|
|
804
|
-
for json_param, json_mtd in constraint_params.items():
|
|
805
|
-
param = (
|
|
806
|
-
get_queryable_from_provider(
|
|
807
|
-
json_param, self.get_metadata_mapping(product_type)
|
|
808
|
-
)
|
|
809
|
-
or json_param
|
|
810
|
-
)
|
|
811
|
-
default = kwargs.get(param, None) or self.config.products.get(
|
|
812
|
-
product_type, {}
|
|
813
|
-
).get(param, None)
|
|
814
|
-
annotated_def = json_field_definition_to_python(
|
|
815
|
-
json_mtd, default_value=default, required=True
|
|
816
|
-
)
|
|
817
|
-
field_definitions[param] = get_args(annotated_def)
|
|
818
|
-
|
|
819
|
-
python_queryables = create_model("m", **field_definitions).model_fields
|
|
820
|
-
return dict(default_queryables, **model_fields_to_annotated(python_queryables))
|
|
821
|
-
|
|
822
725
|
def query(
|
|
823
726
|
self,
|
|
824
727
|
prep: PreparedSearch = PreparedSearch(),
|
|
@@ -1138,9 +1041,13 @@ class QueryStringSearch(Search):
|
|
|
1138
1041
|
logger.debug(
|
|
1139
1042
|
"Could not extract total_items_nb from search results"
|
|
1140
1043
|
)
|
|
1141
|
-
if
|
|
1044
|
+
if (
|
|
1045
|
+
getattr(self.config, "merge_responses", False)
|
|
1046
|
+
and self.config.result_type == "json"
|
|
1047
|
+
):
|
|
1048
|
+
json_result = cast(list[dict[str, Any]], result)
|
|
1142
1049
|
results = (
|
|
1143
|
-
[dict(r, **
|
|
1050
|
+
[dict(r, **json_result[i]) for i, r in enumerate(results)]
|
|
1144
1051
|
if results
|
|
1145
1052
|
else result
|
|
1146
1053
|
)
|
|
@@ -1524,54 +1431,53 @@ class PostJsonSearch(QueryStringSearch):
|
|
|
1524
1431
|
"""
|
|
1525
1432
|
|
|
1526
1433
|
def _get_default_end_date_from_start_date(
|
|
1527
|
-
self, start_datetime: str,
|
|
1434
|
+
self, start_datetime: str, product_type_conf: Dict[str, Any]
|
|
1528
1435
|
) -> str:
|
|
1529
|
-
default_end_date = self.config.products.get(product_type, {}).get(
|
|
1530
|
-
"_default_end_date", None
|
|
1531
|
-
)
|
|
1532
|
-
if default_end_date:
|
|
1533
|
-
return default_end_date
|
|
1534
1436
|
try:
|
|
1535
1437
|
start_date = datetime.fromisoformat(start_datetime)
|
|
1536
1438
|
except ValueError:
|
|
1537
1439
|
start_date = datetime.strptime(start_datetime, "%Y-%m-%dT%H:%M:%SZ")
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
):
|
|
1543
|
-
mapping = product_type_conf["metadata_mapping"][
|
|
1544
|
-
"startTimeFromAscendingNode"
|
|
1545
|
-
]
|
|
1440
|
+
if "completionTimeFromAscendingNode" in product_type_conf:
|
|
1441
|
+
mapping = product_type_conf["completionTimeFromAscendingNode"]
|
|
1442
|
+
# if date is mapped to year/month/(day), use end_date = start_date else start_date + 1 day
|
|
1443
|
+
# (default dates are only needed for ecmwf products where selected timespans should not be too large)
|
|
1546
1444
|
if isinstance(mapping, list) and "year" in mapping[0]:
|
|
1547
|
-
# if date is mapped to year/month/(day), use end_date = start_date to avoid large requests
|
|
1548
1445
|
end_date = start_date
|
|
1549
|
-
|
|
1446
|
+
else:
|
|
1447
|
+
end_date = start_date + timedelta(days=1)
|
|
1448
|
+
return end_date.isoformat()
|
|
1550
1449
|
return self.get_product_type_cfg_value("missionEndDate", today().isoformat())
|
|
1551
1450
|
|
|
1552
|
-
def _check_date_params(
|
|
1451
|
+
def _check_date_params(
|
|
1452
|
+
self, keywords: Dict[str, Any], product_type: Optional[str]
|
|
1453
|
+
) -> None:
|
|
1553
1454
|
"""checks if start and end date are present in the keywords and adds them if not"""
|
|
1554
1455
|
if (
|
|
1555
1456
|
"startTimeFromAscendingNode"
|
|
1556
1457
|
and "completionTimeFromAscendingNode" in keywords
|
|
1557
1458
|
):
|
|
1558
1459
|
return
|
|
1460
|
+
|
|
1461
|
+
product_type_conf = getattr(self.config, "metadata_mapping", {})
|
|
1462
|
+
if (
|
|
1463
|
+
product_type
|
|
1464
|
+
and product_type in self.config.products
|
|
1465
|
+
and "metadata_mapping" in self.config.products[product_type]
|
|
1466
|
+
):
|
|
1467
|
+
product_type_conf = self.config.products[product_type]["metadata_mapping"]
|
|
1559
1468
|
# start time given, end time missing
|
|
1560
1469
|
if "startTimeFromAscendingNode" in keywords:
|
|
1561
1470
|
keywords[
|
|
1562
1471
|
"completionTimeFromAscendingNode"
|
|
1563
1472
|
] = self._get_default_end_date_from_start_date(
|
|
1564
|
-
keywords["startTimeFromAscendingNode"],
|
|
1473
|
+
keywords["startTimeFromAscendingNode"], product_type_conf
|
|
1565
1474
|
)
|
|
1566
1475
|
return
|
|
1567
|
-
|
|
1568
|
-
if
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
mapping = product_type_conf["metadata_mapping"][
|
|
1573
|
-
"startTimeFromAscendingNode"
|
|
1574
|
-
]
|
|
1476
|
+
|
|
1477
|
+
if "completionTimeFromAscendingNode" in product_type_conf:
|
|
1478
|
+
mapping = product_type_conf["startTimeFromAscendingNode"]
|
|
1479
|
+
if not isinstance(mapping, list):
|
|
1480
|
+
mapping = product_type_conf["completionTimeFromAscendingNode"]
|
|
1575
1481
|
if isinstance(mapping, list):
|
|
1576
1482
|
# get time parameters (date, year, month, ...) from metadata mapping
|
|
1577
1483
|
input_mapping = mapping[0].replace("{{", "").replace("}}", "")
|
|
@@ -1587,16 +1493,17 @@ class PostJsonSearch(QueryStringSearch):
|
|
|
1587
1493
|
for tp in time_params:
|
|
1588
1494
|
if tp not in keywords:
|
|
1589
1495
|
in_keywords = False
|
|
1496
|
+
break
|
|
1590
1497
|
if not in_keywords:
|
|
1591
1498
|
keywords[
|
|
1592
1499
|
"startTimeFromAscendingNode"
|
|
1593
1500
|
] = self.get_product_type_cfg_value(
|
|
1594
|
-
"missionStartDate",
|
|
1501
|
+
"missionStartDate", DEFAULT_MISSION_START_DATE
|
|
1595
1502
|
)
|
|
1596
1503
|
keywords[
|
|
1597
1504
|
"completionTimeFromAscendingNode"
|
|
1598
1505
|
] = self._get_default_end_date_from_start_date(
|
|
1599
|
-
keywords["startTimeFromAscendingNode"],
|
|
1506
|
+
keywords["startTimeFromAscendingNode"], product_type_conf
|
|
1600
1507
|
)
|
|
1601
1508
|
|
|
1602
1509
|
def query(
|
|
@@ -1605,7 +1512,7 @@ class PostJsonSearch(QueryStringSearch):
|
|
|
1605
1512
|
**kwargs: Any,
|
|
1606
1513
|
) -> Tuple[List[EOProduct], Optional[int]]:
|
|
1607
1514
|
"""Perform a search on an OpenSearch-like interface"""
|
|
1608
|
-
product_type = kwargs.get("productType",
|
|
1515
|
+
product_type = kwargs.get("productType", "")
|
|
1609
1516
|
count = prep.count
|
|
1610
1517
|
# remove "product_type" from search args if exists for compatibility with QueryStringSearch methods
|
|
1611
1518
|
kwargs.pop("product_type", None)
|
|
@@ -1720,6 +1627,7 @@ class PostJsonSearch(QueryStringSearch):
|
|
|
1720
1627
|
# do not try to extract total_items from search results if count is False
|
|
1721
1628
|
del prep.total_items_nb
|
|
1722
1629
|
del prep.need_count
|
|
1630
|
+
|
|
1723
1631
|
provider_results = self.do_search(prep, **kwargs)
|
|
1724
1632
|
if count and total_items is None and hasattr(prep, "total_items_nb"):
|
|
1725
1633
|
total_items = prep.total_items_nb
|
|
@@ -2072,6 +1980,10 @@ class StacSearch(PostJsonSearch):
|
|
|
2072
1980
|
field_definitions[param] = get_args(annotated_def)
|
|
2073
1981
|
|
|
2074
1982
|
python_queryables = create_model("m", **field_definitions).model_fields
|
|
1983
|
+
# replace geometry by geom
|
|
1984
|
+
geom_queryable = python_queryables.pop("geometry", None)
|
|
1985
|
+
if geom_queryable:
|
|
1986
|
+
python_queryables["geom"] = geom_queryable
|
|
2075
1987
|
|
|
2076
1988
|
return model_fields_to_annotated(python_queryables)
|
|
2077
1989
|
|