|
19 | 19 | import ast |
20 | 20 | import logging as py_logging |
21 | 21 | import shutil |
| 22 | +import types |
22 | 23 | from datetime import date, datetime |
23 | 24 |
|
24 | 25 | from dateutil.parser import isoparse |
|
40 | 41 | ) |
41 | 42 | from eodag.utils.notebook import NotebookWidgets |
42 | 43 | from sentinelsat import SentinelAPI, ServerError |
43 | | -from tenacity import retry, retry_if_not_result, stop_after_delay |
44 | 44 |
|
45 | 45 | logger = py_logging.getLogger("eodag.plugins.apis.sentinelsat") |
46 | 46 |
|
@@ -261,7 +261,8 @@ def download( |
261 | 261 | :param dict kwargs: ``outputs_prefix`` (str), ``extract`` (bool) can be provided |
262 | 262 | here and will override any other values defined in a |
263 | 263 | configuration file or with environment variables. |
264 | | - ``checksum`` can be passed to ``sentinelsat.download_all`` directly |
| 264 | + ``checksum``, ``max_attempts``, ``n_concurrent_dl``, ``fail_fast`` |
| 265 | + and ``node_filter`` can be passed to ``sentinelsat.download_all`` directly |
265 | 266 | which is used under the hood. |
266 | 267 | :returns: The absolute path to the downloaded product in the local filesystem |
267 | 268 | :rtype: str |
@@ -307,9 +308,8 @@ def download_all( |
307 | 308 | :param dict kwargs: ``outputs_prefix`` (str), ``extract`` (bool) can be provided |
308 | 309 | here and will override any other values defined in a |
309 | 310 | configuration file or with environment variables. |
310 | | - ``checksum``, ``max_attempts``, ``n_concurrent_dl`` and |
311 | | - ``lta_retry_delay`` can be passed to ``sentinelsat.download_all`` |
312 | | - directly. |
| 311 | + ``checksum``, ``max_attempts``, ``n_concurrent_dl``, ``fail_fast`` |
| 312 | + and ``node_filter`` can be passed to ``sentinelsat.download_all`` directly. |
313 | 313 | :return: A collection of absolute paths to the downloaded products |
314 | 314 | :rtype: list |
315 | 315 | """ |
@@ -338,80 +338,63 @@ def download_all( |
338 | 338 | k: kwargs.pop(k) |
339 | 339 | for k in list(kwargs) |
340 | 340 | if k |
341 | | - in ["checksum", "max_attempts", "n_concurrent_dl", "lta_retry_delay"] |
| 341 | + in [ |
| 342 | + "max_attempts", |
| 343 | + "checksum", |
| 344 | + "n_concurrent_dl", |
| 345 | + "fail_fast", |
| 346 | + "nodefilter", |
| 347 | + ] |
342 | 348 | } |
343 | | - # Download all products |
344 | | - # Three dicts returned by sentinelsat.download_all, their key is the uuid: |
345 | | - # 1. Product information from get_product_info() as well as the path on disk. |
346 | | - # 2. Product information for products successfully triggered for retrieval |
347 | | - # from the long term archive but not downloaded. |
348 | | - # 3. Product information of products where either downloading or triggering failed |
349 | 349 |
|
350 | | - # another output for notebooks |
351 | | - nb_info = NotebookWidgets() |
352 | | - |
353 | | - def _are_products_missing(results): |
354 | | - """Check if some products have not been downloaded yet, for ``tenacity`` usage.""" |
355 | | - success, ordered, failed = results |
356 | | - if len(ordered) > 0 or len(failed) > 0: |
357 | | - return False |
| 350 | + if progress_callback is None: |
| 351 | + create_sentinelsat_pbar = ProgressCallback |
| 352 | + else: |
| 353 | + create_sentinelsat_pbar = progress_callback.copy |
| 354 | + |
| 355 | + # Use eodag progress bars and avoid duplicates |
| 356 | + self.api.pbar_count = 0 |
| 357 | + |
| 358 | + def _tqdm(self, **kwargs): |
| 359 | + """sentinelsat progressbar wrapper""" |
| 360 | + if self.api.pbar_count == 0 and progress_callback is not None: |
| 361 | + pbar = progress_callback |
| 362 | + for k in kwargs.keys(): |
| 363 | + setattr(pbar, k, kwargs[k]) |
| 364 | + pbar.refresh() |
358 | 365 | else: |
359 | | - return True |
360 | | - |
361 | | - def _wait_callback(retry_state): |
362 | | - """Callback executed after each download attempt failure, for ``tenacity`` usage. |
| 366 | + pbar = create_sentinelsat_pbar(**kwargs) |
| 367 | + self.api.pbar_count += 1 |
| 368 | + return pbar |
363 | 369 |
|
364 | | - :returns: wait time before next try (in seconds) |
365 | | - """ |
366 | | - retry_info = ( |
367 | | - "[Retry #%s] Waiting %ss until next download try (retry every %s' for %s')" |
368 | | - % (retry_state.attempt_number, wait * 60, wait, timeout) |
369 | | - ) |
370 | | - logger.info(retry_info) |
371 | | - nb_info.display_html(retry_info) |
| 370 | + self.api.downloader._tqdm = types.MethodType(_tqdm, self.api.downloader) |
372 | 371 |
|
373 | | - return wait * 60 |
| 372 | + # another output for notebooks |
| 373 | + nb_info = NotebookWidgets() |
374 | 374 |
|
375 | | - def _return_last_value(retry_state): |
376 | | - """Return the result of the last call attempt, for ``tenacity`` usage.""" |
377 | | - timeout_info = ( |
378 | | - "[Retry #%s] %s' timeout reached when trying to download" |
379 | | - % (retry_state.attempt_number, timeout) |
380 | | - ) |
381 | | - logger.info(timeout_info) |
382 | | - nb_info.display_html(timeout_info) |
383 | | - |
384 | | - success, ordered, failed = retry_state.outcome.result() |
385 | | - if len(ordered) > 0: |
386 | | - logger.warning( |
387 | | - "%s products have been ordered but could not be downloaded: %s" |
388 | | - % (len(ordered), ", ".join(ordered.keys())) |
389 | | - ) |
390 | | - if len(failed) > 0: |
391 | | - logger.warning( |
392 | | - "%s products have failed and could not be downloaded: %s" |
393 | | - % (len(failed), ", ".join(failed.keys())) |
394 | | - ) |
395 | | - return success, ordered, failed |
396 | | - |
397 | | - @retry( |
398 | | - stop=stop_after_delay(timeout * 60), |
399 | | - wait=_wait_callback, |
400 | | - retry_error_callback=_return_last_value, |
401 | | - retry=retry_if_not_result(_are_products_missing), |
| 375 | + retry_info = ( |
| 376 | + "Will try downloading every %s' for %s' if product is not ONLINE" |
| 377 | + % (wait, timeout) |
402 | 378 | ) |
403 | | - def _try_download_all( |
404 | | - uuids_to_download, outputs_prefix, **sentinelsat_kwargs |
405 | | - ): |
406 | | - """Download attempts, for ``tenacity`` usage.""" |
407 | | - return self.api.download_all( |
408 | | - uuids_to_download, |
409 | | - directory_path=outputs_prefix, |
410 | | - **sentinelsat_kwargs |
411 | | - ) |
| 379 | + logger.info(retry_info) |
| 380 | + logger.info( |
| 381 | + "Once ordered, OFFLINE/LTA product download retries may not be logged" |
| 382 | + ) |
| 383 | + nb_info.display_html(retry_info) |
| 384 | + |
| 385 | + self.api.lta_timeout = timeout * 60 |
412 | 386 |
|
413 | | - success, _, _ = _try_download_all( |
414 | | - uuids_to_download, outputs_prefix=outputs_prefix, **sentinelsat_kwargs |
| 387 | + # Download all products |
| 388 | + # Three dicts returned by sentinelsat.download_all, their key is the uuid: |
| 389 | + # 1. Product information from get_product_info() as well as the path on disk. |
| 390 | + # 2. Product information for products successfully triggered for retrieval |
| 391 | + # from the long term archive but not downloaded. |
| 392 | + # 3. Product information of products where either downloading or triggering failed |
| 393 | + success, _, _ = self.api.download_all( |
| 394 | + uuids_to_download, |
| 395 | + directory_path=outputs_prefix, |
| 396 | + lta_retry_delay=wait * 60, |
| 397 | + **sentinelsat_kwargs |
415 | 398 | ) |
416 | 399 |
|
417 | 400 | for pm in product_managers: |
|
0 commit comments