eodag 3.0.0b2__py3-none-any.whl → 3.0.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.
Files changed (84) hide show
  1. eodag/__init__.py +6 -8
  2. eodag/api/core.py +295 -287
  3. eodag/api/product/__init__.py +10 -4
  4. eodag/api/product/_assets.py +2 -14
  5. eodag/api/product/_product.py +16 -30
  6. eodag/api/product/drivers/__init__.py +7 -2
  7. eodag/api/product/drivers/base.py +0 -3
  8. eodag/api/product/metadata_mapping.py +12 -31
  9. eodag/api/search_result.py +33 -12
  10. eodag/cli.py +35 -19
  11. eodag/config.py +455 -155
  12. eodag/plugins/apis/base.py +13 -7
  13. eodag/plugins/apis/ecmwf.py +16 -7
  14. eodag/plugins/apis/usgs.py +68 -16
  15. eodag/plugins/authentication/aws_auth.py +25 -7
  16. eodag/plugins/authentication/base.py +10 -1
  17. eodag/plugins/authentication/generic.py +14 -3
  18. eodag/plugins/authentication/header.py +12 -4
  19. eodag/plugins/authentication/keycloak.py +41 -22
  20. eodag/plugins/authentication/oauth.py +11 -1
  21. eodag/plugins/authentication/openid_connect.py +183 -167
  22. eodag/plugins/authentication/qsauth.py +12 -4
  23. eodag/plugins/authentication/sas_auth.py +19 -2
  24. eodag/plugins/authentication/token.py +59 -11
  25. eodag/plugins/authentication/token_exchange.py +19 -19
  26. eodag/plugins/crunch/base.py +7 -2
  27. eodag/plugins/crunch/filter_date.py +8 -11
  28. eodag/plugins/crunch/filter_latest_intersect.py +5 -7
  29. eodag/plugins/crunch/filter_latest_tpl_name.py +2 -5
  30. eodag/plugins/crunch/filter_overlap.py +9 -15
  31. eodag/plugins/crunch/filter_property.py +9 -14
  32. eodag/plugins/download/aws.py +84 -99
  33. eodag/plugins/download/base.py +36 -77
  34. eodag/plugins/download/creodias_s3.py +11 -2
  35. eodag/plugins/download/http.py +134 -109
  36. eodag/plugins/download/s3rest.py +37 -43
  37. eodag/plugins/manager.py +173 -41
  38. eodag/plugins/search/__init__.py +9 -9
  39. eodag/plugins/search/base.py +35 -35
  40. eodag/plugins/search/build_search_result.py +55 -64
  41. eodag/plugins/search/cop_marine.py +113 -32
  42. eodag/plugins/search/creodias_s3.py +20 -8
  43. eodag/plugins/search/csw.py +41 -1
  44. eodag/plugins/search/data_request_search.py +119 -14
  45. eodag/plugins/search/qssearch.py +619 -197
  46. eodag/plugins/search/static_stac_search.py +25 -23
  47. eodag/resources/ext_product_types.json +1 -1
  48. eodag/resources/product_types.yml +211 -56
  49. eodag/resources/providers.yml +1762 -1809
  50. eodag/resources/stac.yml +3 -163
  51. eodag/resources/user_conf_template.yml +134 -119
  52. eodag/rest/config.py +1 -2
  53. eodag/rest/constants.py +0 -1
  54. eodag/rest/core.py +70 -92
  55. eodag/rest/errors.py +181 -0
  56. eodag/rest/server.py +24 -330
  57. eodag/rest/stac.py +105 -630
  58. eodag/rest/types/eodag_search.py +17 -15
  59. eodag/rest/types/queryables.py +5 -14
  60. eodag/rest/types/stac_search.py +18 -13
  61. eodag/rest/utils/rfc3339.py +0 -1
  62. eodag/types/__init__.py +24 -6
  63. eodag/types/download_args.py +14 -5
  64. eodag/types/queryables.py +1 -2
  65. eodag/types/search_args.py +10 -11
  66. eodag/types/whoosh.py +0 -2
  67. eodag/utils/__init__.py +97 -136
  68. eodag/utils/constraints.py +0 -8
  69. eodag/utils/exceptions.py +23 -9
  70. eodag/utils/import_system.py +0 -4
  71. eodag/utils/logging.py +37 -80
  72. eodag/utils/notebook.py +4 -4
  73. eodag/utils/requests.py +13 -23
  74. eodag/utils/rest.py +0 -4
  75. eodag/utils/stac_reader.py +3 -15
  76. {eodag-3.0.0b2.dist-info → eodag-3.0.1.dist-info}/METADATA +41 -24
  77. eodag-3.0.1.dist-info/RECORD +109 -0
  78. {eodag-3.0.0b2.dist-info → eodag-3.0.1.dist-info}/WHEEL +1 -1
  79. {eodag-3.0.0b2.dist-info → eodag-3.0.1.dist-info}/entry_points.txt +1 -0
  80. eodag/resources/constraints/climate-dt.json +0 -13
  81. eodag/resources/constraints/extremes-dt.json +0 -8
  82. eodag-3.0.0b2.dist-info/RECORD +0 -110
  83. {eodag-3.0.0b2.dist-info → eodag-3.0.1.dist-info}/LICENSE +0 -0
  84. {eodag-3.0.0b2.dist-info → eodag-3.0.1.dist-info}/top_level.txt +0 -0
