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.
Files changed (75) hide show
  1. eodag/__init__.py +6 -1
  2. eodag/api/collection.py +353 -0
  3. eodag/api/core.py +606 -641
  4. eodag/api/product/__init__.py +3 -3
  5. eodag/api/product/_product.py +74 -56
  6. eodag/api/product/drivers/__init__.py +4 -46
  7. eodag/api/product/drivers/base.py +0 -28
  8. eodag/api/product/metadata_mapping.py +178 -216
  9. eodag/api/search_result.py +156 -15
  10. eodag/cli.py +83 -403
  11. eodag/config.py +81 -51
  12. eodag/plugins/apis/base.py +2 -2
  13. eodag/plugins/apis/ecmwf.py +36 -25
  14. eodag/plugins/apis/usgs.py +55 -40
  15. eodag/plugins/authentication/base.py +1 -3
  16. eodag/plugins/crunch/filter_date.py +3 -3
  17. eodag/plugins/crunch/filter_latest_intersect.py +2 -2
  18. eodag/plugins/crunch/filter_latest_tpl_name.py +1 -1
  19. eodag/plugins/download/aws.py +46 -42
  20. eodag/plugins/download/base.py +13 -14
  21. eodag/plugins/download/http.py +65 -65
  22. eodag/plugins/manager.py +28 -29
  23. eodag/plugins/search/__init__.py +6 -4
  24. eodag/plugins/search/base.py +131 -80
  25. eodag/plugins/search/build_search_result.py +245 -173
  26. eodag/plugins/search/cop_marine.py +87 -56
  27. eodag/plugins/search/csw.py +47 -37
  28. eodag/plugins/search/qssearch.py +653 -429
  29. eodag/plugins/search/stac_list_assets.py +1 -1
  30. eodag/plugins/search/static_stac_search.py +43 -44
  31. eodag/resources/{product_types.yml → collections.yml} +2594 -2453
  32. eodag/resources/ext_collections.json +1 -1
  33. eodag/resources/ext_product_types.json +1 -1
  34. eodag/resources/providers.yml +2706 -2733
  35. eodag/resources/stac_provider.yml +50 -92
  36. eodag/resources/user_conf_template.yml +9 -0
  37. eodag/types/__init__.py +2 -0
  38. eodag/types/queryables.py +70 -91
  39. eodag/types/search_args.py +1 -1
  40. eodag/utils/__init__.py +97 -21
  41. eodag/utils/dates.py +0 -12
  42. eodag/utils/exceptions.py +6 -6
  43. eodag/utils/free_text_search.py +3 -3
  44. eodag/utils/repr.py +2 -0
  45. {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/METADATA +13 -99
  46. eodag-4.0.0a2.dist-info/RECORD +93 -0
  47. {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/entry_points.txt +0 -4
  48. eodag/plugins/authentication/oauth.py +0 -60
  49. eodag/plugins/download/creodias_s3.py +0 -71
  50. eodag/plugins/download/s3rest.py +0 -351
  51. eodag/plugins/search/data_request_search.py +0 -565
  52. eodag/resources/stac.yml +0 -294
  53. eodag/resources/stac_api.yml +0 -2105
  54. eodag/rest/__init__.py +0 -24
  55. eodag/rest/cache.py +0 -70
  56. eodag/rest/config.py +0 -67
  57. eodag/rest/constants.py +0 -26
  58. eodag/rest/core.py +0 -764
  59. eodag/rest/errors.py +0 -210
  60. eodag/rest/server.py +0 -604
  61. eodag/rest/server.wsgi +0 -6
  62. eodag/rest/stac.py +0 -1032
  63. eodag/rest/templates/README +0 -1
  64. eodag/rest/types/__init__.py +0 -18
  65. eodag/rest/types/collections_search.py +0 -44
  66. eodag/rest/types/eodag_search.py +0 -386
  67. eodag/rest/types/queryables.py +0 -174
  68. eodag/rest/types/stac_search.py +0 -272
  69. eodag/rest/utils/__init__.py +0 -207
  70. eodag/rest/utils/cql_evaluate.py +0 -119
  71. eodag/rest/utils/rfc3339.py +0 -64
  72. eodag-3.10.1.dist-info/RECORD +0 -116
  73. {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/WHEEL +0 -0
  74. {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/licenses/LICENSE +0 -0
  75. {eodag-3.10.1.dist-info → eodag-4.0.0a2.dist-info}/top_level.txt +0 -0
@@ -53,7 +53,6 @@ if TYPE_CHECKING:
53
53
  from eodag.api.product import EOProduct
54
54
  from eodag.api.search_result import SearchResult
55
55
  from eodag.config import PluginConfig
56
- from eodag.types import S3SessionKwargs
57
56
  from eodag.types.download_args import DownloadConf
58
57
  from eodag.utils import DownloadedCallback, Unpack
59
58
 
@@ -84,8 +83,8 @@ class Download(PluginTopic):
84
83
  (e.g. ``file:///tmp/product_folder`` on Linux or
85
84
  ``file:///C:/Users/username/AppData/Local/Temp`` on Windows)
86
85
  - save a *record* file in the directory ``{output_dir}/.downloaded`` whose name
87
- is built on the MD5 hash of the product's ``product_type`` and ``properties['id']``
88
- attributes (``hashlib.md5((product.product_type+"-"+product.properties['id']).encode("utf-8")).hexdigest()``)
86
+ is built on the MD5 hash of the product's ``collection`` and ``properties['id']``
87
+ attributes (``hashlib.md5((product.collection+"-"+product.properties['id']).encode("utf-8")).hexdigest()``)
89
88
  and whose content is the product's ``remote_location`` attribute itself.
90
89
  - not try to download a product whose ``location`` attribute already points to an
91
90
  existing file/directory
@@ -104,7 +103,7 @@ class Download(PluginTopic):
104
103
  def download(
105
104
  self,
106
105
  product: EOProduct,
107
- auth: Optional[Union[AuthBase, S3SessionKwargs, S3ServiceResource]] = None,
106
+ auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
108
107
  progress_callback: Optional[ProgressCallback] = None,
109
108
  wait: float = DEFAULT_DOWNLOAD_WAIT,
110
109
  timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
@@ -134,7 +133,7 @@ class Download(PluginTopic):
134
133
  def _stream_download_dict(
135
134
  self,
136
135
  product: EOProduct,
137
- auth: Optional[Union[AuthBase, S3SessionKwargs, S3ServiceResource]] = None,
136
+ auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
138
137
  byte_range: tuple[Optional[int], Optional[int]] = (None, None),
139
138
  compress: Literal["zip", "raw", "auto"] = "auto",
140
139
  wait: float = DEFAULT_DOWNLOAD_WAIT,
@@ -279,14 +278,14 @@ class Download(PluginTopic):
279
278
  def generate_record_hash(self, product: EOProduct) -> str:
280
279
  """Generate the record hash of the given product.
281
280
 
282
- The MD5 hash is built from the product's ``product_type`` and ``properties['id']`` attributes
283
- (``hashlib.md5((product.product_type+"-"+product.properties['id']).encode("utf-8")).hexdigest()``)
281
+ The MD5 hash is built from the product's ``collection`` and ``properties['id']`` attributes
282
+ (``hashlib.md5((product.collection+"-"+product.properties['id']).encode("utf-8")).hexdigest()``)
284
283
 
285
284
  :param product: The product to calculate the record hash
286
285
  :returns: The MD5 hash
287
286
  """
288
- # In some unit tests, `product.product_type` is `None` and `product.properties["id"]` is `ìnt`
289
- product_hash = str(product.product_type) + "-" + str(product.properties["id"])
287
+ # In some unit tests, `product.collection` is `None` and `product.properties["id"]` is `ìnt`
288
+ product_hash = str(product.collection) + "-" + str(product.properties["id"])
290
289
  return hashlib.md5(product_hash.encode("utf-8")).hexdigest()
291
290
 
292
291
  def _resolve_archive_depth(self, product_path: str) -> str:
@@ -445,7 +444,7 @@ class Download(PluginTopic):
445
444
  def download_all(
446
445
  self,
447
446
  products: SearchResult,
448
- auth: Optional[Union[AuthBase, S3SessionKwargs]] = None,
447
+ auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
449
448
  downloaded_callback: Optional[DownloadedCallback] = None,
450
449
  progress_callback: Optional[ProgressCallback] = None,
451
450
  wait: float = DEFAULT_DOWNLOAD_WAIT,
@@ -620,7 +619,7 @@ class Download(PluginTopic):
620
619
  not_available_info = str(e)
621
620
  else:
622
621
  if (
623
- product.properties.get("storageStatus", ONLINE_STATUS)
622
+ product.properties.get("order:status", ONLINE_STATUS)
624
623
  == ONLINE_STATUS
625
624
  ) or timeout <= 0:
626
625
  return download
@@ -676,11 +675,11 @@ class Download(PluginTopic):
676
675
  nb_info.display_html(retry_info)
677
676
  sleep(wait_seconds)
678
677
  elif datetime_now >= stop_time and timeout > 0:
679
- if "storageStatus" not in product.properties:
680
- product.properties["storageStatus"] = "N/A status"
678
+ if "order:status" not in product.properties:
679
+ product.properties["order:status"] = "N/A status"
681
680
  logger.info(not_available_info)
682
681
  raise NotAvailableError(
683
- f"{product.properties['title']} is not available ({product.properties['storageStatus']})"
682
+ f"{product.properties['title']} is not available ({product.properties['order:status']})"
684
683
  f" and order was not successfull, timeout reached"
685
684
  )
686
685
  elif datetime_now >= stop_time:
@@ -92,7 +92,6 @@ if TYPE_CHECKING:
92
92
  from eodag.api.product import Asset, EOProduct # type: ignore
93
93
  from eodag.api.search_result import SearchResult
94
94
  from eodag.config import PluginConfig
95
- from eodag.types import S3SessionKwargs
96
95
  from eodag.types.download_args import DownloadConf
97
96
  from eodag.utils import DownloadedCallback, Unpack
98
97
 
@@ -119,7 +118,8 @@ class HTTPDownload(Download):
119
118
  default: ``1``
120
119
  * :attr:`~eodag.config.PluginConfig.flatten_top_dirs` (``bool``): if the directory structure should be
121
120
  flattened; default: ``True``
122
- * :attr:`~eodag.config.PluginConfig.ignore_assets` (``bool``): ignore assets and download using downloadLink;
121
+ * :attr:`~eodag.config.PluginConfig.ignore_assets` (``bool``): ignore assets and download using
122
+ eodag:download_link;
123
123
  default: ``False``
124
124
  * :attr:`~eodag.config.PluginConfig.timeout` (``int``): time to wait until request timeout in seconds;
125
125
  default: ``5``
@@ -128,8 +128,8 @@ class HTTPDownload(Download):
128
128
  * :attr:`~eodag.config.PluginConfig.no_auth_download` (``bool``): if the download should be done without
129
129
  authentication; default: ``True``
130
130
  * :attr:`~eodag.config.PluginConfig.order_enabled` (``bool``): if the product has to be ordered to download it;
131
- if this parameter is set to true, a mapping for the orderLink has to be added to the metadata mapping of
132
- the search plugin used for the provider; default: ``False``
131
+ if this parameter is set to true, a mapping for ``eodag:order_link`` has to be added to the metadata mapping
132
+ of the search plugin used for the provider; default: ``False``
133
133
  * :attr:`~eodag.config.PluginConfig.order_method` (``str``): HTTP request method for the order request (``GET``
134
134
  or ``POST``); default: ``GET``
135
135
  * :attr:`~eodag.config.PluginConfig.order_headers` (``[dict[str, str]]``): headers to be added to the order
@@ -140,9 +140,9 @@ class HTTPDownload(Download):
140
140
  * :attr:`~eodag.config.PluginConfig.order_status` (:class:`~eodag.config.PluginConfig.OrderStatus`):
141
141
  configuration to handle the order status; contains information which method to use, how the response data is
142
142
  interpreted, which status corresponds to success, ordered and error and what should be done on success.
143
- * :attr:`~eodag.config.PluginConfig.products` (``dict[str, dict[str, Any]``): product type specific config; the
144
- keys are the product types, the values are dictionaries which can contain the key
145
- :attr:`~eodag.config.PluginConfig.extract` to overwrite the provider config for a specific product type
143
+ * :attr:`~eodag.config.PluginConfig.products` (``dict[str, dict[str, Any]``): collection specific config; the
144
+ keys are the collections, the values are dictionaries which can contain the key
145
+ :attr:`~eodag.config.PluginConfig.extract` to overwrite the provider config for a specific collection
146
146
 
147
147
  """
148
148
 
@@ -158,12 +158,12 @@ class HTTPDownload(Download):
158
158
 
159
159
  """Send product order request.
160
160
 
161
- It will be executed once before the download retry loop, if the product is OFFLINE
162
- and has `orderLink` in its properties.
161
+ It will be executed once before the download retry loop, if the product is orderable
162
+ and has ``eodag:order_link`` in its properties.
163
163
  Product ordering can be configured using the following download plugin parameters:
164
164
 
165
165
  - :attr:`~eodag.config.PluginConfig.order_enabled`: Wether order is enabled or not (may not use this method
166
- if no `orderLink` exists)
166
+ if no ``eodag:order_link`` exists)
167
167
 
168
168
  - :attr:`~eodag.config.PluginConfig.order_method`: (optional) HTTP request method, GET (default) or POST
169
169
 
@@ -174,14 +174,14 @@ class HTTPDownload(Download):
174
174
 
175
175
  Product properties used for order:
176
176
 
177
- - **orderLink**: order request URL
177
+ - **eodag:order_link**: order request URL
178
178
 
179
179
  :param product: The EO product to order
180
180
  :param auth: (optional) authenticated object
181
181
  :param kwargs: download additional kwargs
182
182
  :returns: the returned json status response
183
183
  """
184
- product.properties["storageStatus"] = STAGING_STATUS
184
+ product.properties["order:status"] = STAGING_STATUS
185
185
 
186
186
  order_method = getattr(self.config, "order_method", "GET").upper()
187
187
  ssl_verify = getattr(self.config, "ssl_verify", True)
@@ -192,7 +192,7 @@ class HTTPDownload(Download):
192
192
  order_kwargs: OrderKwargs = {}
193
193
  if order_method == "POST":
194
194
  # separate url & parameters
195
- parts = urlparse(str(product.properties["orderLink"]))
195
+ parts = urlparse(str(product.properties["eodag:order_link"]))
196
196
  query_dict = {}
197
197
  # `parts.query` may be a JSON with query strings as one of values. If `parse_qs` is executed as first step,
198
198
  # the resulting `query_dict` would be erroneous.
@@ -205,7 +205,7 @@ class HTTPDownload(Download):
205
205
  if query_dict:
206
206
  order_kwargs["json"] = query_dict
207
207
  else:
208
- order_url = product.properties["orderLink"]
208
+ order_url = product.properties["eodag:order_link"]
209
209
  order_kwargs = {}
210
210
 
211
211
  headers = {**getattr(self.config, "order_headers", {}), **USER_AGENT}
@@ -224,7 +224,7 @@ class HTTPDownload(Download):
224
224
  response.raise_for_status()
225
225
  ordered_message = response.text
226
226
  logger.debug(ordered_message)
227
- product.properties["storageStatus"] = STAGING_STATUS
227
+ product.properties["order:status"] = STAGING_STATUS
228
228
  except RequestException as e:
229
229
  self._check_auth_exception(e)
230
230
  msg = f"{product.properties['title']} could not be ordered"
@@ -269,16 +269,16 @@ class HTTPDownload(Download):
269
269
  # the job id becomes the product id for EcmwfSearch products
270
270
  if "ORDERABLE" in product.properties.get("id", ""):
271
271
  product.properties["id"] = product.properties.get(
272
- "orderId", product.properties["id"]
272
+ "eodag:order_id", product.properties["id"]
273
273
  )
274
274
  product.properties["title"] = (
275
- (product.product_type or product.provider).upper()
275
+ (product.collection or product.provider).upper()
276
276
  + "_"
277
277
  + product.properties["id"]
278
278
  )
279
- if "downloadLink" in product.properties:
279
+ if "eodag:download_link" in product.properties:
280
280
  product.remote_location = product.location = product.properties[
281
- "downloadLink"
281
+ "eodag:download_link"
282
282
  ]
283
283
  logger.debug(f"Product location updated to {product.location}")
284
284
 
@@ -298,7 +298,7 @@ class HTTPDownload(Download):
298
298
 
299
299
  Product properties used for order status:
300
300
 
301
- - **orderStatusLink**: order status request URL
301
+ - **eodag:status_link**: order status request URL
302
302
 
303
303
  :param product: The ordered EO product
304
304
  :param auth: (optional) authenticated object
@@ -355,14 +355,14 @@ class HTTPDownload(Download):
355
355
 
356
356
  if status_request_method == "POST":
357
357
  # separate url & parameters
358
- parts = urlparse(str(product.properties["orderStatusLink"]))
358
+ parts = urlparse(str(product.properties["eodag:status_link"]))
359
359
  status_url = parts._replace(query="").geturl()
360
360
  query_dict = parse_qs(parts.query)
361
361
  if not query_dict and parts.query:
362
362
  query_dict = geojson.loads(parts.query)
363
363
  json_data = query_dict if query_dict else None
364
364
  else:
365
- status_url = product.properties["orderStatusLink"]
365
+ status_url = product.properties["eodag:status_link"]
366
366
  json_data = None
367
367
 
368
368
  # check header for success before full status request
@@ -443,8 +443,8 @@ class HTTPDownload(Download):
443
443
  )
444
444
 
445
445
  # display progress percentage
446
- if "percent" in status_dict:
447
- status_percent = str(status_dict["percent"])
446
+ if "eodag:order_percent" in status_dict:
447
+ status_percent = str(status_dict["eodag:order_percent"])
448
448
  if status_percent.isdigit():
449
449
  status_percent += "%"
450
450
  logger.info(
@@ -455,9 +455,11 @@ class HTTPDownload(Download):
455
455
  {k: v for k, v in status_dict.items() if v != NOT_AVAILABLE}
456
456
  )
457
457
 
458
- product.properties["orderStatus"] = status_dict.get("status")
458
+ product.properties["eodag:order_status"] = status_dict.get(
459
+ "eodag:order_status"
460
+ )
459
461
 
460
- status_message = status_dict.get("message")
462
+ status_message = status_dict.get("eodag:order_message")
461
463
 
462
464
  # handle status error
463
465
  errors: dict[str, Any] = status_config.get("error", {})
@@ -466,16 +468,18 @@ class HTTPDownload(Download):
466
468
  f"Provider {product.provider} returned: {status_dict.get('error_message', status_message)}"
467
469
  )
468
470
 
469
- product.properties["storageStatus"] = STAGING_STATUS
471
+ product.properties["order:status"] = STAGING_STATUS
470
472
 
471
- success_status: dict[str, Any] = status_config.get("success", {}).get("status")
473
+ success_status: dict[str, Any] = status_config.get("success", {}).get(
474
+ "eodag:order_status"
475
+ )
472
476
  # if not success
473
- if (success_status and success_status != status_dict.get("status")) or (
474
- success_code and success_code != response.status_code
475
- ):
477
+ if (
478
+ success_status and success_status != status_dict.get("eodag:order_status")
479
+ ) or (success_code and success_code != response.status_code):
476
480
  return None
477
481
 
478
- product.properties["storageStatus"] = ONLINE_STATUS
482
+ product.properties["order:status"] = ONLINE_STATUS
479
483
 
480
484
  if not config_on_success:
481
485
  # Nothing left to do
@@ -483,9 +487,13 @@ class HTTPDownload(Download):
483
487
 
484
488
  # need search on success ?
485
489
  if config_on_success.get("need_search"):
486
- logger.debug(f"Search for new location: {product.properties['searchLink']}")
490
+ logger.debug(
491
+ f"Search for new location: {product.properties['eodag:search_link']}"
492
+ )
487
493
  try:
488
- response = _request(product.properties["searchLink"], timeout=timeout)
494
+ response = _request(
495
+ product.properties["eodag:search_link"], timeout=timeout
496
+ )
489
497
  except RequestException as e:
490
498
  logger.warning(
491
499
  "%s order status could not be checked, request returned %s",
@@ -503,11 +511,7 @@ class HTTPDownload(Download):
503
511
 
504
512
  on_success_mm_querypath = (
505
513
  # append product.properties as input for on success response parsing
506
- mtd_cfg_as_conversion_and_querypath(
507
- dict(
508
- {k: str(v) for k, v in product.properties.items()}, **on_success_mm
509
- ),
510
- )
514
+ mtd_cfg_as_conversion_and_querypath(on_success_mm)
511
515
  if on_success_mm
512
516
  else {}
513
517
  )
@@ -530,7 +534,7 @@ class HTTPDownload(Download):
530
534
  if len(results) != 1:
531
535
  raise DownloadError(
532
536
  "Could not get a single result after order success for "
533
- f"{product.properties['searchLink']} request. "
537
+ f"{product.properties['eodag:search_link']} request. "
534
538
  f"Please search and download {product} again"
535
539
  )
536
540
  assert isinstance(results, list), "results must be in a list"
@@ -581,9 +585,9 @@ class HTTPDownload(Download):
581
585
 
582
586
  # update product
583
587
  product.properties.update(properties_update)
584
- if "downloadLink" in properties_update:
588
+ if "eodag:download_link" in properties_update:
585
589
  product.location = product.remote_location = product.properties[
586
- "downloadLink"
590
+ "eodag:download_link"
587
591
  ]
588
592
  else:
589
593
  self.order_response_process(response, product)
@@ -591,7 +595,7 @@ class HTTPDownload(Download):
591
595
  def download(
592
596
  self,
593
597
  product: EOProduct,
594
- auth: Optional[Union[AuthBase, S3SessionKwargs, S3ServiceResource]] = None,
598
+ auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
595
599
  progress_callback: Optional[ProgressCallback] = None,
596
600
  wait: float = DEFAULT_DOWNLOAD_WAIT,
597
601
  timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
@@ -677,7 +681,7 @@ class HTTPDownload(Download):
677
681
  raise DownloadError(f"product {product.properties['id']} is empty")
678
682
  else:
679
683
  # make sure storage status is online
680
- product.properties["storageStatus"] = ONLINE_STATUS
684
+ product.properties["order:status"] = ONLINE_STATUS
681
685
 
682
686
  return path
683
687
  else:
@@ -720,14 +724,14 @@ class HTTPDownload(Download):
720
724
  stream_size = int(self.stream.headers.get("content-length", 0))
721
725
  if (
722
726
  stream_size == 0
723
- and "storageStatus" in product.properties
724
- and product.properties["storageStatus"] != ONLINE_STATUS
727
+ and "order:status" in product.properties
728
+ and product.properties["order:status"] != ONLINE_STATUS
725
729
  ):
726
730
  raise NotAvailableError(
727
731
  "%s(initially %s) ordered, got: %s"
728
732
  % (
729
733
  product.properties["title"],
730
- product.properties["storageStatus"],
734
+ product.properties["order:status"],
731
735
  self.stream.reason,
732
736
  )
733
737
  )
@@ -755,7 +759,7 @@ class HTTPDownload(Download):
755
759
  def _stream_download_dict(
756
760
  self,
757
761
  product: EOProduct,
758
- auth: Optional[Union[AuthBase, S3SessionKwargs, S3ServiceResource]] = None,
762
+ auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
759
763
  byte_range: tuple[Optional[int], Optional[int]] = (None, None),
760
764
  compress: Literal["zip", "raw", "auto"] = "auto",
761
765
  wait: float = DEFAULT_DOWNLOAD_WAIT,
@@ -882,7 +886,7 @@ class HTTPDownload(Download):
882
886
  e.response.text.strip() if e is not None and e.response is not None else ""
883
887
  )
884
888
  # product not available
885
- if product.properties.get("storageStatus", ONLINE_STATUS) != ONLINE_STATUS:
889
+ if product.properties.get("order:status", ONLINE_STATUS) != ONLINE_STATUS:
886
890
  msg = (
887
891
  ordered_message
888
892
  if ordered_message and not response_text
@@ -893,7 +897,7 @@ class HTTPDownload(Download):
893
897
  "%s(initially %s) requested, returned: %s"
894
898
  % (
895
899
  product.properties["title"],
896
- product.properties["storageStatus"],
900
+ product.properties["order:status"],
897
901
  msg,
898
902
  )
899
903
  )
@@ -915,22 +919,22 @@ class HTTPDownload(Download):
915
919
  auth: Optional[AuthBase],
916
920
  ) -> None:
917
921
  if (
918
- "orderLink" in product.properties
919
- and product.properties.get("storageStatus") == OFFLINE_STATUS
920
- and not product.properties.get("orderStatus")
922
+ "eodag:order_link" in product.properties
923
+ and product.properties.get("order:status") == OFFLINE_STATUS
924
+ and not product.properties.get("eodag:order_status")
921
925
  ):
922
926
  self._order(product=product, auth=auth)
923
927
 
924
928
  if (
925
- product.properties.get("orderStatusLink")
926
- and product.properties.get("storageStatus") != ONLINE_STATUS
929
+ product.properties.get("eodag:status_link")
930
+ and product.properties.get("order:status") != ONLINE_STATUS
927
931
  ):
928
932
  self._order_status(product=product, auth=auth)
929
933
 
930
934
  def order(
931
935
  self,
932
936
  product: EOProduct,
933
- auth: Optional[Union[AuthBase, S3SessionKwargs]] = None,
937
+ auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
934
938
  wait: float = DEFAULT_DOWNLOAD_WAIT,
935
939
  timeout: float = DEFAULT_DOWNLOAD_TIMEOUT,
936
940
  ) -> None:
@@ -982,7 +986,7 @@ class HTTPDownload(Download):
982
986
  )
983
987
 
984
988
  req_method = (
985
- product.properties.get("downloadMethod", "").lower()
989
+ product.properties.get("eodag:download_method", "").lower()
986
990
  or getattr(self.config, "method", "GET").lower()
987
991
  )
988
992
  url = product.remote_location
@@ -1041,7 +1045,7 @@ class HTTPDownload(Download):
1041
1045
  ).get(
1042
1046
  "http_code"
1043
1047
  ):
1044
- product.properties["storageStatus"] = "ORDERED"
1048
+ product.properties["order:status"] = "ORDERED"
1045
1049
  self._process_exception(None, product, ordered_message)
1046
1050
  stream_size = self._check_stream_size(product) or None
1047
1051
 
@@ -1096,9 +1100,7 @@ class HTTPDownload(Download):
1096
1100
  assets_common_subdir = os.path.commonpath(asset_rel_paths_list)
1097
1101
 
1098
1102
  # product conf overrides provider conf for "flatten_top_dirs"
1099
- product_conf = getattr(self.config, "products", {}).get(
1100
- product.product_type, {}
1101
- )
1103
+ product_conf = getattr(self.config, "products", {}).get(product.collection, {})
1102
1104
  flatten_top_dirs = product_conf.get(
1103
1105
  "flatten_top_dirs", getattr(self.config, "flatten_top_dirs", True)
1104
1106
  )
@@ -1246,9 +1248,7 @@ class HTTPDownload(Download):
1246
1248
  os.makedirs(fs_dir_path)
1247
1249
 
1248
1250
  # product conf overrides provider conf for "flatten_top_dirs"
1249
- product_conf = getattr(self.config, "products", {}).get(
1250
- product.product_type, {}
1251
- )
1251
+ product_conf = getattr(self.config, "products", {}).get(product.collection, {})
1252
1252
  flatten_top_dirs = product_conf.get(
1253
1253
  "flatten_top_dirs", getattr(self.config, "flatten_top_dirs", True)
1254
1254
  )
@@ -1413,7 +1413,7 @@ class HTTPDownload(Download):
1413
1413
  def download_all(
1414
1414
  self,
1415
1415
  products: SearchResult,
1416
- auth: Optional[Union[AuthBase, S3SessionKwargs]] = None,
1416
+ auth: Optional[Union[AuthBase, S3ServiceResource]] = None,
1417
1417
  downloaded_callback: Optional[DownloadedCallback] = None,
1418
1418
  progress_callback: Optional[ProgressCallback] = None,
1419
1419
  wait: float = DEFAULT_DOWNLOAD_WAIT,
eodag/plugins/manager.py CHANGED
@@ -36,7 +36,7 @@ from eodag.plugins.base import EODAGPluginMount
36
36
  from eodag.plugins.crunch.base import Crunch
37
37
  from eodag.plugins.download.base import Download
38
38
  from eodag.plugins.search.base import Search
39
- from eodag.utils import GENERIC_PRODUCT_TYPE, deepcopy, dict_md5sum
39
+ from eodag.utils import GENERIC_COLLECTION, deepcopy, dict_md5sum
40
40
  from eodag.utils.exceptions import (
41
41
  AuthenticationError,
42
42
  MisconfiguredError,
@@ -50,7 +50,6 @@ if TYPE_CHECKING:
50
50
  from eodag.api.product import EOProduct
51
51
  from eodag.config import PluginConfig, ProviderConfig
52
52
  from eodag.plugins.base import PluginTopic
53
- from eodag.types import S3SessionKwargs
54
53
 
55
54
 
56
55
  logger = logging.getLogger("eodag.plugins.manager")
@@ -74,7 +73,7 @@ class PluginManager:
74
73
 
75
74
  supported_topics = set(PLUGINS_TOPICS_KEYS)
76
75
 
77
- product_type_to_provider_config_map: dict[str, list[ProviderConfig]]
76
+ collection_to_provider_config_map: dict[str, list[ProviderConfig]]
78
77
 
79
78
  skipped_plugins: list[str]
80
79
 
@@ -134,12 +133,12 @@ class PluginManager:
134
133
  if providers_config is not None:
135
134
  self.providers_config = providers_config
136
135
 
137
- self.build_product_type_to_provider_config_map()
136
+ self.build_collection_to_provider_config_map()
138
137
  self._built_plugins_cache: dict[tuple[str, str, str], Any] = {}
139
138
 
140
- def build_product_type_to_provider_config_map(self) -> None:
141
- """Build mapping conf between product types and providers"""
142
- self.product_type_to_provider_config_map = {}
139
+ def build_collection_to_provider_config_map(self) -> None:
140
+ """Build mapping conf between collections and providers"""
141
+ self.collection_to_provider_config_map = {}
143
142
  for provider in list(self.providers_config):
144
143
  provider_config = self.providers_config[provider]
145
144
  if not hasattr(provider_config, "products") or not provider_config.products:
@@ -154,26 +153,26 @@ class PluginManager:
154
153
  if getattr(provider_config, "priority", None) is None:
155
154
  self.providers_config[provider].priority = provider_config.priority = 0
156
155
 
157
- for product_type in provider_config.products:
158
- product_type_providers = (
159
- self.product_type_to_provider_config_map.setdefault( # noqa
160
- product_type, []
156
+ for collection in provider_config.products:
157
+ collection_providers = (
158
+ self.collection_to_provider_config_map.setdefault( # noqa
159
+ collection, []
161
160
  )
162
161
  )
163
- product_type_providers.append(provider_config)
164
- product_type_providers.sort(key=attrgetter("priority"), reverse=True)
162
+ collection_providers.append(provider_config)
163
+ collection_providers.sort(key=attrgetter("priority"), reverse=True)
165
164
 
166
165
  def get_search_plugins(
167
- self, product_type: Optional[str] = None, provider: Optional[str] = None
166
+ self, collection: Optional[str] = None, provider: Optional[str] = None
168
167
  ) -> Iterator[Union[Search, Api]]:
169
- """Build and return all the search plugins supporting the given product type,
168
+ """Build and return all the search plugins supporting the given collection,
170
169
  ordered by highest priority, or the search plugin of the given provider
171
170
 
172
- :param product_type: (optional) The product type that the constructed plugins
171
+ :param collection: (optional) The collection that the constructed plugins
173
172
  must support
174
173
  :param provider: (optional) The provider or the provider group on which to get
175
174
  the search plugins
176
- :returns: All the plugins supporting the product type, one by one (a generator
175
+ :returns: All the plugins supporting the collection, one by one (a generator
177
176
  object)
178
177
  or :class:`~eodag.plugins.download.Api`)
179
178
  :raises: :class:`~eodag.utils.exceptions.UnsupportedProvider`
@@ -196,13 +195,13 @@ class PluginManager:
196
195
  return plugin
197
196
 
198
197
  configs: Optional[list[ProviderConfig]]
199
- if product_type:
200
- configs = self.product_type_to_provider_config_map.get(product_type)
198
+ if collection:
199
+ configs = self.collection_to_provider_config_map.get(collection)
201
200
  if not configs:
202
201
  logger.info(
203
- "UnsupportedProductType: %s, using generic settings", product_type
202
+ "UnsupportedCollection: %s, using generic settings", collection
204
203
  )
205
- configs = self.product_type_to_provider_config_map[GENERIC_PRODUCT_TYPE]
204
+ configs = self.collection_to_provider_config_map[GENERIC_COLLECTION]
206
205
  else:
207
206
  configs = list(self.providers_config.values())
208
207
 
@@ -211,9 +210,9 @@ class PluginManager:
211
210
  c for c in configs if provider in [getattr(c, "group", None), c.name]
212
211
  ]
213
212
 
214
- if not configs and product_type:
213
+ if not configs and collection:
215
214
  raise UnsupportedProvider(
216
- f"{provider} is not (yet) supported for {product_type}"
215
+ f"{provider} is not (yet) supported for {collection}"
217
216
  )
218
217
  if not configs:
219
218
  raise UnsupportedProvider(f"{provider} is not (yet) supported")
@@ -265,8 +264,8 @@ class PluginManager:
265
264
  matching_url = next(iter(product.assets.values()))["href"]
266
265
  elif product is not None:
267
266
  matching_url = product.properties.get(
268
- "downloadLink"
269
- ) or product.properties.get("orderLink")
267
+ "eodag:download_link"
268
+ ) or product.properties.get("eodag:order_link")
270
269
  else:
271
270
  # search auth
272
271
  matching_url = getattr(associated_plugin.config, "api_endpoint", None)
@@ -289,7 +288,7 @@ class PluginManager:
289
288
  matching_url: Optional[str] = None,
290
289
  matching_conf: Optional[PluginConfig] = None,
291
290
  ) -> Iterator[Authentication]:
292
- """Build and return the authentication plugin for the given product_type and
291
+ """Build and return the authentication plugin for the given collection and
293
292
  provider
294
293
 
295
294
  :param provider: The provider for which to get the authentication plugin
@@ -362,7 +361,7 @@ class PluginManager:
362
361
  provider: str,
363
362
  matching_url: Optional[str] = None,
364
363
  matching_conf: Optional[PluginConfig] = None,
365
- ) -> Optional[Union[AuthBase, S3SessionKwargs, S3ServiceResource]]:
364
+ ) -> Optional[Union[AuthBase, S3ServiceResource]]:
366
365
  """Authenticate and return the authenticated object for the first matching
367
366
  authentication plugin
368
367
 
@@ -400,7 +399,7 @@ class PluginManager:
400
399
 
401
400
  def sort_providers(self) -> None:
402
401
  """Sort providers taking into account current priority order"""
403
- for provider_configs in self.product_type_to_provider_config_map.values():
402
+ for provider_configs in self.collection_to_provider_config_map.values():
404
403
  provider_configs.sort(key=attrgetter("priority"), reverse=True)
405
404
 
406
405
  def set_priority(self, provider: str, priority: int) -> None:
@@ -414,7 +413,7 @@ class PluginManager:
414
413
  for (
415
414
  _,
416
415
  provider_configs,
417
- ) in self.product_type_to_provider_config_map.items():
416
+ ) in self.collection_to_provider_config_map.items():
418
417
  for config in provider_configs:
419
418
  if config.name == provider:
420
419
  config.priority = priority
@@ -30,27 +30,29 @@ if TYPE_CHECKING:
30
30
  from requests.auth import AuthBase
31
31
 
32
32
  from eodag.plugins.authentication.base import Authentication
33
- from eodag.types import S3SessionKwargs
34
33
 
35
34
 
36
35
  @dataclass
37
36
  class PreparedSearch:
38
37
  """An object collecting needed information for search."""
39
38
 
40
- product_type: Optional[str] = None
39
+ collection: Optional[str] = None
41
40
  page: Optional[int] = DEFAULT_PAGE
42
41
  items_per_page: Optional[int] = DEFAULT_ITEMS_PER_PAGE
43
- auth: Optional[Union[AuthBase, S3SessionKwargs, S3ServiceResource]] = None
42
+ auth: Optional[Union[AuthBase, S3ServiceResource]] = None
44
43
  auth_plugin: Optional[Authentication] = None
45
44
  count: bool = True
46
45
  url: Optional[str] = None
47
46
  info_message: Optional[str] = None
48
47
  exception_message: Optional[str] = None
48
+ next_page_token: Optional[str] = None
49
+ next_page_token_key: Optional[str] = None
49
50
 
50
51
  need_count: bool = field(init=False, repr=False)
51
52
  query_params: dict[str, Any] = field(init=False, repr=False)
52
53
  query_string: str = field(init=False, repr=False)
53
54
  search_urls: list[str] = field(init=False, repr=False)
54
- product_type_def_params: dict[str, Any] = field(init=False, repr=False)
55
+ collection_def_params: dict[str, Any] = field(init=False, repr=False)
55
56
  total_items_nb: int = field(init=False, repr=False)
56
57
  sort_by_qs: str = field(init=False, repr=False)
58
+ raise_errors: Optional[bool] = field(init=False, repr=False)