eodag 3.10.1__py3-none-any.whl → 4.0.0a2__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/__init__.py +6 -1
- eodag/api/collection.py +353 -0
- eodag/api/core.py +606 -641
- eodag/api/product/__init__.py +3 -3
- eodag/api/product/_product.py +74 -56
- eodag/api/product/drivers/__init__.py +4 -46
- eodag/api/product/drivers/base.py +0 -28
- eodag/api/product/metadata_mapping.py +178 -216
- eodag/api/search_result.py +156 -15
- eodag/cli.py +83 -403
- eodag/config.py +81 -51
- eodag/plugins/apis/base.py +2 -2
- eodag/plugins/apis/ecmwf.py +36 -25
- eodag/plugins/apis/usgs.py +55 -40
- eodag/plugins/authentication/base.py +1 -3
- eodag/plugins/crunch/filter_date.py +3 -3
- eodag/plugins/crunch/filter_latest_intersect.py +2 -2
- eodag/plugins/crunch/filter_latest_tpl_name.py +1 -1
- eodag/plugins/download/aws.py +46 -42
- eodag/plugins/download/base.py +13 -14
- eodag/plugins/download/http.py +65 -65
- eodag/plugins/manager.py +28 -29
- eodag/plugins/search/__init__.py +6 -4
- eodag/plugins/search/base.py +131 -80
- eodag/plugins/search/build_search_result.py +245 -173
- eodag/plugins/search/cop_marine.py +87 -56
- eodag/plugins/search/csw.py +47 -37
- eodag/plugins/search/qssearch.py +653 -429
- eodag/plugins/search/stac_list_assets.py +1 -1
- eodag/plugins/search/static_stac_search.py +43 -44
- eodag/resources/{product_types.yml → collections.yml} +2594 -2453
- eodag/resources/ext_collections.json +1 -1
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/providers.yml +2706 -2733
- eodag/resources/stac_provider.yml +50 -92
- eodag/resources/user_conf_template.yml +9 -0
- eodag/types/__init__.py +2 -0
- eodag/types/queryables.py +70 -91
- eodag/types/search_args.py +1 -1
- eodag/utils/__init__.py +97 -21
- eodag/utils/dates.py +0 -12
- eodag/utils/exceptions.py +6 -6
- eodag/utils/free_text_search.py +3 -3
- eodag/utils/repr.py +2 -0
- {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/METADATA +13 -99
- eodag-4.0.0a2.dist-info/RECORD +93 -0
- {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/entry_points.txt +0 -4
- eodag/plugins/authentication/oauth.py +0 -60
- eodag/plugins/download/creodias_s3.py +0 -71
- eodag/plugins/download/s3rest.py +0 -351
- eodag/plugins/search/data_request_search.py +0 -565
- eodag/resources/stac.yml +0 -294
- eodag/resources/stac_api.yml +0 -2105
- eodag/rest/__init__.py +0 -24
- eodag/rest/cache.py +0 -70
- eodag/rest/config.py +0 -67
- eodag/rest/constants.py +0 -26
- eodag/rest/core.py +0 -764
- eodag/rest/errors.py +0 -210
- eodag/rest/server.py +0 -604
- eodag/rest/server.wsgi +0 -6
- eodag/rest/stac.py +0 -1032
- eodag/rest/templates/README +0 -1
- eodag/rest/types/__init__.py +0 -18
- eodag/rest/types/collections_search.py +0 -44
- eodag/rest/types/eodag_search.py +0 -386
- eodag/rest/types/queryables.py +0 -174
- eodag/rest/types/stac_search.py +0 -272
- eodag/rest/utils/__init__.py +0 -207
- eodag/rest/utils/cql_evaluate.py +0 -119
- eodag/rest/utils/rfc3339.py +0 -64
- eodag-3.10.1.dist-info/RECORD +0 -116
- {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/WHEEL +0 -0
- {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/licenses/LICENSE +0 -0
- {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/top_level.txt +0 -0
eodag/config.py
CHANGED
|
@@ -38,7 +38,6 @@ from typing import (
|
|
|
38
38
|
import orjson
|
|
39
39
|
import requests
|
|
40
40
|
import yaml
|
|
41
|
-
import yaml.constructor
|
|
42
41
|
import yaml.parser
|
|
43
42
|
from annotated_types import Gt
|
|
44
43
|
from jsonpath_ng import JSONPath
|
|
@@ -64,8 +63,8 @@ from eodag.utils.exceptions import ValidationError
|
|
|
64
63
|
|
|
65
64
|
logger = logging.getLogger("eodag.config")
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
"https://cs-si.github.io/eodag/eodag/resources/
|
|
66
|
+
EXT_COLLECTIONS_CONF_URI = (
|
|
67
|
+
"https://cs-si.github.io/eodag/eodag/resources/ext_collections.json"
|
|
69
68
|
)
|
|
70
69
|
AUTH_TOPIC_KEYS = ("auth", "search_auth", "download_auth")
|
|
71
70
|
PLUGINS_TOPICS_KEYS = ("api", "search", "download") + AUTH_TOPIC_KEYS
|
|
@@ -114,7 +113,7 @@ class ProviderConfig(yaml.YAMLObject):
|
|
|
114
113
|
Lower value means lower priority. (Default: 0)
|
|
115
114
|
:param api: (optional) The configuration of a plugin of type Api
|
|
116
115
|
:param search: (optional) The configuration of a plugin of type Search
|
|
117
|
-
:param products: (optional) The
|
|
116
|
+
:param products: (optional) The collections supported by the provider
|
|
118
117
|
:param download: (optional) The configuration of a plugin of type Download
|
|
119
118
|
:param auth: (optional) The configuration of a plugin of type Authentication
|
|
120
119
|
:param search_auth: (optional) The configuration of a plugin of type Authentication for search
|
|
@@ -135,7 +134,7 @@ class ProviderConfig(yaml.YAMLObject):
|
|
|
135
134
|
auth: PluginConfig
|
|
136
135
|
search_auth: PluginConfig
|
|
137
136
|
download_auth: PluginConfig
|
|
138
|
-
|
|
137
|
+
collections_fetched: bool # set in core.update_collections_list
|
|
139
138
|
|
|
140
139
|
yaml_loader = yaml.Loader
|
|
141
140
|
yaml_dumper = yaml.SafeDumper
|
|
@@ -241,10 +240,15 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
241
240
|
next_page_url_tpl: str
|
|
242
241
|
#: The query-object for POST pagination requests.
|
|
243
242
|
next_page_query_obj: str
|
|
243
|
+
#: Next page token key used in pagination. Can be guessed from ``KNOWN_NEXT_PAGE_TOKEN_KEYS`` (but needed by
|
|
244
|
+
# ``stac-fastapi-eodag`` that cannot guess and will use ``page`` as default).
|
|
245
|
+
next_page_token_key: str
|
|
244
246
|
#: The endpoint for counting the number of items satisfying a request
|
|
245
247
|
count_endpoint: str
|
|
246
248
|
#: Index of the starting page
|
|
247
249
|
start_page: int
|
|
250
|
+
#: Key in the current page URL for the next page URL
|
|
251
|
+
parse_url_key: str
|
|
248
252
|
|
|
249
253
|
class Sort(TypedDict):
|
|
250
254
|
"""Configuration for sort during search"""
|
|
@@ -274,17 +278,19 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
274
278
|
metadata_path: str
|
|
275
279
|
#: list search parameters to send as is to the provider
|
|
276
280
|
search_param_unparsed: list[str]
|
|
281
|
+
#: Use as STAC extension prefix if it does not have one already
|
|
282
|
+
metadata_prefix: str
|
|
277
283
|
#: Whether an error must be raised when using a search parameter which is not queryable or not
|
|
278
284
|
raise_mtd_discovery_error: bool
|
|
279
285
|
|
|
280
|
-
class
|
|
281
|
-
"""Configuration for
|
|
286
|
+
class DiscoverCollections(TypedDict, total=False):
|
|
287
|
+
"""Configuration for collections discovery"""
|
|
282
288
|
|
|
283
|
-
#: URL from which the
|
|
289
|
+
#: URL from which the collections can be fetched
|
|
284
290
|
fetch_url: Optional[str]
|
|
285
|
-
#: HTTP method used to fetch
|
|
291
|
+
#: HTTP method used to fetch collections
|
|
286
292
|
fetch_method: str
|
|
287
|
-
#: Request body to fetch
|
|
293
|
+
#: Request body to fetch collections using POST method
|
|
288
294
|
fetch_body: dict[str, Any]
|
|
289
295
|
#: Maximum number of connections for concurrent HTTP requests
|
|
290
296
|
max_connections: int
|
|
@@ -294,32 +300,32 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
294
300
|
start_page: int
|
|
295
301
|
#: Type of the provider result
|
|
296
302
|
result_type: str
|
|
297
|
-
#: JsonPath to the list of
|
|
303
|
+
#: JsonPath to the list of collections
|
|
298
304
|
results_entry: Union[JSONPath, str]
|
|
299
|
-
#: Mapping for the
|
|
300
|
-
|
|
301
|
-
#: Mapping for
|
|
305
|
+
#: Mapping for the collection id
|
|
306
|
+
generic_collection_id: str
|
|
307
|
+
#: Mapping for collection metadata (e.g. ``description``, ``license``) which can be parsed from the provider
|
|
302
308
|
#: result
|
|
303
|
-
|
|
304
|
-
#: Mapping for
|
|
305
|
-
|
|
306
|
-
#: Mapping for
|
|
307
|
-
|
|
309
|
+
generic_collection_parsable_metadata: dict[str, str]
|
|
310
|
+
#: Mapping for collection properties which can be parsed from the result and are not collection metadata
|
|
311
|
+
generic_collection_parsable_properties: dict[str, str]
|
|
312
|
+
#: Mapping for collection properties which cannot be parsed from the result and are not collection metadata
|
|
313
|
+
generic_collection_unparsable_properties: dict[str, str]
|
|
308
314
|
#: URL to fetch data for a single collection
|
|
309
315
|
single_collection_fetch_url: str
|
|
310
316
|
#: Query string to be added to the fetch_url to filter for a collection
|
|
311
317
|
single_collection_fetch_qs: str
|
|
312
|
-
#: Mapping for
|
|
313
|
-
#: is redefined in this mapping, it will replace ``
|
|
314
|
-
|
|
318
|
+
#: Mapping for collection metadata returned by the endpoint given in single_collection_fetch_url. If ``id``
|
|
319
|
+
#: is redefined in this mapping, it will replace ``generic_collection_id`` value
|
|
320
|
+
single_collection_parsable_metadata: dict[str, str]
|
|
315
321
|
|
|
316
322
|
class DiscoverQueryables(TypedDict, total=False):
|
|
317
323
|
"""Configuration for queryables discovery"""
|
|
318
324
|
|
|
319
|
-
#: URL to fetch the queryables valid for all
|
|
325
|
+
#: URL to fetch the queryables valid for all collections
|
|
320
326
|
fetch_url: Optional[str]
|
|
321
|
-
#: URL to fetch the queryables for a specific
|
|
322
|
-
|
|
327
|
+
#: URL to fetch the queryables for a specific collection
|
|
328
|
+
collection_fetch_url: Optional[str]
|
|
323
329
|
#: Type of the result
|
|
324
330
|
result_type: str
|
|
325
331
|
#: JsonPath to retrieve the queryables from the provider result
|
|
@@ -329,6 +335,30 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
329
335
|
#: :class:`~eodag.plugins.search.base.Search` Key in the json result where the constraints can be found
|
|
330
336
|
constraints_entry: str
|
|
331
337
|
|
|
338
|
+
class CollectionSelector(TypedDict, total=False):
|
|
339
|
+
"""Define the criteria to select a collection in :class:`~eodag.config.PluginConfig.DynamicDiscoverQueryables`.
|
|
340
|
+
|
|
341
|
+
The selector matches if the field value starts with the given prefix,
|
|
342
|
+
i.e. it matches if ``parameters[field].startswith(prefix)==True``"""
|
|
343
|
+
|
|
344
|
+
#: Field in the search parameters to match
|
|
345
|
+
field: str
|
|
346
|
+
#: Prefix to match in the field
|
|
347
|
+
prefix: str
|
|
348
|
+
|
|
349
|
+
class DynamicDiscoverQueryables(TypedDict, total=False):
|
|
350
|
+
"""Configuration for queryables dynamic discovery.
|
|
351
|
+
|
|
352
|
+
The given configuration for queryables discovery is used if any collection selector
|
|
353
|
+
matches the search parameters.
|
|
354
|
+
"""
|
|
355
|
+
|
|
356
|
+
#: List of collection selection criterias
|
|
357
|
+
collection_selector: list[PluginConfig.CollectionSelector]
|
|
358
|
+
|
|
359
|
+
#: Configuration for queryables discovery to use
|
|
360
|
+
discover_queryables: PluginConfig.DiscoverQueryables
|
|
361
|
+
|
|
332
362
|
class OrderOnResponse(TypedDict):
|
|
333
363
|
"""Configuration for order on-response during download"""
|
|
334
364
|
|
|
@@ -431,8 +461,8 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
431
461
|
# search & api -----------------------------------------------------------------------------------------------------
|
|
432
462
|
# copied from ProviderConfig in PluginManager.get_search_plugins()
|
|
433
463
|
priority: int
|
|
434
|
-
# per
|
|
435
|
-
|
|
464
|
+
# per collection metadata-mapping, set in core._prepare_search
|
|
465
|
+
collection_config: dict[str, Any]
|
|
436
466
|
|
|
437
467
|
#: :class:`~eodag.plugins.search.base.Search` Plugin API endpoint
|
|
438
468
|
api_endpoint: str
|
|
@@ -449,14 +479,14 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
449
479
|
sort: PluginConfig.Sort
|
|
450
480
|
#: :class:`~eodag.plugins.search.base.Search` Configuration for the metadata auto-discovery
|
|
451
481
|
discover_metadata: PluginConfig.DiscoverMetadata
|
|
452
|
-
#: :class:`~eodag.plugins.search.base.Search` Configuration for the
|
|
453
|
-
|
|
482
|
+
#: :class:`~eodag.plugins.search.base.Search` Configuration for the collections auto-discovery
|
|
483
|
+
discover_collections: PluginConfig.DiscoverCollections
|
|
454
484
|
#: :class:`~eodag.plugins.search.base.Search` Configuration for the queryables auto-discovery
|
|
455
485
|
discover_queryables: PluginConfig.DiscoverQueryables
|
|
456
486
|
#: :class:`~eodag.plugins.search.base.Search` The mapping between eodag metadata and the plugin specific metadata
|
|
457
487
|
metadata_mapping: dict[str, Union[str, list[str]]]
|
|
458
488
|
#: :class:`~eodag.plugins.search.base.Search` :attr:`~eodag.config.PluginConfig.metadata_mapping` got from the given
|
|
459
|
-
#:
|
|
489
|
+
#: collection
|
|
460
490
|
metadata_mapping_from_product: str
|
|
461
491
|
#: :class:`~eodag.plugins.search.base.Search` A mapping for the metadata of individual assets
|
|
462
492
|
assets_mapping: dict[str, dict[str, Any]]
|
|
@@ -476,26 +506,19 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
476
506
|
per_product_metadata_query: bool
|
|
477
507
|
#: :class:`~eodag.plugins.search.qssearch.ODataV4Search` Dict used to simplify further metadata extraction
|
|
478
508
|
metadata_pre_mapping: PluginConfig.MetadataPreMapping
|
|
479
|
-
#: :class:`~eodag.plugins.search.data_request_search.DataRequestSearch` URL to which the data request shall be sent
|
|
480
|
-
data_request_url: str
|
|
481
|
-
#: :class:`~eodag.plugins.search.data_request_search.DataRequestSearch` URL to fetch the status of the data request
|
|
482
|
-
status_url: str
|
|
483
|
-
#: :class:`~eodag.plugins.search.data_request_search.DataRequestSearch`
|
|
484
|
-
#: URL to fetch the search result when the data request is done
|
|
485
|
-
result_url: str
|
|
486
|
-
#: :class:`~eodag.plugins.search.data_request_search.DataRequestSearch`
|
|
487
|
-
#: if date parameters are mandatory in the request
|
|
488
|
-
dates_required: bool
|
|
489
509
|
#: :class:`~eodag.plugins.search.csw.CSWSearch` Search definition dictionary
|
|
490
510
|
search_definition: dict[str, Any]
|
|
491
511
|
#: :class:`~eodag.plugins.search.qssearch.PostJsonSearch` Whether to merge responses or not (`aws_eos` specific)
|
|
492
512
|
merge_responses: bool
|
|
493
513
|
#: :class:`~eodag.plugins.search.qssearch.PostJsonSearch` Collections names (`aws_eos` specific)
|
|
494
|
-
|
|
514
|
+
_collection: list[str]
|
|
495
515
|
#: :class:`~eodag.plugins.search.static_stac_search.StaticStacSearch`
|
|
496
516
|
#: Maximum number of connections for concurrent HTTP requests
|
|
497
517
|
max_connections: int
|
|
498
518
|
#: :class:`~eodag.plugins.search.build_search_result.ECMWFSearch`
|
|
519
|
+
#: if date parameters are mandatory in the request
|
|
520
|
+
dates_required: bool
|
|
521
|
+
#: :class:`~eodag.plugins.search.build_search_result.ECMWFSearch`
|
|
499
522
|
#: Whether end date should be excluded from search request or not
|
|
500
523
|
end_date_excluded: bool
|
|
501
524
|
#: :class:`~eodag.plugins.search.build_search_result.ECMWFSearch`
|
|
@@ -506,6 +529,12 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
506
529
|
version: str
|
|
507
530
|
#: :class:`~eodag.plugins.apis.ecmwf.EcmwfApi` url of the authentication endpoint
|
|
508
531
|
auth_endpoint: str
|
|
532
|
+
#: :class:`~eodag.plugins.search.build_search_result.WekeoECMWFSearch`
|
|
533
|
+
#: Configurations for the queryables dynamic auto-discovery.
|
|
534
|
+
#: A configuration is used based on the given selection criterias. The first match is used.
|
|
535
|
+
#: If no match is found, it falls back to standard behaviors (e.g. discovery using
|
|
536
|
+
#: :attr:`~eodag.config.PluginConfig.discover_queryables`).
|
|
537
|
+
dynamic_discover_queryables: list[PluginConfig.DynamicDiscoverQueryables]
|
|
509
538
|
|
|
510
539
|
# download ---------------------------------------------------------------------------------------------------------
|
|
511
540
|
#: :class:`~eodag.plugins.download.base.Download` Default endpoint url
|
|
@@ -521,9 +550,10 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
521
550
|
flatten_top_dirs: bool
|
|
522
551
|
#: :class:`~eodag.plugins.download.base.Download` Level in extracted path tree where to find data
|
|
523
552
|
archive_depth: int
|
|
524
|
-
#: :class:`~eodag.plugins.download.base.Download` Whether ignore assets and download using ``
|
|
553
|
+
#: :class:`~eodag.plugins.download.base.Download` Whether ignore assets and download using ``eodag:download_link``
|
|
554
|
+
#: or not
|
|
525
555
|
ignore_assets: bool
|
|
526
|
-
#: :class:`~eodag.plugins.download.base.Download`
|
|
556
|
+
#: :class:`~eodag.plugins.download.base.Download` Collection specific configuration
|
|
527
557
|
products: dict[str, dict[str, Any]]
|
|
528
558
|
#: :class:`~eodag.plugins.download.http.HTTPDownload` Whether the product has to be ordered to download it or not
|
|
529
559
|
order_enabled: bool
|
|
@@ -542,7 +572,7 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
542
572
|
no_auth_download: bool
|
|
543
573
|
#: :class:`~eodag.plugins.download.http.HTTPDownload` Parameters to be added to the query params of the request
|
|
544
574
|
dl_url_params: dict[str, str]
|
|
545
|
-
#: :class:`~eodag.plugins.download.
|
|
575
|
+
#: :class:`~eodag.plugins.download.aws.AwsDownload`
|
|
546
576
|
#: At which level of the path part of the url the bucket can be found
|
|
547
577
|
bucket_path_level: int
|
|
548
578
|
#: :class:`~eodag.plugins.download.aws.AwsDownload` S3 endpoint
|
|
@@ -1069,15 +1099,15 @@ def load_stac_provider_config() -> dict[str, Any]:
|
|
|
1069
1099
|
).source
|
|
1070
1100
|
|
|
1071
1101
|
|
|
1072
|
-
def
|
|
1073
|
-
conf_uri: str =
|
|
1102
|
+
def get_ext_collections_conf(
|
|
1103
|
+
conf_uri: str = EXT_COLLECTIONS_CONF_URI,
|
|
1074
1104
|
) -> dict[str, Any]:
|
|
1075
|
-
"""Read external
|
|
1105
|
+
"""Read external collections conf
|
|
1076
1106
|
|
|
1077
1107
|
:param conf_uri: URI to local or remote configuration file
|
|
1078
|
-
:returns: The external
|
|
1108
|
+
:returns: The external collections configuration
|
|
1079
1109
|
"""
|
|
1080
|
-
logger.info("Fetching external
|
|
1110
|
+
logger.info("Fetching external collections from %s", conf_uri)
|
|
1081
1111
|
if conf_uri.lower().startswith("http"):
|
|
1082
1112
|
# read from remote
|
|
1083
1113
|
try:
|
|
@@ -1089,7 +1119,7 @@ def get_ext_product_types_conf(
|
|
|
1089
1119
|
except requests.RequestException as e:
|
|
1090
1120
|
logger.debug(e)
|
|
1091
1121
|
logger.warning(
|
|
1092
|
-
"Could not read remote external
|
|
1122
|
+
"Could not read remote external collections conf from %s", conf_uri
|
|
1093
1123
|
)
|
|
1094
1124
|
return {}
|
|
1095
1125
|
elif conf_uri.lower().startswith("file"):
|
|
@@ -1102,6 +1132,6 @@ def get_ext_product_types_conf(
|
|
|
1102
1132
|
except (orjson.JSONDecodeError, FileNotFoundError) as e:
|
|
1103
1133
|
logger.debug(e)
|
|
1104
1134
|
logger.warning(
|
|
1105
|
-
"Could not read local external
|
|
1135
|
+
"Could not read local external collections conf from %s", conf_uri
|
|
1106
1136
|
)
|
|
1107
1137
|
return {}
|
eodag/plugins/apis/base.py
CHANGED
|
@@ -45,8 +45,8 @@ class Api(Search, Download):
|
|
|
45
45
|
(e.g. 'file:///tmp/product_folder' on Linux or
|
|
46
46
|
'file:///C:/Users/username/AppData/Local/Temp' on Windows)
|
|
47
47
|
- save a *record* file in the directory ``output_dir/.downloaded`` whose name
|
|
48
|
-
is built on the MD5 hash of the product's ``
|
|
49
|
-
attributes (``hashlib.md5((product.
|
|
48
|
+
is built on the MD5 hash of the product's ``collection`` and ``properties['id']``
|
|
49
|
+
attributes (``hashlib.md5((product.collection+"-"+product.properties['id']).encode("utf-8")).hexdigest()``)
|
|
50
50
|
and whose content is the product's ``remote_location`` attribute itself.
|
|
51
51
|
- not try to download a product whose ``location`` attribute already points to an
|
|
52
52
|
existing file/directory
|
eodag/plugins/apis/ecmwf.py
CHANGED
|
@@ -27,6 +27,7 @@ from ecmwfapi import ECMWFDataServer, ECMWFService
|
|
|
27
27
|
from ecmwfapi.api import APIException, Connection, get_apikey_values
|
|
28
28
|
from pydantic.fields import FieldInfo
|
|
29
29
|
|
|
30
|
+
from eodag.api.search_result import RawSearchResult
|
|
30
31
|
from eodag.plugins.apis.base import Api
|
|
31
32
|
from eodag.plugins.search import PreparedSearch
|
|
32
33
|
from eodag.plugins.search.base import Search
|
|
@@ -35,6 +36,7 @@ from eodag.utils import (
|
|
|
35
36
|
DEFAULT_DOWNLOAD_TIMEOUT,
|
|
36
37
|
DEFAULT_DOWNLOAD_WAIT,
|
|
37
38
|
DEFAULT_MISSION_START_DATE,
|
|
39
|
+
get_collection_dates,
|
|
38
40
|
get_geometry_from_various,
|
|
39
41
|
path_to_uri,
|
|
40
42
|
sanitize,
|
|
@@ -52,7 +54,6 @@ if TYPE_CHECKING:
|
|
|
52
54
|
from eodag.api.product import EOProduct
|
|
53
55
|
from eodag.api.search_result import SearchResult
|
|
54
56
|
from eodag.config import PluginConfig
|
|
55
|
-
from eodag.types import S3SessionKwargs
|
|
56
57
|
from eodag.types.download_args import DownloadConf
|
|
57
58
|
from eodag.utils import DownloadedCallback, ProgressCallback, Unpack
|
|
58
59
|
|
|
@@ -103,36 +104,45 @@ class EcmwfApi(Api, ECMWFSearch):
|
|
|
103
104
|
self.config.__dict__.setdefault("pagination", {"next_page_query_obj": "{{}}"})
|
|
104
105
|
self.config.__dict__.setdefault("api_endpoint", "")
|
|
105
106
|
|
|
106
|
-
def do_search(
|
|
107
|
+
def do_search(
|
|
108
|
+
self, prep: PreparedSearch = PreparedSearch(items_per_page=None), **kwargs: Any
|
|
109
|
+
) -> RawSearchResult:
|
|
107
110
|
"""Should perform the actual search request."""
|
|
108
|
-
|
|
111
|
+
raw_search_results = RawSearchResult([{}])
|
|
112
|
+
raw_search_results.search_params = kwargs
|
|
113
|
+
raw_search_results.query_params = (
|
|
114
|
+
prep.query_params if hasattr(prep, "query_params") else {}
|
|
115
|
+
)
|
|
116
|
+
raw_search_results.collection_def_params = (
|
|
117
|
+
prep.collection_def_params if hasattr(prep, "collection_def_params") else {}
|
|
118
|
+
)
|
|
119
|
+
return raw_search_results
|
|
109
120
|
|
|
110
121
|
def query(
|
|
111
122
|
self,
|
|
112
123
|
prep: PreparedSearch = PreparedSearch(),
|
|
113
124
|
**kwargs: Any,
|
|
114
|
-
) ->
|
|
125
|
+
) -> SearchResult:
|
|
115
126
|
"""Build ready-to-download SearchResult"""
|
|
116
127
|
|
|
117
|
-
# check
|
|
118
|
-
#
|
|
119
|
-
if not kwargs.get("
|
|
120
|
-
kwargs["
|
|
128
|
+
# check collection, dates, geometry, use defaults if not specified
|
|
129
|
+
# collection
|
|
130
|
+
if not kwargs.get("collection"):
|
|
131
|
+
kwargs["collection"] = "%s_%s_%s" % (
|
|
121
132
|
kwargs.get("ecmwf:dataset", "mars"),
|
|
122
133
|
kwargs.get("ecmwf:type", ""),
|
|
123
134
|
kwargs.get("ecmwf:levtype", ""),
|
|
124
135
|
)
|
|
136
|
+
|
|
137
|
+
col_start, col_end = get_collection_dates(
|
|
138
|
+
getattr(self.config, "collection_config", {})
|
|
139
|
+
)
|
|
125
140
|
# start date
|
|
126
|
-
if "
|
|
127
|
-
kwargs["
|
|
128
|
-
getattr(self.config, "product_type_config", {}).get("missionStartDate")
|
|
129
|
-
or DEFAULT_MISSION_START_DATE
|
|
130
|
-
)
|
|
141
|
+
if "start_datetime" not in kwargs:
|
|
142
|
+
kwargs["start_datetime"] = col_start or DEFAULT_MISSION_START_DATE
|
|
131
143
|
# end date
|
|
132
|
-
if "
|
|
133
|
-
kwargs["
|
|
134
|
-
self.config, "product_type_config", {}
|
|
135
|
-
).get("missionEndDate") or datetime.now(timezone.utc).isoformat(
|
|
144
|
+
if "end_datetime" not in kwargs:
|
|
145
|
+
kwargs["end_datetime"] = col_end or datetime.now(timezone.utc).isoformat(
|
|
136
146
|
timespec="seconds"
|
|
137
147
|
)
|
|
138
148
|
|
|
@@ -173,7 +183,7 @@ class EcmwfApi(Api, ECMWFSearch):
|
|
|
173
183
|
def download(
|
|
174
184
|
self,
|
|
175
185
|
product: EOProduct,
|
|
176
|
-
auth: Optional[Union[AuthBase,
|
|
186
|
+
auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
|
|
177
187
|
progress_callback: Optional[ProgressCallback] = None,
|
|
178
188
|
wait: float = DEFAULT_DOWNLOAD_WAIT,
|
|
179
189
|
timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
|
|
@@ -205,7 +215,7 @@ class EcmwfApi(Api, ECMWFSearch):
|
|
|
205
215
|
os.makedirs(new_fs_path)
|
|
206
216
|
fs_path = os.path.join(new_fs_path, os.path.basename(fs_path))
|
|
207
217
|
|
|
208
|
-
# get download request dict from product.location/
|
|
218
|
+
# get download request dict from product.location/eodag:download_link url query string
|
|
209
219
|
# separate url & parameters
|
|
210
220
|
download_request = geojson.loads(urlsplit(product.location).query)
|
|
211
221
|
|
|
@@ -245,7 +255,7 @@ class EcmwfApi(Api, ECMWFSearch):
|
|
|
245
255
|
raise DownloadError(e)
|
|
246
256
|
|
|
247
257
|
with open(record_filename, "w") as fh:
|
|
248
|
-
fh.write(product.properties["
|
|
258
|
+
fh.write(product.properties["eodag:download_link"])
|
|
249
259
|
logger.debug("Download recorded in %s", record_filename)
|
|
250
260
|
|
|
251
261
|
# do not try to extract a directory
|
|
@@ -262,7 +272,7 @@ class EcmwfApi(Api, ECMWFSearch):
|
|
|
262
272
|
def download_all(
|
|
263
273
|
self,
|
|
264
274
|
products: SearchResult,
|
|
265
|
-
auth: Optional[Union[AuthBase,
|
|
275
|
+
auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
|
|
266
276
|
downloaded_callback: Optional[DownloadedCallback] = None,
|
|
267
277
|
progress_callback: Optional[ProgressCallback] = None,
|
|
268
278
|
wait: float = DEFAULT_DOWNLOAD_WAIT,
|
|
@@ -287,13 +297,14 @@ class EcmwfApi(Api, ECMWFSearch):
|
|
|
287
297
|
pass
|
|
288
298
|
|
|
289
299
|
def discover_queryables(
|
|
290
|
-
self,
|
|
300
|
+
self,
|
|
301
|
+
**kwargs: Any,
|
|
291
302
|
) -> Optional[dict[str, Annotated[Any, FieldInfo]]]:
|
|
292
303
|
"""Fetch queryables list from provider using metadata mapping
|
|
293
304
|
|
|
294
|
-
:param kwargs: additional filters for queryables (`
|
|
305
|
+
:param kwargs: additional filters for queryables (`collection` and other search
|
|
295
306
|
arguments)
|
|
296
307
|
:returns: fetched queryable parameters dict
|
|
297
308
|
"""
|
|
298
|
-
|
|
299
|
-
return self.queryables_from_metadata_mapping(
|
|
309
|
+
collection = kwargs.get("collection")
|
|
310
|
+
return self.queryables_from_metadata_mapping(collection)
|