@@ -34,6 +34,7 @@ from typing import (
34
34
  Optional,
35
35
  Set,
36
36
  Tuple,
37
+ TypedDict,
37
38
  Union,
38
39
  cast,
39
40
  )
@@ -69,6 +70,7 @@ from eodag.utils.exceptions import (
69
70
  AuthenticationError,
70
71
  DownloadError,
71
72
  MisconfiguredError,
73
+ NoMatchingProductType,
72
74
  NotAvailableError,
73
75
  TimeOutError,
74
76
  )
@@ -213,23 +215,36 @@ class AwsDownload(Download):
213
215
  """Download on AWS using S3 protocol.
214
216
 
215
217
  :param provider: provider name
216
- :type provider: str
217
218
  :param config: Download plugin configuration:
218
219
 
219
- * ``config.base_uri`` (str) - s3 endpoint url
220
- * ``config.requester_pays`` (bool) - (optional) whether download is done from a
221
- requester-pays bucket or not
222
- * ``config.flatten_top_dirs`` (bool) - (optional) flatten directory structure
223
- * ``config.products`` (dict) - (optional) product_type specific configuration
224
- * ``config.ignore_assets`` (bool) - (optional) ignore assets and download using downloadLink
220
+ * :attr:`~eodag.config.PluginConfig.type` (``str``) (**mandatory**): AwsDownload
221
+ * :attr:`~eodag.config.PluginConfig.base_uri` (``str``) (**mandatory**): s3 endpoint url
222
+ * :attr:`~eodag.config.PluginConfig.requester_pays` (``bool``): whether download is done
223
+ from a requester-pays bucket or not; default: ``False``
224
+ * :attr:`~eodag.config.PluginConfig.flatten_top_dirs` (``bool``): if the directory structure
225
+ should be flattened; default: ``True``
226
+ * :attr:`~eodag.config.PluginConfig.ignore_assets` (``bool``): ignore assets and download
227
+ using ``downloadLink``; default: ``False``
228
+ * :attr:`~eodag.config.PluginConfig.ssl_verify` (``bool``): if the ssl certificates should
229
+ be verified in requests; default: ``True``
230
+ * :attr:`~eodag.config.PluginConfig.bucket_path_level` (``int``): at which level of the
231
+ path part of the url the bucket can be found; If no bucket_path_level is given, the bucket
232
+ is taken from the first element of the netloc part.
233
+ * :attr:`~eodag.config.PluginConfig.products` (``Dict[str, Dict[str, Any]``): product type
234
+ specific config; the keys are the product types, the values are dictionaries which can contain the keys:
235
+
236
+ * **default_bucket** (``str``): bucket where the product type can be found
237
+ * **complementary_url_key** (``str``): keys to add additional urls
238
+ * **build_safe** (``bool``): if a SAFE (Standard Archive Format for Europe) product should
239
+ be created; used for Sentinel products; default: False
240
+ * **fetch_metadata** (``Dict[str, Any]``): config for metadata to be fetched for the SAFE product
225
241
 
226
- :type config: :class:`~eodag.config.PluginConfig`
227
242
  """
228
243
 
229
244
  def __init__(self, provider: str, config: PluginConfig) -> None:
230
245
  super(AwsDownload, self).__init__(provider, config)
231
246
  self.requester_pays = getattr(self.config, "requester_pays", False)
232
- self.s3_session = None
247
+ self.s3_session: Optional[boto3.session.Session] = None
233
248
 
