eodag 3.8.1__py3-none-any.whl → 3.9.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 +1 -1
- eodag/api/product/drivers/generic.py +5 -1
- eodag/api/product/metadata_mapping.py +132 -35
- eodag/cli.py +36 -4
- eodag/config.py +5 -2
- eodag/plugins/apis/ecmwf.py +3 -1
- eodag/plugins/apis/usgs.py +2 -1
- eodag/plugins/authentication/aws_auth.py +235 -37
- eodag/plugins/authentication/base.py +12 -2
- eodag/plugins/authentication/oauth.py +5 -0
- eodag/plugins/base.py +3 -2
- eodag/plugins/download/aws.py +44 -285
- eodag/plugins/download/base.py +3 -2
- eodag/plugins/download/creodias_s3.py +1 -38
- eodag/plugins/download/http.py +111 -103
- eodag/plugins/download/s3rest.py +3 -1
- eodag/plugins/manager.py +2 -1
- eodag/plugins/search/__init__.py +2 -1
- eodag/plugins/search/base.py +2 -1
- eodag/plugins/search/build_search_result.py +2 -2
- eodag/plugins/search/creodias_s3.py +9 -1
- eodag/plugins/search/qssearch.py +3 -1
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +220 -30
- eodag/resources/providers.yml +633 -88
- eodag/resources/stac_provider.yml +5 -2
- eodag/resources/user_conf_template.yml +0 -5
- eodag/rest/core.py +8 -0
- eodag/rest/errors.py +9 -0
- eodag/rest/server.py +8 -0
- eodag/rest/stac.py +8 -0
- eodag/rest/utils/__init__.py +2 -4
- eodag/rest/utils/rfc3339.py +1 -1
- eodag/utils/__init__.py +69 -54
- eodag/utils/dates.py +204 -0
- eodag/utils/s3.py +187 -168
- {eodag-3.8.1.dist-info → eodag-3.9.1.dist-info}/METADATA +4 -3
- {eodag-3.8.1.dist-info → eodag-3.9.1.dist-info}/RECORD +42 -42
- {eodag-3.8.1.dist-info → eodag-3.9.1.dist-info}/entry_points.txt +1 -1
- eodag/utils/rest.py +0 -100
- {eodag-3.8.1.dist-info → eodag-3.9.1.dist-info}/WHEEL +0 -0
- {eodag-3.8.1.dist-info → eodag-3.9.1.dist-info}/licenses/LICENSE +0 -0
- {eodag-3.8.1.dist-info → eodag-3.9.1.dist-info}/top_level.txt +0 -0
eodag/api/core.py
CHANGED
|
@@ -74,6 +74,7 @@ from eodag.utils import (
|
|
|
74
74
|
string_to_jsonpath,
|
|
75
75
|
uri_to_path,
|
|
76
76
|
)
|
|
77
|
+
from eodag.utils.dates import rfc3339_str_to_datetime
|
|
77
78
|
from eodag.utils.env import is_env_var_true
|
|
78
79
|
from eodag.utils.exceptions import (
|
|
79
80
|
AuthenticationError,
|
|
@@ -84,7 +85,6 @@ from eodag.utils.exceptions import (
|
|
|
84
85
|
UnsupportedProvider,
|
|
85
86
|
)
|
|
86
87
|
from eodag.utils.free_text_search import compile_free_text_query
|
|
87
|
-
from eodag.utils.rest import rfc3339_str_to_datetime
|
|
88
88
|
from eodag.utils.stac_reader import fetch_stac_items
|
|
89
89
|
|
|
90
90
|
if TYPE_CHECKING:
|
|
@@ -33,7 +33,11 @@ class GenericDriver(DatasetDriver):
|
|
|
33
33
|
# data
|
|
34
34
|
{
|
|
35
35
|
"pattern": re.compile(
|
|
36
|
-
|
|
36
|
+
(
|
|
37
|
+
r"^(?:.*[/\\])?([^/\\]+)"
|
|
38
|
+
r"(\.jp2|\.tiff?|\.dat|\.nc|\.grib2?|"
|
|
39
|
+
r"\.zarr|\.nat|\.covjson|\.parquet|\.zip|\.tar|\.gz)$"
|
|
40
|
+
),
|
|
37
41
|
re.IGNORECASE,
|
|
38
42
|
),
|
|
39
43
|
"roles": ["data"],
|
|
@@ -47,7 +47,6 @@ from eodag.utils import (
|
|
|
47
47
|
dict_items_recursive_apply,
|
|
48
48
|
format_string,
|
|
49
49
|
get_geometry_from_various,
|
|
50
|
-
get_timestamp,
|
|
51
50
|
items_recursive_apply,
|
|
52
51
|
nested_pairs2dict,
|
|
53
52
|
remove_str_array_quotes,
|
|
@@ -55,6 +54,7 @@ from eodag.utils import (
|
|
|
55
54
|
string_to_jsonpath,
|
|
56
55
|
update_nested_dict,
|
|
57
56
|
)
|
|
57
|
+
from eodag.utils.dates import get_timestamp
|
|
58
58
|
from eodag.utils.exceptions import ValidationError
|
|
59
59
|
|
|
60
60
|
if TYPE_CHECKING:
|
|
@@ -149,39 +149,38 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
149
149
|
"""Format a string of form ``{<field_name>#<conversion_function>}``
|
|
150
150
|
|
|
151
151
|
The currently understood converters are:
|
|
152
|
-
- ``
|
|
153
|
-
|
|
154
|
-
- ``
|
|
155
|
-
- ``
|
|
156
|
-
- ``
|
|
157
|
-
- ``
|
|
158
|
-
- ``to_geojson``: convert to a GeoJSON (via __geo_interface__ if exists)
|
|
152
|
+
- ``ceda_collection_name``: generate a CEDA collection name from a string
|
|
153
|
+
- ``csv_list``: convert to a comma separated list
|
|
154
|
+
- ``datetime_to_timestamp_milliseconds``: converts a utc date string to a timestamp in milliseconds
|
|
155
|
+
- ``dict_filter_and_sub``: filter dict items using jsonpath and then apply recursive_sub_str
|
|
156
|
+
- ``fake_l2a_title_from_l1c``: used to generate SAFE format metadata for data from AWS
|
|
157
|
+
- ``from_alternate``: update assets using given alternate
|
|
159
158
|
- ``from_ewkt``: convert EWKT to shapely geometry / WKT in DEFAULT_PROJ
|
|
160
|
-
- ``to_ewkt``: convert to EWKT (Extended Well-Known text)
|
|
161
159
|
- ``from_georss``: convert GeoRSS to shapely geometry / WKT in DEFAULT_PROJ
|
|
162
|
-
- ``
|
|
163
|
-
- ``to_iso_utc_datetime_from_milliseconds``: convert a utc timestamp in given
|
|
164
|
-
milliseconds to a utc iso datetime
|
|
165
|
-
- ``to_iso_utc_datetime``: convert a UTC datetime string to ISO UTC datetime
|
|
166
|
-
string
|
|
167
|
-
- ``to_iso_date``: remove the time part of a iso datetime string
|
|
168
|
-
- ``remove_extension``: on a string that contains dots, only take the first
|
|
169
|
-
part of the list obtained by splitting the string on dots
|
|
160
|
+
- ``get_ecmwf_time``: get the time of a datetime string in the ECMWF format
|
|
170
161
|
- ``get_group_name``: get the matching regex group name
|
|
162
|
+
- ``recursive_sub_str``: recursively substitue in the structure (e.g. dict) values matching a regex
|
|
163
|
+
- ``remove_extension``: on a string that contains dots, only take the first part of the list obtained by
|
|
164
|
+
splitting the string on dots
|
|
171
165
|
- ``replace_str``: execute "string".replace(old, new)
|
|
172
|
-
- ``recursive_sub_str``: recursively substitue in the structure (e.g. dict)
|
|
173
|
-
values matching a regex
|
|
174
|
-
- ``slice_str``: slice a string (equivalent to s[start, end, step])
|
|
175
|
-
- ``to_lower``: Convert a string to lowercase
|
|
176
|
-
- ``to_upper``: Convert a string to uppercase
|
|
177
|
-
- ``fake_l2a_title_from_l1c``: used to generate SAFE format metadata for data from AWS
|
|
178
166
|
- ``s2msil2a_title_to_aws_productinfo``: used to generate SAFE format metadata for data from AWS
|
|
167
|
+
- ``sanitize``: sanitize string
|
|
168
|
+
- ``slice_str``: slice a string (equivalent to s[start, end, step])
|
|
179
169
|
- ``split_cop_dem_id``: get the bbox by splitting the product id
|
|
180
170
|
- ``split_corine_id``: get the product type by splitting the product id
|
|
171
|
+
- ``to_bounds_lists``: convert to list(s) of bounds
|
|
181
172
|
- ``to_datetime_dict``: convert a datetime string to a dictionary where values are either a string or a list
|
|
182
|
-
- ``
|
|
183
|
-
- ``
|
|
184
|
-
- ``
|
|
173
|
+
- ``to_ewkt``: convert to EWKT (Extended Well-Known text)
|
|
174
|
+
- ``to_geojson``: convert to a GeoJSON (via __geo_interface__ if exists)
|
|
175
|
+
- ``to_iso_date``: remove the time part of a iso datetime string
|
|
176
|
+
- ``to_iso_utc_datetime_from_milliseconds``: convert a utc timestamp in given milliseconds to a utc iso datetime
|
|
177
|
+
- ``to_iso_utc_datetime``: convert a UTC datetime string to ISO UTC datetime string
|
|
178
|
+
- ``to_lower``: Convert a string to lowercase
|
|
179
|
+
- ``to_nwse_bounds_str``: convert to North,West,South,East bounds string with given separator
|
|
180
|
+
- ``to_nwse_bounds``: convert to North,West,South,East bounds
|
|
181
|
+
- ``to_rounded_wkt``: simplify the WKT of a geometry
|
|
182
|
+
- ``to_title``: Convert a string to title case
|
|
183
|
+
- ``to_upper``: Convert a string to uppercase
|
|
185
184
|
|
|
186
185
|
:param search_param: The string to be formatted
|
|
187
186
|
:param args: (optional) Additional arguments to use in the formatting process
|
|
@@ -487,9 +486,9 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
487
486
|
return {"lon": lon, "lat": lat}
|
|
488
487
|
|
|
489
488
|
@staticmethod
|
|
490
|
-
def convert_csv_list(values_list: Any) -> Any:
|
|
489
|
+
def convert_csv_list(values_list: Any, separator=",") -> Any:
|
|
491
490
|
if isinstance(values_list, list):
|
|
492
|
-
return
|
|
491
|
+
return separator.join([str(x) for x in values_list])
|
|
493
492
|
else:
|
|
494
493
|
return values_list
|
|
495
494
|
|
|
@@ -529,6 +528,35 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
529
528
|
old, new = ast.literal_eval(args)
|
|
530
529
|
return re.sub(old, new, value)
|
|
531
530
|
|
|
531
|
+
@staticmethod
|
|
532
|
+
def convert_replace_str_tuple(value: Any, args: str) -> str:
|
|
533
|
+
"""
|
|
534
|
+
Apply multiple replacements on a string.
|
|
535
|
+
args should be a string representing a list/tuple of (old, new) pairs.
|
|
536
|
+
Example: '(("old1", "new1"), ("old2", "new2"))'
|
|
537
|
+
"""
|
|
538
|
+
if isinstance(value, dict):
|
|
539
|
+
value = MetadataFormatter.convert_to_geojson(value)
|
|
540
|
+
elif not isinstance(value, str):
|
|
541
|
+
raise TypeError(
|
|
542
|
+
f"convert_replace_str_tuple expects a string or a dict (apply to_geojson). "
|
|
543
|
+
f"Got {type(value)}: {value}"
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
# args sera une chaîne représentant une liste/tuple de tuples
|
|
547
|
+
replacements = ast.literal_eval(args)
|
|
548
|
+
|
|
549
|
+
if not isinstance(replacements, (list, tuple)):
|
|
550
|
+
raise TypeError(
|
|
551
|
+
f"convert_replace_str_tuple expects a list/tuple of (old,new) pairs. "
|
|
552
|
+
f"Got {type(replacements)}: {replacements}"
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
for old, new in replacements:
|
|
556
|
+
value = re.sub(old, new, value)
|
|
557
|
+
|
|
558
|
+
return value
|
|
559
|
+
|
|
532
560
|
@staticmethod
|
|
533
561
|
def convert_ceda_collection_name(value: str) -> str:
|
|
534
562
|
data_regex = re.compile(r"/data/(?P<name>.+?)/?$")
|
|
@@ -580,6 +608,45 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
580
608
|
result[key] = match.value
|
|
581
609
|
return result
|
|
582
610
|
|
|
611
|
+
@staticmethod
|
|
612
|
+
def convert_dict_filter_and_sub(
|
|
613
|
+
input_dict: dict[Any, Any], args: str
|
|
614
|
+
) -> Union[dict[Any, Any], list[Any]]:
|
|
615
|
+
"""Fitlers dict items using jsonpath and then apply recursive_sub_str"""
|
|
616
|
+
jsonpath_filter_str, old, new = ast.literal_eval(args)
|
|
617
|
+
filtered = MetadataFormatter.convert_dict_filter(
|
|
618
|
+
input_dict, jsonpath_filter_str
|
|
619
|
+
)
|
|
620
|
+
args_str = f"('{old}', '{new}')"
|
|
621
|
+
return MetadataFormatter.convert_recursive_sub_str(filtered, args_str)
|
|
622
|
+
|
|
623
|
+
@staticmethod
|
|
624
|
+
def convert_from_alternate(
|
|
625
|
+
input_obj: dict[str, Any], value: str
|
|
626
|
+
) -> dict[str, Any]:
|
|
627
|
+
"""
|
|
628
|
+
Update assets using given alternate.
|
|
629
|
+
"""
|
|
630
|
+
result: dict[str, Any] = {}
|
|
631
|
+
for k, v in input_obj.items():
|
|
632
|
+
if not isinstance(v, dict):
|
|
633
|
+
continue
|
|
634
|
+
|
|
635
|
+
alt_dict = deepcopy(v).get("alternate")
|
|
636
|
+
if not isinstance(alt_dict, dict):
|
|
637
|
+
continue
|
|
638
|
+
|
|
639
|
+
value_entry = alt_dict.pop(value, None)
|
|
640
|
+
if not isinstance(value_entry, dict):
|
|
641
|
+
continue
|
|
642
|
+
|
|
643
|
+
result[k] = v | value_entry | {"alternate": alt_dict}
|
|
644
|
+
|
|
645
|
+
if len(result[k]["alternate"]) == 0:
|
|
646
|
+
del result[k]["alternate"]
|
|
647
|
+
|
|
648
|
+
return result
|
|
649
|
+
|
|
583
650
|
@staticmethod
|
|
584
651
|
def convert_slice_str(string: str, args: str) -> str:
|
|
585
652
|
cmin, cmax, cstep = [
|
|
@@ -591,6 +658,8 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
591
658
|
@staticmethod
|
|
592
659
|
def convert_to_lower(string: str) -> str:
|
|
593
660
|
"""Convert a string to lowercase."""
|
|
661
|
+
if string == NOT_AVAILABLE:
|
|
662
|
+
return string
|
|
594
663
|
return string.lower()
|
|
595
664
|
|
|
596
665
|
@staticmethod
|
|
@@ -598,6 +667,13 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
598
667
|
"""Convert a string to uppercase."""
|
|
599
668
|
return string.upper()
|
|
600
669
|
|
|
670
|
+
@staticmethod
|
|
671
|
+
def convert_to_title(string: str) -> str:
|
|
672
|
+
"""Convert a string to title case."""
|
|
673
|
+
if string == NOT_AVAILABLE:
|
|
674
|
+
return string
|
|
675
|
+
return string.title()
|
|
676
|
+
|
|
601
677
|
@staticmethod
|
|
602
678
|
def convert_fake_l2a_title_from_l1c(string: str) -> str:
|
|
603
679
|
id_regex = re.compile(
|
|
@@ -1362,17 +1438,30 @@ def format_query_params(
|
|
|
1362
1438
|
error_context,
|
|
1363
1439
|
)
|
|
1364
1440
|
|
|
1365
|
-
for eodag_search_key,
|
|
1441
|
+
for eodag_search_key, provider_search_param in queryables.items():
|
|
1366
1442
|
user_input = query_dict[eodag_search_key]
|
|
1367
1443
|
|
|
1368
|
-
if
|
|
1369
|
-
|
|
1444
|
+
if provider_search_param == user_input:
|
|
1445
|
+
# means the mapping is to be passed as is, in which case we
|
|
1446
|
+
# readily register it
|
|
1447
|
+
if (
|
|
1448
|
+
eodag_search_key in query_params
|
|
1449
|
+
and isinstance(query_params[eodag_search_key], dict)
|
|
1450
|
+
and isinstance(user_input, dict)
|
|
1451
|
+
):
|
|
1452
|
+
query_params[eodag_search_key].update(user_input)
|
|
1453
|
+
else:
|
|
1454
|
+
query_params[eodag_search_key] = user_input
|
|
1455
|
+
continue
|
|
1456
|
+
|
|
1457
|
+
if COMPLEX_QS_REGEX.match(provider_search_param):
|
|
1458
|
+
parts = provider_search_param.split("=")
|
|
1370
1459
|
if len(parts) == 1:
|
|
1371
1460
|
formatted_query_param = format_metadata(
|
|
1372
|
-
|
|
1461
|
+
provider_search_param, product_type, **query_dict
|
|
1373
1462
|
)
|
|
1374
1463
|
formatted_query_param = formatted_query_param.replace("'", '"')
|
|
1375
|
-
if "{{" in
|
|
1464
|
+
if "{{" in provider_search_param:
|
|
1376
1465
|
# retrieve values from hashes where keys are given in the param
|
|
1377
1466
|
if "}[" in formatted_query_param:
|
|
1378
1467
|
formatted_query_param = _resolve_hashes(formatted_query_param)
|
|
@@ -1396,7 +1485,7 @@ def format_query_params(
|
|
|
1396
1485
|
provider_value, product_type, **query_dict
|
|
1397
1486
|
)
|
|
1398
1487
|
else:
|
|
1399
|
-
query_params[
|
|
1488
|
+
query_params[provider_search_param] = user_input
|
|
1400
1489
|
# Now get all the literal search params (i.e params to be passed "as is"
|
|
1401
1490
|
# in the search request)
|
|
1402
1491
|
# ignore additional_params if it isn't a dictionary
|
|
@@ -1527,7 +1616,15 @@ def _get_queryables(
|
|
|
1527
1616
|
config.discover_metadata.get("metadata_pattern", "")
|
|
1528
1617
|
)
|
|
1529
1618
|
search_param_cfg = config.discover_metadata.get("search_param", "")
|
|
1530
|
-
|
|
1619
|
+
search_param_unparsed_cfg = config.discover_metadata.get(
|
|
1620
|
+
"search_param_unparsed", []
|
|
1621
|
+
)
|
|
1622
|
+
if (
|
|
1623
|
+
search_param_unparsed_cfg
|
|
1624
|
+
and eodag_search_key in search_param_unparsed_cfg
|
|
1625
|
+
):
|
|
1626
|
+
queryables[eodag_search_key] = user_input
|
|
1627
|
+
elif pattern.match(eodag_search_key) and isinstance(
|
|
1531
1628
|
search_param_cfg, str
|
|
1532
1629
|
):
|
|
1533
1630
|
search_param = search_param_cfg.format(metadata=eodag_search_key)
|
eodag/cli.py
CHANGED
|
@@ -42,13 +42,14 @@ Commands:
|
|
|
42
42
|
|
|
43
43
|
from __future__ import annotations
|
|
44
44
|
|
|
45
|
+
import functools
|
|
45
46
|
import json
|
|
46
47
|
import os
|
|
47
48
|
import shutil
|
|
48
49
|
import sys
|
|
49
50
|
import textwrap
|
|
50
51
|
from importlib.metadata import metadata
|
|
51
|
-
from typing import TYPE_CHECKING, Any, Mapping
|
|
52
|
+
from typing import TYPE_CHECKING, Any, Callable, Mapping, Optional
|
|
52
53
|
from urllib.parse import parse_qs
|
|
53
54
|
|
|
54
55
|
import click
|
|
@@ -118,6 +119,22 @@ class MutuallyExclusiveOption(click.Option):
|
|
|
118
119
|
return super(MutuallyExclusiveOption, self).handle_parse_result(ctx, opts, args)
|
|
119
120
|
|
|
120
121
|
|
|
122
|
+
def _deprecated_cli(message: str, version: Optional[str] = None) -> Callable[..., Any]:
|
|
123
|
+
"""Decorator to mark a CLI command as deprecated and print a bold yellow warning."""
|
|
124
|
+
version_msg = f" -- Deprecated since v{version}" if version else ""
|
|
125
|
+
|
|
126
|
+
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
127
|
+
@functools.wraps(func)
|
|
128
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
129
|
+
full_message = f"DEPRECATED: {message}{version_msg}"
|
|
130
|
+
click.echo(click.style(full_message, fg="yellow", bold=True), err=True)
|
|
131
|
+
return func(*args, **kwargs)
|
|
132
|
+
|
|
133
|
+
return wrapper
|
|
134
|
+
|
|
135
|
+
return decorator
|
|
136
|
+
|
|
137
|
+
|
|
121
138
|
@click.group(chain=True)
|
|
122
139
|
@click.option(
|
|
123
140
|
"-v",
|
|
@@ -631,9 +648,17 @@ def download(ctx: Context, **kwargs: Any) -> None:
|
|
|
631
648
|
|
|
632
649
|
|
|
633
650
|
@eodag.command(
|
|
634
|
-
help="Start eodag HTTP server\n\n"
|
|
635
|
-
|
|
636
|
-
|
|
651
|
+
help="(deprecated) Start eodag HTTP server\n\n"
|
|
652
|
+
+ (
|
|
653
|
+
click.style(
|
|
654
|
+
"Running a web server from the CLI is deprecated and will be removed in a future version.\n"
|
|
655
|
+
"This feature has been moved to its own repository: https://github.com/CS-SI/stac-fastapi-eodag\n\n",
|
|
656
|
+
fg="yellow",
|
|
657
|
+
bold=True,
|
|
658
|
+
)
|
|
659
|
+
+ "Set EODAG_CORS_ALLOWED_ORIGINS environment variable to configure Cross-Origin Resource Sharing allowed "
|
|
660
|
+
"origins as comma-separated URLs (e.g. 'http://somewhere,http://somewhere.else')."
|
|
661
|
+
)
|
|
637
662
|
)
|
|
638
663
|
@click.option(
|
|
639
664
|
"-f",
|
|
@@ -676,6 +701,13 @@ def download(ctx: Context, **kwargs: Any) -> None:
|
|
|
676
701
|
help="Run in debug mode (for development purpose)",
|
|
677
702
|
)
|
|
678
703
|
@click.pass_context
|
|
704
|
+
@_deprecated_cli(
|
|
705
|
+
message=(
|
|
706
|
+
"Running a web server from the CLI is deprecated and will be removed in a future version. "
|
|
707
|
+
"This feature has been moved to its own repository: https://github.com/CS-SI/stac-fastapi-eodag"
|
|
708
|
+
),
|
|
709
|
+
version="3.9.0",
|
|
710
|
+
)
|
|
679
711
|
def serve_rest(
|
|
680
712
|
ctx: Context,
|
|
681
713
|
daemon: bool,
|
eodag/config.py
CHANGED
|
@@ -272,6 +272,8 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
272
272
|
search_param: str | dict[str, Any]
|
|
273
273
|
#: Path to the metadata in search result
|
|
274
274
|
metadata_path: str
|
|
275
|
+
#: list search parameters to send as is to the provider
|
|
276
|
+
search_param_unparsed: list[str]
|
|
275
277
|
#: Whether an error must be raised when using a search parameter which is not queryable or not
|
|
276
278
|
raise_mtd_discovery_error: bool
|
|
277
279
|
|
|
@@ -543,8 +545,6 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
543
545
|
#: :class:`~eodag.plugins.download.s3rest.S3RestDownload`
|
|
544
546
|
#: At which level of the path part of the url the bucket can be found
|
|
545
547
|
bucket_path_level: int
|
|
546
|
-
#: :class:`~eodag.plugins.download.aws.AwsDownload` Whether download is done from a requester-pays bucket or not
|
|
547
|
-
requester_pays: bool
|
|
548
548
|
#: :class:`~eodag.plugins.download.aws.AwsDownload` S3 endpoint
|
|
549
549
|
s3_endpoint: str
|
|
550
550
|
|
|
@@ -571,6 +571,9 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
571
571
|
#: :class:`~eodag.plugins.authentication.base.Authentication` Part of the search or download plugin configuration
|
|
572
572
|
#: that needs authentication
|
|
573
573
|
matching_conf: dict[str, Any]
|
|
574
|
+
#: :class:`~eodag.plugins.authentication.aws_auth.AwsAuth`
|
|
575
|
+
#: Whether download is done from a requester-pays bucket or not
|
|
576
|
+
requester_pays: bool
|
|
574
577
|
#: :class:`~eodag.plugins.authentication.openid_connect.OIDCRefreshTokenBase`
|
|
575
578
|
#: How the token should be used in the request
|
|
576
579
|
token_provision: str
|
eodag/plugins/apis/ecmwf.py
CHANGED
|
@@ -46,6 +46,7 @@ from eodag.utils.logging import get_logging_verbose
|
|
|
46
46
|
if TYPE_CHECKING:
|
|
47
47
|
from typing import Any, Optional, Union
|
|
48
48
|
|
|
49
|
+
from mypy_boto3_s3 import S3ServiceResource
|
|
49
50
|
from requests.auth import AuthBase
|
|
50
51
|
|
|
51
52
|
from eodag.api.product import EOProduct
|
|
@@ -55,6 +56,7 @@ if TYPE_CHECKING:
|
|
|
55
56
|
from eodag.types.download_args import DownloadConf
|
|
56
57
|
from eodag.utils import DownloadedCallback, ProgressCallback, Unpack
|
|
57
58
|
|
|
59
|
+
|
|
58
60
|
logger = logging.getLogger("eodag.apis.ecmwf")
|
|
59
61
|
|
|
60
62
|
ECMWF_MARS_KNOWN_FORMATS = {"grib": "grib", "netcdf": "nc"}
|
|
@@ -171,7 +173,7 @@ class EcmwfApi(Api, ECMWFSearch):
|
|
|
171
173
|
def download(
|
|
172
174
|
self,
|
|
173
175
|
product: EOProduct,
|
|
174
|
-
auth: Optional[Union[AuthBase, S3SessionKwargs]] = None,
|
|
176
|
+
auth: Optional[Union[AuthBase, S3SessionKwargs, S3ServiceResource]] = None,
|
|
175
177
|
progress_callback: Optional[ProgressCallback] = None,
|
|
176
178
|
wait: float = DEFAULT_DOWNLOAD_WAIT,
|
|
177
179
|
timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
|
eodag/plugins/apis/usgs.py
CHANGED
|
@@ -57,6 +57,7 @@ from eodag.utils.exceptions import (
|
|
|
57
57
|
)
|
|
58
58
|
|
|
59
59
|
if TYPE_CHECKING:
|
|
60
|
+
from mypy_boto3_s3 import S3ServiceResource
|
|
60
61
|
from requests.auth import AuthBase
|
|
61
62
|
|
|
62
63
|
from eodag.api.search_result import SearchResult
|
|
@@ -296,7 +297,7 @@ class UsgsApi(Api):
|
|
|
296
297
|
def download(
|
|
297
298
|
self,
|
|
298
299
|
product: EOProduct,
|
|
299
|
-
auth: Optional[Union[AuthBase, S3SessionKwargs]] = None,
|
|
300
|
+
auth: Optional[Union[AuthBase, S3SessionKwargs, S3ServiceResource]] = None,
|
|
300
301
|
progress_callback: Optional[ProgressCallback] = None,
|
|
301
302
|
wait: float = DEFAULT_DOWNLOAD_WAIT,
|
|
302
303
|
timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
|