eodag 3.0.0b3__py3-none-any.whl → 3.1.0__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 +347 -247
- eodag/api/product/_assets.py +44 -15
- eodag/api/product/_product.py +58 -47
- eodag/api/product/drivers/__init__.py +81 -4
- eodag/api/product/drivers/base.py +65 -4
- eodag/api/product/drivers/generic.py +65 -0
- eodag/api/product/drivers/sentinel1.py +97 -0
- eodag/api/product/drivers/sentinel2.py +95 -0
- eodag/api/product/metadata_mapping.py +129 -93
- eodag/api/search_result.py +28 -12
- eodag/cli.py +61 -24
- eodag/config.py +457 -167
- eodag/plugins/apis/base.py +10 -4
- eodag/plugins/apis/ecmwf.py +53 -23
- eodag/plugins/apis/usgs.py +41 -17
- eodag/plugins/authentication/aws_auth.py +30 -18
- eodag/plugins/authentication/base.py +14 -3
- eodag/plugins/authentication/generic.py +14 -3
- eodag/plugins/authentication/header.py +14 -6
- eodag/plugins/authentication/keycloak.py +44 -25
- eodag/plugins/authentication/oauth.py +18 -4
- eodag/plugins/authentication/openid_connect.py +192 -171
- eodag/plugins/authentication/qsauth.py +12 -4
- eodag/plugins/authentication/sas_auth.py +22 -5
- eodag/plugins/authentication/token.py +95 -17
- eodag/plugins/authentication/token_exchange.py +19 -19
- eodag/plugins/base.py +4 -4
- eodag/plugins/crunch/base.py +8 -5
- eodag/plugins/crunch/filter_date.py +9 -6
- eodag/plugins/crunch/filter_latest_intersect.py +9 -8
- eodag/plugins/crunch/filter_latest_tpl_name.py +8 -8
- eodag/plugins/crunch/filter_overlap.py +9 -11
- eodag/plugins/crunch/filter_property.py +10 -10
- eodag/plugins/download/aws.py +181 -105
- eodag/plugins/download/base.py +49 -67
- eodag/plugins/download/creodias_s3.py +40 -2
- eodag/plugins/download/http.py +247 -223
- eodag/plugins/download/s3rest.py +29 -28
- eodag/plugins/manager.py +176 -41
- eodag/plugins/search/__init__.py +6 -5
- eodag/plugins/search/base.py +123 -60
- eodag/plugins/search/build_search_result.py +1046 -355
- eodag/plugins/search/cop_marine.py +132 -39
- eodag/plugins/search/creodias_s3.py +19 -68
- eodag/plugins/search/csw.py +48 -8
- eodag/plugins/search/data_request_search.py +124 -23
- eodag/plugins/search/qssearch.py +531 -310
- eodag/plugins/search/stac_list_assets.py +85 -0
- eodag/plugins/search/static_stac_search.py +23 -24
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +1295 -355
- eodag/resources/providers.yml +1819 -3010
- eodag/resources/stac.yml +3 -163
- eodag/resources/stac_api.yml +2 -2
- eodag/resources/user_conf_template.yml +115 -99
- eodag/rest/cache.py +2 -2
- eodag/rest/config.py +3 -4
- eodag/rest/constants.py +0 -1
- eodag/rest/core.py +157 -117
- eodag/rest/errors.py +181 -0
- eodag/rest/server.py +57 -339
- eodag/rest/stac.py +133 -581
- eodag/rest/types/collections_search.py +3 -3
- eodag/rest/types/eodag_search.py +41 -30
- eodag/rest/types/queryables.py +42 -32
- eodag/rest/types/stac_search.py +15 -16
- eodag/rest/utils/__init__.py +14 -21
- eodag/rest/utils/cql_evaluate.py +6 -6
- eodag/rest/utils/rfc3339.py +2 -2
- eodag/types/__init__.py +153 -32
- eodag/types/bbox.py +2 -2
- eodag/types/download_args.py +4 -4
- eodag/types/queryables.py +183 -73
- eodag/types/search_args.py +6 -6
- eodag/types/whoosh.py +127 -3
- eodag/utils/__init__.py +228 -106
- eodag/utils/exceptions.py +47 -26
- eodag/utils/import_system.py +2 -2
- eodag/utils/logging.py +37 -77
- eodag/utils/repr.py +65 -6
- eodag/utils/requests.py +13 -15
- eodag/utils/rest.py +2 -2
- eodag/utils/s3.py +231 -0
- eodag/utils/stac_reader.py +11 -11
- {eodag-3.0.0b3.dist-info → eodag-3.1.0.dist-info}/METADATA +81 -81
- eodag-3.1.0.dist-info/RECORD +113 -0
- {eodag-3.0.0b3.dist-info → eodag-3.1.0.dist-info}/WHEEL +1 -1
- {eodag-3.0.0b3.dist-info → eodag-3.1.0.dist-info}/entry_points.txt +5 -2
- eodag/resources/constraints/climate-dt.json +0 -13
- eodag/resources/constraints/extremes-dt.json +0 -8
- eodag/utils/constraints.py +0 -244
- eodag-3.0.0b3.dist-info/RECORD +0 -110
- {eodag-3.0.0b3.dist-info → eodag-3.1.0.dist-info}/LICENSE +0 -0
- {eodag-3.0.0b3.dist-info → eodag-3.1.0.dist-info}/top_level.txt +0 -0
eodag/plugins/download/base.py
CHANGED
|
@@ -26,17 +26,7 @@ import tempfile
|
|
|
26
26
|
import zipfile
|
|
27
27
|
from datetime import datetime, timedelta
|
|
28
28
|
from time import sleep
|
|
29
|
-
from typing import
|
|
30
|
-
TYPE_CHECKING,
|
|
31
|
-
Any,
|
|
32
|
-
Callable,
|
|
33
|
-
Dict,
|
|
34
|
-
List,
|
|
35
|
-
Optional,
|
|
36
|
-
Tuple,
|
|
37
|
-
TypeVar,
|
|
38
|
-
Union,
|
|
39
|
-
)
|
|
29
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union
|
|
40
30
|
|
|
41
31
|
from eodag.plugins.base import PluginTopic
|
|
42
32
|
from eodag.utils import (
|
|
@@ -60,6 +50,7 @@ if TYPE_CHECKING:
|
|
|
60
50
|
from eodag.api.product import EOProduct
|
|
61
51
|
from eodag.api.search_result import SearchResult
|
|
62
52
|
from eodag.config import PluginConfig
|
|
53
|
+
from eodag.types import S3SessionKwargs
|
|
63
54
|
from eodag.types.download_args import DownloadConf
|
|
64
55
|
from eodag.utils import DownloadedCallback, Unpack
|
|
65
56
|
|
|
@@ -81,15 +72,15 @@ class Download(PluginTopic):
|
|
|
81
72
|
|
|
82
73
|
- download data in the ``output_dir`` folder defined in the plugin's
|
|
83
74
|
configuration or passed through kwargs
|
|
84
|
-
- extract products from their archive (if relevant) if ``extract`` is set to True
|
|
85
|
-
(True by default)
|
|
75
|
+
- extract products from their archive (if relevant) if ``extract`` is set to ``True``
|
|
76
|
+
(``True`` by default)
|
|
86
77
|
- save a product in an archive/directory (in ``output_dir``) whose name must be
|
|
87
78
|
the product's ``title`` property
|
|
88
79
|
- update the product's ``location`` attribute once its data is downloaded (and
|
|
89
80
|
eventually after it's extracted) to the product's location given as a file URI
|
|
90
|
-
(e.g.
|
|
91
|
-
|
|
92
|
-
- save a *record* file in the directory ``output_dir/.downloaded`` whose name
|
|
81
|
+
(e.g. ``file:///tmp/product_folder`` on Linux or
|
|
82
|
+
``file:///C:/Users/username/AppData/Local/Temp`` on Windows)
|
|
83
|
+
- save a *record* file in the directory ``{output_dir}/.downloaded`` whose name
|
|
93
84
|
is built on the MD5 hash of the product's ``product_type`` and ``properties['id']``
|
|
94
85
|
attributes (``hashlib.md5((product.product_type+"-"+product.properties['id']).encode("utf-8")).hexdigest()``)
|
|
95
86
|
and whose content is the product's ``remote_location`` attribute itself.
|
|
@@ -110,10 +101,10 @@ class Download(PluginTopic):
|
|
|
110
101
|
def download(
|
|
111
102
|
self,
|
|
112
103
|
product: EOProduct,
|
|
113
|
-
auth: Optional[Union[AuthBase,
|
|
104
|
+
auth: Optional[Union[AuthBase, S3SessionKwargs]] = None,
|
|
114
105
|
progress_callback: Optional[ProgressCallback] = None,
|
|
115
|
-
wait:
|
|
116
|
-
timeout:
|
|
106
|
+
wait: float = DEFAULT_DOWNLOAD_WAIT,
|
|
107
|
+
timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
|
|
117
108
|
**kwargs: Unpack[DownloadConf],
|
|
118
109
|
) -> Optional[str]:
|
|
119
110
|
r"""
|
|
@@ -130,8 +121,8 @@ class Download(PluginTopic):
|
|
|
130
121
|
and will override any other values defined in a configuration
|
|
131
122
|
file or with environment variables.
|
|
132
123
|
:returns: The absolute path to the downloaded product in the local filesystem
|
|
133
|
-
(e.g.
|
|
134
|
-
|
|
124
|
+
(e.g. ``/tmp/product.zip`` on Linux or
|
|
125
|
+
``C:\\Users\\username\\AppData\\Local\\Temp\\product.zip`` on Windows)
|
|
135
126
|
"""
|
|
136
127
|
raise NotImplementedError(
|
|
137
128
|
"A Download plugin must implement a method named download"
|
|
@@ -140,10 +131,10 @@ class Download(PluginTopic):
|
|
|
140
131
|
def _stream_download_dict(
|
|
141
132
|
self,
|
|
142
133
|
product: EOProduct,
|
|
143
|
-
auth: Optional[Union[AuthBase,
|
|
134
|
+
auth: Optional[Union[AuthBase, S3SessionKwargs]] = None,
|
|
144
135
|
progress_callback: Optional[ProgressCallback] = None,
|
|
145
|
-
wait:
|
|
146
|
-
timeout:
|
|
136
|
+
wait: float = DEFAULT_DOWNLOAD_WAIT,
|
|
137
|
+
timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
|
|
147
138
|
**kwargs: Unpack[DownloadConf],
|
|
148
139
|
) -> StreamResponse:
|
|
149
140
|
r"""
|
|
@@ -155,11 +146,11 @@ class Download(PluginTopic):
|
|
|
155
146
|
:param wait: (optional) If download fails, wait time in minutes between two download tries
|
|
156
147
|
:param timeout: (optional) If download fails, maximum time in minutes before stop retrying
|
|
157
148
|
to download
|
|
158
|
-
:param kwargs:
|
|
159
|
-
and
|
|
149
|
+
:param kwargs: ``output_dir`` (str), ``extract`` (bool), ``delete_archive`` (bool)
|
|
150
|
+
and ``dl_url_params`` (dict) can be provided as additional kwargs
|
|
160
151
|
and will override any other values defined in a configuration
|
|
161
152
|
file or with environment variables.
|
|
162
|
-
:returns:
|
|
153
|
+
:returns: Dictionary of :class:`~fastapi.responses.StreamingResponse` keyword-arguments
|
|
163
154
|
"""
|
|
164
155
|
raise NotImplementedError(
|
|
165
156
|
"Download streaming must be implemented using a method named _stream_download_dict"
|
|
@@ -170,7 +161,7 @@ class Download(PluginTopic):
|
|
|
170
161
|
product: EOProduct,
|
|
171
162
|
progress_callback: Optional[ProgressCallback] = None,
|
|
172
163
|
**kwargs: Unpack[DownloadConf],
|
|
173
|
-
) ->
|
|
164
|
+
) -> tuple[Optional[str], Optional[str]]:
|
|
174
165
|
"""Check if file has already been downloaded, and prepare product download
|
|
175
166
|
|
|
176
167
|
:param product: The EO product to download
|
|
@@ -202,8 +193,8 @@ class Download(PluginTopic):
|
|
|
202
193
|
or getattr(self.config, "output_dir", tempfile.gettempdir())
|
|
203
194
|
or tempfile.gettempdir()
|
|
204
195
|
)
|
|
205
|
-
output_extension = kwargs.get("output_extension"
|
|
206
|
-
self.config, "output_extension", "
|
|
196
|
+
output_extension = kwargs.get("output_extension") or getattr(
|
|
197
|
+
self.config, "output_extension", ""
|
|
207
198
|
)
|
|
208
199
|
|
|
209
200
|
# Strong asumption made here: all products downloaded will be zip files
|
|
@@ -233,9 +224,13 @@ class Download(PluginTopic):
|
|
|
233
224
|
logger.warning(
|
|
234
225
|
f"Unable to create records directory. Got:\n{tb.format_exc()}",
|
|
235
226
|
)
|
|
227
|
+
url_hash = hashlib.md5(url.encode("utf-8")).hexdigest()
|
|
228
|
+
old_record_filename = os.path.join(download_records_dir, url_hash)
|
|
236
229
|
record_filename = os.path.join(
|
|
237
230
|
download_records_dir, self.generate_record_hash(product)
|
|
238
231
|
)
|
|
232
|
+
if os.path.isfile(old_record_filename):
|
|
233
|
+
os.rename(old_record_filename, record_filename)
|
|
239
234
|
if os.path.isfile(record_filename) and os.path.isfile(fs_path):
|
|
240
235
|
logger.info(
|
|
241
236
|
f"Product already downloaded: {fs_path}",
|
|
@@ -339,13 +334,7 @@ class Download(PluginTopic):
|
|
|
339
334
|
if delete_archive is not None
|
|
340
335
|
else getattr(self.config, "delete_archive", True)
|
|
341
336
|
)
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
product_path = (
|
|
345
|
-
fs_path[: fs_path.index(output_extension)]
|
|
346
|
-
if output_extension in fs_path
|
|
347
|
-
else fs_path
|
|
348
|
-
)
|
|
337
|
+
product_path, _ = os.path.splitext(fs_path)
|
|
349
338
|
product_path_exists = os.path.exists(product_path)
|
|
350
339
|
if product_path_exists and os.path.isfile(product_path):
|
|
351
340
|
logger.info(
|
|
@@ -422,10 +411,10 @@ class Download(PluginTopic):
|
|
|
422
411
|
|
|
423
412
|
tmp_dir.cleanup()
|
|
424
413
|
|
|
425
|
-
if delete_archive:
|
|
414
|
+
if delete_archive and os.path.isfile(fs_path):
|
|
426
415
|
logger.info(f"Deleting archive {os.path.basename(fs_path)}")
|
|
427
416
|
os.unlink(fs_path)
|
|
428
|
-
|
|
417
|
+
elif os.path.isfile(fs_path):
|
|
429
418
|
logger.info(
|
|
430
419
|
f"Archive deletion is deactivated, keeping {os.path.basename(fs_path)}"
|
|
431
420
|
)
|
|
@@ -441,13 +430,13 @@ class Download(PluginTopic):
|
|
|
441
430
|
def download_all(
|
|
442
431
|
self,
|
|
443
432
|
products: SearchResult,
|
|
444
|
-
auth: Optional[Union[AuthBase,
|
|
433
|
+
auth: Optional[Union[AuthBase, S3SessionKwargs]] = None,
|
|
445
434
|
downloaded_callback: Optional[DownloadedCallback] = None,
|
|
446
435
|
progress_callback: Optional[ProgressCallback] = None,
|
|
447
|
-
wait:
|
|
448
|
-
timeout:
|
|
436
|
+
wait: float = DEFAULT_DOWNLOAD_WAIT,
|
|
437
|
+
timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
|
|
449
438
|
**kwargs: Unpack[DownloadConf],
|
|
450
|
-
) ->
|
|
439
|
+
) -> list[str]:
|
|
451
440
|
"""
|
|
452
441
|
Base download_all method.
|
|
453
442
|
|
|
@@ -458,7 +447,7 @@ class Download(PluginTopic):
|
|
|
458
447
|
:param auth: (optional) authenticated object
|
|
459
448
|
:param downloaded_callback: (optional) A method or a callable object which takes
|
|
460
449
|
as parameter the ``product``. You can use the base class
|
|
461
|
-
:class:`~eodag.
|
|
450
|
+
:class:`~eodag.utils.DownloadedCallback` and override
|
|
462
451
|
its ``__call__`` method. Will be called each time a product
|
|
463
452
|
finishes downloading
|
|
464
453
|
:param progress_callback: (optional) A progress callback
|
|
@@ -476,7 +465,7 @@ class Download(PluginTopic):
|
|
|
476
465
|
# Products are going to be removed one by one from this sequence once
|
|
477
466
|
# downloaded.
|
|
478
467
|
products = products[:]
|
|
479
|
-
paths:
|
|
468
|
+
paths: list[str] = []
|
|
480
469
|
# initiate retry loop
|
|
481
470
|
start_time = datetime.now()
|
|
482
471
|
stop_time = start_time + timedelta(minutes=timeout)
|
|
@@ -541,7 +530,7 @@ class Download(PluginTopic):
|
|
|
541
530
|
)
|
|
542
531
|
raise
|
|
543
532
|
|
|
544
|
-
except RuntimeError:
|
|
533
|
+
except (RuntimeError, Exception):
|
|
545
534
|
import traceback as tb
|
|
546
535
|
|
|
547
536
|
logger.error(
|
|
@@ -549,16 +538,9 @@ class Download(PluginTopic):
|
|
|
549
538
|
"Skipping it"
|
|
550
539
|
)
|
|
551
540
|
logger.debug(f"\n{tb.format_exc()}")
|
|
552
|
-
stop_time = datetime.now()
|
|
553
541
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
logger.warning(
|
|
558
|
-
f"A problem occurred during download of product: {product}. "
|
|
559
|
-
"Skipping it",
|
|
560
|
-
)
|
|
561
|
-
logger.debug(f"\n{tb.format_exc()}")
|
|
542
|
+
# product skipped, to not retry it
|
|
543
|
+
products.remove(product)
|
|
562
544
|
|
|
563
545
|
if (
|
|
564
546
|
len(products) > 0
|
|
@@ -585,14 +567,14 @@ class Download(PluginTopic):
|
|
|
585
567
|
|
|
586
568
|
return paths
|
|
587
569
|
|
|
588
|
-
def
|
|
589
|
-
self, product: EOProduct, wait:
|
|
570
|
+
def _order_download_retry(
|
|
571
|
+
self, product: EOProduct, wait: float, timeout: float
|
|
590
572
|
) -> Callable[[Callable[..., T]], Callable[..., T]]:
|
|
591
573
|
"""
|
|
592
|
-
|
|
574
|
+
Order download retry decorator.
|
|
593
575
|
|
|
594
|
-
Retries the wrapped
|
|
595
|
-
exception is thrown until
|
|
576
|
+
Retries the wrapped order_download method after ``wait`` minutes if a
|
|
577
|
+
``NotAvailableError`` exception is thrown until ``timeout`` minutes.
|
|
596
578
|
|
|
597
579
|
:param product: The EO product to download
|
|
598
580
|
:param wait: If download fails, wait time in minutes between two download tries
|
|
@@ -601,7 +583,7 @@ class Download(PluginTopic):
|
|
|
601
583
|
:returns: decorator
|
|
602
584
|
"""
|
|
603
585
|
|
|
604
|
-
def decorator(
|
|
586
|
+
def decorator(order_download: Callable[..., T]) -> Callable[..., T]:
|
|
605
587
|
def download_and_retry(*args: Any, **kwargs: Unpack[DownloadConf]) -> T:
|
|
606
588
|
# initiate retry loop
|
|
607
589
|
start_time = datetime.now()
|
|
@@ -618,7 +600,7 @@ class Download(PluginTopic):
|
|
|
618
600
|
if datetime_now >= product.next_try:
|
|
619
601
|
product.next_try += timedelta(minutes=wait)
|
|
620
602
|
try:
|
|
621
|
-
return
|
|
603
|
+
return order_download(*args, **kwargs)
|
|
622
604
|
|
|
623
605
|
except NotAvailableError as e:
|
|
624
606
|
if not getattr(self.config, "order_enabled", False):
|
|
@@ -634,7 +616,7 @@ class Download(PluginTopic):
|
|
|
634
616
|
).seconds
|
|
635
617
|
retry_count += 1
|
|
636
618
|
retry_info = (
|
|
637
|
-
f"[Retry #{retry_count}] Waited {wait_seconds}s,
|
|
619
|
+
f"[Retry #{retry_count}] Waited {wait_seconds}s, checking order status again"
|
|
638
620
|
f" (retry every {wait}' for {timeout}')"
|
|
639
621
|
)
|
|
640
622
|
logger.info(not_available_info)
|
|
@@ -656,8 +638,8 @@ class Download(PluginTopic):
|
|
|
656
638
|
).microseconds / 1e6
|
|
657
639
|
retry_count += 1
|
|
658
640
|
retry_info = (
|
|
659
|
-
f"[Retry #{retry_count}] Waiting {wait_seconds}s until next
|
|
660
|
-
f"
|
|
641
|
+
f"[Retry #{retry_count}] Waiting {wait_seconds}s until next order status check"
|
|
642
|
+
f" (retry every {wait}' for {timeout}')"
|
|
661
643
|
)
|
|
662
644
|
logger.info(not_available_info)
|
|
663
645
|
# Retry-After info from Response header
|
|
@@ -678,12 +660,12 @@ class Download(PluginTopic):
|
|
|
678
660
|
logger.info(not_available_info)
|
|
679
661
|
raise NotAvailableError(
|
|
680
662
|
f"{product.properties['title']} is not available ({product.properties['storageStatus']})"
|
|
681
|
-
f" and
|
|
663
|
+
f" and order was not successfull, timeout reached"
|
|
682
664
|
)
|
|
683
665
|
elif datetime_now >= stop_time:
|
|
684
666
|
raise NotAvailableError(not_available_info)
|
|
685
667
|
|
|
686
|
-
return
|
|
668
|
+
return order_download(*args, **kwargs)
|
|
687
669
|
|
|
688
670
|
return download_and_retry
|
|
689
671
|
|
|
@@ -15,17 +15,28 @@
|
|
|
15
15
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
16
|
# See the License for the specific language governing permissions and
|
|
17
17
|
# limitations under the License.
|
|
18
|
+
from typing import Optional
|
|
18
19
|
|
|
19
20
|
import boto3
|
|
20
21
|
from botocore.exceptions import ClientError
|
|
21
22
|
|
|
23
|
+
from eodag import EOProduct
|
|
22
24
|
from eodag.plugins.download.aws import AwsDownload
|
|
23
25
|
from eodag.utils.exceptions import MisconfiguredError
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
class CreodiasS3Download(AwsDownload):
|
|
27
29
|
"""
|
|
28
|
-
Download on creodias s3 from their VMs
|
|
30
|
+
Download on creodias s3 from their VMs (extension of :class:`~eodag.plugins.download.aws.AwsDownload`)
|
|
31
|
+
|
|
32
|
+
:param provider: provider name
|
|
33
|
+
:param config: Download plugin configuration:
|
|
34
|
+
|
|
35
|
+
* :attr:`~eodag.config.PluginConfig.type` (``str``) (**mandatory**): CreodiasS3Download
|
|
36
|
+
* :attr:`~eodag.config.PluginConfig.base_uri` (``str``) (**mandatory**): s3 endpoint url
|
|
37
|
+
* :attr:`~eodag.config.PluginConfig.s3_bucket` (``str``) (**mandatory**): bucket where the products can be found
|
|
38
|
+
* :attr:`~eodag.config.PluginConfig.ssl_verify` (``bool``): if the ssl certificates should be
|
|
39
|
+
verified in requests; default: ``True``
|
|
29
40
|
"""
|
|
30
41
|
|
|
31
42
|
def _get_authenticated_objects_unsigned(self, bucket_name, prefix, auth_dict):
|
|
@@ -50,9 +61,36 @@ class CreodiasS3Download(AwsDownload):
|
|
|
50
61
|
|
|
51
62
|
s3_session = boto3.session.Session(**auth_dict)
|
|
52
63
|
s3_resource = s3_session.resource(
|
|
53
|
-
"s3", endpoint_url=getattr(self.config, "
|
|
64
|
+
"s3", endpoint_url=getattr(self.config, "s3_endpoint", None)
|
|
54
65
|
)
|
|
55
66
|
objects = s3_resource.Bucket(bucket_name).objects.filter()
|
|
56
67
|
list(objects.filter(Prefix=prefix).limit(1))
|
|
57
68
|
self.s3_session = s3_session
|
|
58
69
|
return objects
|
|
70
|
+
|
|
71
|
+
def _get_bucket_names_and_prefixes(
|
|
72
|
+
self,
|
|
73
|
+
product: EOProduct,
|
|
74
|
+
asset_filter: Optional[str] = None,
|
|
75
|
+
ignore_assets: Optional[bool] = False,
|
|
76
|
+
) -> list[tuple[str, Optional[str]]]:
|
|
77
|
+
"""
|
|
78
|
+
Retrieves the bucket names and path prefixes for the assets
|
|
79
|
+
|
|
80
|
+
:param product: product for which the assets shall be downloaded
|
|
81
|
+
:param asset_filter: text for which the assets should be filtered
|
|
82
|
+
:param ignore_assets: if product instead of individual assets should be used
|
|
83
|
+
:return: tuples of bucket names and prefixes
|
|
84
|
+
"""
|
|
85
|
+
# if assets are defined, use them instead of scanning product.location
|
|
86
|
+
if len(product.assets) > 0 and not ignore_assets:
|
|
87
|
+
bucket_names_and_prefixes = super()._get_bucket_names_and_prefixes(
|
|
88
|
+
product, asset_filter, ignore_assets
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
# if no assets are given, use productIdentifier to get S3 path for download
|
|
92
|
+
s3_url = "s3:/" + product.properties["productIdentifier"]
|
|
93
|
+
bucket_names_and_prefixes = [
|
|
94
|
+
self.get_product_bucket_name_and_prefix(product, s3_url)
|
|
95
|
+
]
|
|
96
|
+
return bucket_names_and_prefixes
|