234
249
  def download(
235
250
  self,
@@ -246,25 +261,20 @@ class AwsDownload(Download):
246
261
  SAFE-build is configured for a given provider and product type.
247
262
  If the product title is configured to be updated during download and
248
263
  SAFE-formatted, its destination path will be:
249
- `{outputs_prefix}/{title}`
264
+ `{output_dir}/{title}`
250
265
 
251
266
  :param product: The EO product to download
252
- :type product: :class:`~eodag.api.product._product.EOProduct`
253
267
  :param auth: (optional) authenticated object
254
- :type auth: Union[AuthBase, Dict[str, str]]
255
268
  :param progress_callback: (optional) A method or a callable object
256
269
  which takes a current size and a maximum
257
270
  size as inputs and handle progress bar
258
271
  creation and update to give the user a
259
272
  feedback on the download progress
260
- :type progress_callback: :class:`~eodag.utils.ProgressCallback` or None
261
- :param kwargs: `outputs_prefix` (str), `extract` (bool), `delete_archive` (bool)
273
+ :param kwargs: `output_dir` (str), `extract` (bool), `delete_archive` (bool)
262
274
  and `dl_url_params` (dict) can be provided as additional kwargs
263
275
  and will override any other values defined in a configuration
264
276
  file or with environment variables.
265
- :type kwargs: Union[str, bool, dict]
266
277
  :returns: The absolute path to the downloaded product in the local filesystem
267
- :rtype: str
268
278
  """
269
279
  if auth is None:
270
280
  auth = {}
@@ -404,13 +414,9 @@ class AwsDownload(Download):
404
414
  - get file path
405
415
  - create directories
406
416
  :param product: product to be downloaded
407
- :type product: EOProduct
408
417
  :param progress_callback: progress callback to be used
409
- :type progress_callback: ProgressCallback
410
418
  :param kwargs: additional arguments
411
- :type kwargs: Any
412
419
  :return: local path and file name
413
- :rtype: Tuple[str, Optional[str]]
414
420
  """
415
421
  product_local_path, record_filename = self._prepare_download(
416
422
  product, progress_callback=progress_callback, **kwargs
@@ -432,9 +438,7 @@ class AwsDownload(Download):
432
438
  """
433
439
  updates the product properties with fetch metadata if safe build is enabled
434
440
  :param build_safe: if safe build is enabled
435
- :type build_safe: bool
436
441
  :param product: product to be updated
437
- :type product: EOProduct
438
442
  """
439
443
  product_conf = getattr(self.config, "products", {}).get(
440
444
  product.product_type, {}
@@ -480,13 +484,9 @@ class AwsDownload(Download):
480
484
  """
481
485
  retrieves the bucket names and path prefixes for the assets
482
486
  :param product: product for which the assets shall be downloaded
483
- :type product: EOProduct
484
487
  :param asset_filter: text for which the assets should be filtered
485
- :type asset_filter: str
486
488
  :param ignore_assets: if product instead of individual assets should be used
487
- :type ignore_assets: bool
488
489
  :return: tuples of bucket names and prefixes
489
- :rtype: List[Tuple[str, Optional[str]]]
490
490
  """
491
491
  # if assets are defined, use them instead of scanning product.location
492
492
  if len(product.assets) > 0 and not ignore_assets:
@@ -528,11 +528,8 @@ class AwsDownload(Download):
528
528
  authenticates with s3 and retrieves the available objects
529
529
  raises an error when authentication is not possible
530
530
  :param bucket_names_and_prefixes: list of bucket names and corresponding path prefixes
531
- :type bucket_names_and_prefixes: List[Tuple[str, Optional[str]]]
532
531
  :param auth: authentication information
533
- :type auth: Dict[str, str]
534
532
  :return: authenticated objects per bucket, list of available objects
535
- :rtype: Tuple[Dict[str, Any], ResourceCollection[Any]]
536
533
  """
537
534
  if not isinstance(auth, (dict, type(None))):
538
535
  raise AuthenticationError(
@@ -602,17 +599,11 @@ class AwsDownload(Download):
602
599
  """
603
600
  retrieve unique product chunks based on authenticated objects and asset filters
604
601
  :param bucket_names_and_prefixes: list of bucket names and corresponding path prefixes
605
- :type bucket_names_and_prefixes: List[Tuple[str, Optional[str]]]
606
602
  :param authenticated_objects: available objects per bucket
607
- :type authenticated_objects: Dict[str, Any]
608
603
  :param asset_filter: text for which assets should be filtered
609
- :type asset_filter: str
610
604
  :param ignore_assets: if product instead of individual assets should be used
611
- :type ignore_assets: bool
612
605
  :param product: product that shall be downloaded
613
- :type product: EOProduct
614
606
  :return: set of product chunks that can be downloaded
615
- :rtype: Set[Any]
616
607
  """
617
608
  product_chunks: List[Any] = []
618
609
  for bucket_name, prefix in bucket_names_and_prefixes:
@@ -637,19 +628,20 @@ class AwsDownload(Download):
637
628
  raise NotAvailableError(
638
629
  rf"No file basename matching re.fullmatch(r'{asset_filter}') was found in {product.remote_location}"
639
630
  )
631
+
632
+ if not unique_product_chunks:
633
+ raise NoMatchingProductType("No product found to download.")
634
+
640
635
  return unique_product_chunks
641
636
 
642
637
  def _raise_if_auth_error(self, exception: ClientError) -> None:
643
638
  """Raises an error if given exception is an authentication error"""
644
- err = exception.response["Error"]
639
+ err = cast(Dict[str, str], exception.response["Error"])
645
640
  if err["Code"] in AWS_AUTH_ERROR_MESSAGES and "key" in err["Message"].lower():
646
641
  raise AuthenticationError(
647
- "HTTP error {} returned\n{}: {}\nPlease check your credentials for {}".format(
648
- exception.response["ResponseMetadata"]["HTTPStatusCode"],
649
- err["Code"],
650
- err["Message"],
651
- self.provider,
652
- )
642
+ f"Please check your credentials for {self.provider}.",
643
+ f"HTTP Error {exception.response['ResponseMetadata']['HTTPStatusCode']} returned.",
644
+ err["Code"] + ": " + err["Message"],
653
645
  )
654
646
 
655
647
  def _stream_download_dict(
@@ -662,27 +654,20 @@ class AwsDownload(Download):
662
654
  **kwargs: Unpack[DownloadConf],
663
655
  ) -> StreamResponse:
664
656
  r"""
665
- Returns dictionnary of :class:`~fastapi.responses.StreamingResponse` keyword-arguments.
657
+ Returns dictionary of :class:`~fastapi.responses.StreamingResponse` keyword-arguments.
666
658
  It contains a generator to streamed download chunks and the response headers.
667
659
 
668
660
  :param product: The EO product to download
669
- :type product: :class:`~eodag.api.product._product.EOProduct`
670
661
  :param auth: (optional) The configuration of a plugin of type Authentication
671
- :type auth: :class:`~eodag.config.PluginConfig`
672
662
  :param progress_callback: (optional) A progress callback
673
- :type progress_callback: :class:`~eodag.utils.ProgressCallback`
674
663
  :param wait: (optional) If download fails, wait time in minutes between two download tries
675
- :type wait: int
676
664
  :param timeout: (optional) If download fails, maximum time in minutes before stop retrying
677
665
  to download
678
- :type timeout: int
679
- :param kwargs: `outputs_prefix` (str), `extract` (bool), `delete_archive` (bool)
666
+ :param kwargs: `output_dir` (str), `extract` (bool), `delete_archive` (bool)
680
667
  and `dl_url_params` (dict) can be provided as additional kwargs
681
668
  and will override any other values defined in a configuration
682
669
  file or with environment variables.
683
- :type kwargs: Union[str, bool, dict]
684
- :returns: Dictionnary of :class:`~fastapi.responses.StreamingResponse` keyword-arguments
685
- :rtype: dict
670
+ :returns: Dictionary of :class:`~fastapi.responses.StreamingResponse` keyword-arguments
686
671
  """
687
672
  if progress_callback is None:
688
673
  logger.info(
@@ -773,7 +758,7 @@ class AwsDownload(Download):
773
758
  build_safe: bool,
774
759
  progress_callback: ProgressCallback,
775
760
  assets_values: List[Dict[str, Any]],
776
- ) -> Iterator[Tuple[str, datetime, int, Any, Iterator[Any]]]:
761
+ ) -> Iterator[Any]:
777
762
  """Yield product data chunks"""
778
763
 
779
764
  chunk_size = 4096 * 1024
@@ -784,7 +769,6 @@ class AwsDownload(Download):
784
769
  product_chunk: Any, progress_callback: ProgressCallback
785
770
  ) -> Any:
786
771
  try:
787
-
788
772
  chunk_start = 0
789
773
  chunk_end = chunk_start + chunk_size - 1
790
774
 
@@ -861,13 +845,9 @@ class AwsDownload(Download):
861
845
  """Get rasterio environment variables needed for data access authentication.
862
846
 
863
847
  :param bucket_name: Bucket containg objects
864
- :type bucket_name: str
865
848
  :param prefix: Prefix used to try auth
866
- :type prefix: str
867
- :param auth_dict: Dictionnary containing authentication keys
868
- :type auth_dict: dict
849
+ :param auth_dict: Dictionary containing authentication keys
869
850
  :returns: The rasterio environement variables
870
- :rtype: dict
871
851
  """
872
852
  if self.s3_session is not None:
873
853
  if self.requester_pays:
@@ -892,14 +872,10 @@ class AwsDownload(Download):
892
872
  Also expose ``s3_session`` as class variable if available.
893
873
 
894
874
  :param bucket_name: Bucket containg objects
895
- :type bucket_name: str
896
875
  :param prefix: Prefix used to filter objects on auth try
897
876
  (not used to filter returned objects)
898
- :type prefix: str
899
- :param auth_dict: Dictionnary containing authentication keys
900
- :type auth_dict: dict
877
+ :param auth_dict: Dictionary containing authentication keys
901
878
  :returns: The boto3 authenticated objects
902
- :rtype: :class:`~boto3.resources.collection.s3.Bucket.objectsCollection`
903
879
  """
904
880
  auth_methods: List[
905
881
  Callable[[str, str, Dict[str, str]], Optional[ResourceCollection]]
@@ -941,15 +917,15 @@ class AwsDownload(Download):
941
917
  ) -> Optional[ResourceCollection]:
942
918
  """Auth strategy using no-sign-request"""
943
919
 
944
- s3_resource = boto3.resource( # type: ignore
945
- service_name="s3", endpoint_url=getattr(self.config, "base_uri", None)
920
+ s3_resource = boto3.resource(
921
+ service_name="s3", endpoint_url=getattr(self.config, "s3_endpoint", None)
946
922
  )
947
- s3_resource.meta.client.meta.events.register( # type: ignore
923
+ s3_resource.meta.client.meta.events.register(
948
924
  "choose-signer.s3.*", disable_signing
949
925
  )
950
- objects = s3_resource.Bucket(bucket_name).objects # type: ignore
951
- list(objects.filter(Prefix=prefix).limit(1)) # type: ignore
952
- return objects # type: ignore
926
+ objects = s3_resource.Bucket(bucket_name).objects
927
+ list(objects.filter(Prefix=prefix).limit(1))
928
+ return objects
953
929
 
954
930
  def _get_authenticated_objects_from_auth_profile(
955
931
  self, bucket_name: str, prefix: str, auth_dict: Dict[str, str]
@@ -957,20 +933,20 @@ class AwsDownload(Download):
957
933
  """Auth strategy using RequestPayer=requester and ``aws_profile`` from provided credentials"""
958
934
 
959
935
  if "profile_name" in auth_dict.keys():
960
- s3_session = boto3.session.Session(profile_name=auth_dict["profile_name"]) # type: ignore
961
- s3_resource = s3_session.resource( # type: ignore
936
+ s3_session = boto3.session.Session(profile_name=auth_dict["profile_name"])
937
+ s3_resource = s3_session.resource(
962
938
  service_name="s3",
963
- endpoint_url=getattr(self.config, "base_uri", None),
939
+ endpoint_url=getattr(self.config, "s3_endpoint", None),
964
940
  )
965
941
  if self.requester_pays:
966
- objects = s3_resource.Bucket(bucket_name).objects.filter( # type: ignore
942
+ objects = s3_resource.Bucket(bucket_name).objects.filter(
967
943
  RequestPayer="requester"
968
944
  )
969
945
  else:
970
- objects = s3_resource.Bucket(bucket_name).objects # type: ignore
971
- list(objects.filter(Prefix=prefix).limit(1)) # type: ignore
972
- self.s3_session = s3_session # type: ignore
973
- return objects # type: ignore
946
+ objects = s3_resource.Bucket(bucket_name).objects
947
+ list(objects.filter(Prefix=prefix).limit(1))
948
+ self.s3_session = s3_session
949
+ return objects
974
950
  else:
975
951
  return None
976
952
 
@@ -981,23 +957,35 @@ class AwsDownload(Download):
981
957
  from provided credentials"""
982
958
 
983
959
  if all(k in auth_dict for k in ("aws_access_key_id", "aws_secret_access_key")):
984
- s3_session = boto3.session.Session( # type: ignore
985
- aws_access_key_id=auth_dict["aws_access_key_id"],
986
- aws_secret_access_key=auth_dict["aws_secret_access_key"],
960
+ S3SessionKwargs = TypedDict(
961
+ "S3SessionKwargs",
962
+ {
963
+ "aws_access_key_id": str,
964
+ "aws_secret_access_key": str,
965
+ "aws_session_token": str,
966
+ },
967
+ total=False,
987
968
  )
988
- s3_resource = s3_session.resource( # type: ignore
969
+ s3_session_kwargs: S3SessionKwargs = {
970
+ "aws_access_key_id": auth_dict["aws_access_key_id"],
971
+ "aws_secret_access_key": auth_dict["aws_secret_access_key"],
972
+ }
973
+ if auth_dict.get("aws_session_token"):
974
+ s3_session_kwargs["aws_session_token"] = auth_dict["aws_session_token"]
975
+ s3_session = boto3.session.Session(**s3_session_kwargs)
976
+ s3_resource = s3_session.resource(
989
977
  service_name="s3",
990
- endpoint_url=getattr(self.config, "base_uri", None),
978
+ endpoint_url=getattr(self.config, "s3_endpoint", None),
991
979
  )
992
980
  if self.requester_pays:
993
- objects = s3_resource.Bucket(bucket_name).objects.filter( # type: ignore
981
+ objects = s3_resource.Bucket(bucket_name).objects.filter(
994
982
  RequestPayer="requester"
995
983
  )
996
984
  else:
997
- objects = s3_resource.Bucket(bucket_name).objects # type: ignore
998
- list(objects.filter(Prefix=prefix).limit(1)) # type: ignore
999
- self.s3_session = s3_session # type: ignore
1000
- return objects # type: ignore
985
+ objects = s3_resource.Bucket(bucket_name).objects
986
+ list(objects.filter(Prefix=prefix).limit(1))
987
+ self.s3_session = s3_session
988
+ return objects
1001
989
  else:
1002
990
  return None
1003
991
 
@@ -1006,19 +994,19 @@ class AwsDownload(Download):
1006
994
  ) -> Optional[ResourceCollection]:
1007
995
  """Auth strategy using RequestPayer=requester and current environment"""
1008
996
 
1009
- s3_session = boto3.session.Session() # type: ignore
1010
- s3_resource = s3_session.resource( # type: ignore
1011
- service_name="s3", endpoint_url=getattr(self.config, "base_uri", None)
997
+ s3_session = boto3.session.Session()
998
+ s3_resource = s3_session.resource(
999
+ service_name="s3", endpoint_url=getattr(self.config, "s3_endpoint", None)
1012
1000
  )
1013
1001
  if self.requester_pays:
1014
- objects = s3_resource.Bucket(bucket_name).objects.filter( # type: ignore
1002
+ objects = s3_resource.Bucket(bucket_name).objects.filter(
1015
1003
  RequestPayer="requester"
1016
1004
  )
1017
1005
  else:
1018
- objects = s3_resource.Bucket(bucket_name).objects # type: ignore
1019
- list(objects.filter(Prefix=prefix).limit(1)) # type: ignore
1020
- self.s3_session = s3_session # type: ignore
1021
- return objects # type: ignore
1006
+ objects = s3_resource.Bucket(bucket_name).objects
1007
+ list(objects.filter(Prefix=prefix).limit(1))
1008
+ self.s3_session = s3_session
1009
+ return objects
1022
1010
 
1023
1011
  def get_product_bucket_name_and_prefix(
1024
1012
  self, product: EOProduct, url: Optional[str] = None
@@ -1026,11 +1014,8 @@ class AwsDownload(Download):
1026
1014
  """Extract bucket name and prefix from product URL
1027
1015
 
1028
1016
  :param product: The EO product to download
1029
- :type product: :class:`~eodag.api.product._product.EOProduct`
1030
1017
  :param url: (optional) URL to use as product.location
1031
- :type url: str
1032
1018
  :returns: bucket_name and prefix as str
1033
- :rtype: tuple
1034
1019
  """
1035
1020
  if url is None:
1036
1021
  url = product.location