eodag 3.9.0__py3-none-any.whl → 3.10.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.
@@ -149,42 +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
- - ``datetime_to_timestamp_milliseconds``: converts a utc date string to a timestamp in
153
- milliseconds
154
- - ``to_rounded_wkt``: simplify the WKT of a geometry
155
- - ``to_bounds_lists``: convert to list(s) of bounds
156
- - ``to_nwse_bounds``: convert to North,West,South,East bounds
157
- - ``to_nwse_bounds_str``: convert to North,West,South,East bounds string with given separator
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
- - ``csv_list``: convert to a comma separated list
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
- - ``to_title``: Convert a string to title case
178
- - ``fake_l2a_title_from_l1c``: used to generate SAFE format metadata for data from AWS
179
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])
180
169
  - ``split_cop_dem_id``: get the bbox by splitting the product id
181
170
  - ``split_corine_id``: get the product type by splitting the product id
171
+ - ``to_bounds_lists``: convert to list(s) of bounds
182
172
  - ``to_datetime_dict``: convert a datetime string to a dictionary where values are either a string or a list
183
- - ``get_ecmwf_time``: get the time of a datetime string in the ECMWF format
184
- - ``sanitize``: sanitize string
185
- - ``ceda_collection_name``: generate a CEDA collection name from a string
186
- - ``convert_dict_filter_and_sub``: filter dict items using jsonpath and then apply recursive_sub_str
187
- - ``convert_from_alternate``: update assets using given alternate
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
188
184
 
189
185
  :param search_param: The string to be formatted
190
186
  :param args: (optional) Additional arguments to use in the formatting process
@@ -490,9 +486,9 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
490
486
  return {"lon": lon, "lat": lat}
491
487
 
492
488
  @staticmethod
493
- def convert_csv_list(values_list: Any) -> Any:
489
+ def convert_csv_list(values_list: Any, separator=",") -> Any:
494
490
  if isinstance(values_list, list):
495
- return ",".join([str(x) for x in values_list])
491
+ return separator.join([str(x) for x in values_list])
496
492
  else:
497
493
  return values_list
498
494
 
@@ -24,9 +24,11 @@ import boto3
24
24
  from botocore.exceptions import ClientError, ProfileNotFound
25
25
  from botocore.handlers import disable_signing
26
26
 
27
+ from eodag.api.product._assets import Asset
27
28
  from eodag.plugins.authentication.base import Authentication
28
29
  from eodag.types import S3SessionKwargs
29
- from eodag.utils.exceptions import AuthenticationError
30
+ from eodag.utils import get_bucket_name_and_prefix
31
+ from eodag.utils.exceptions import AuthenticationError, EodagError
30
32
 
31
33
  if TYPE_CHECKING:
32
34
  from mypy_boto3_s3 import S3Client, S3ServiceResource
@@ -106,9 +108,12 @@ class AwsAuth(Authentication):
106
108
  def _create_s3_session_from_credentials(self) -> boto3.Session:
107
109
  credentials = getattr(self.config, "credentials", {}) or {}
108
110
  if "aws_profile" in credentials:
111
+ logger.debug("Authentication using AWS profile")
109
112
  return create_s3_session(profile_name=credentials["aws_profile"])
110
113
  # auth using aws keys
111
- elif credentials:
114
+ elif credentials.get("aws_access_key_id") and credentials.get(
115
+ "aws_secret_access_key"
116
+ ):
112
117
  s3_session_kwargs: S3SessionKwargs = {
113
118
  "aws_access_key_id": credentials["aws_access_key_id"],
114
119
  "aws_secret_access_key": credentials["aws_secret_access_key"],
@@ -120,6 +125,7 @@ class AwsAuth(Authentication):
120
125
  return create_s3_session(**s3_session_kwargs)
121
126
  else:
122
127
  # auth using env variables or ~/.aws
128
+ logger.debug("Authentication using AWS environment")
123
129
  return create_s3_session()
124
130
 
125
131
  def _create_s3_resource(self) -> S3ServiceResource:
@@ -133,6 +139,9 @@ class AwsAuth(Authentication):
133
139
  endpoint_url=endpoint_url,
134
140
  )
135
141
  # could not auth using credentials: use no-sign-request strategy
142
+ logger.debug(
143
+ "Authentication using AWS no-sign-request strategy (no credentials found)"
144
+ )
136
145
  s3_resource = boto3.resource(service_name="s3", endpoint_url=endpoint_url)
137
146
  s3_resource.meta.client.meta.events.register(
138
147
  "choose-signer.s3.*", disable_signing
@@ -276,3 +285,36 @@ class AwsAuth(Authentication):
276
285
  "session": self.s3_session,
277
286
  **rio_env_kwargs,
278
287
  }
288
+
289
+ def presign_url(
290
+ self,
291
+ asset: Asset,
292
+ expires_in: int = 3600,
293
+ ) -> str:
294
+ """This method is used to presign a url to download an asset from S3.
295
+
296
+ :param asset: asset for which the url shall be presigned
297
+ :param expires_in: expiration time of the presigned url in seconds
298
+ :returns: presigned url
299
+ :raises: :class:`~eodag.utils.exceptions.EodagError`
300
+ :raises: :class:`NotImplementedError`
301
+ """
302
+ if not getattr(self.config, "support_presign_url", True):
303
+ raise NotImplementedError(
304
+ f"presign_url is not supported for provider {self.provider}"
305
+ )
306
+
307
+ s3_client = self.get_s3_client()
308
+ bucket, prefix = get_bucket_name_and_prefix(asset["href"])
309
+ try:
310
+ presigned_url = s3_client.generate_presigned_url(
311
+ "get_object",
312
+ Params={
313
+ "Bucket": bucket,
314
+ "Key": prefix,
315
+ },
316
+ ExpiresIn=expires_in,
317
+ )
318
+ return presigned_url
319
+ except ClientError:
320
+ raise EodagError(f"Couldn't get a presigned URL for '{asset}'.")
@@ -19,6 +19,7 @@ from __future__ import annotations
19
19
 
20
20
  from typing import TYPE_CHECKING, Any, Optional, Union
21
21
 
22
+ from eodag.api.product._assets import Asset
22
23
  from eodag.plugins.base import PluginTopic
23
24
  from eodag.utils.exceptions import MisconfiguredError
24
25
 
@@ -80,3 +81,19 @@ class Authentication(PluginTopic):
80
81
  Authenticates with s3 and retrieves the available objects
81
82
  """
82
83
  raise NotImplementedError
84
+
85
+ def presign_url(
86
+ self,
87
+ asset: Asset,
88
+ expires_in: int = 3600,
89
+ ) -> str:
90
+ """This method is used to presign a url to download an asset from S3.
91
+
92
+ :param asset: asset for which the url shall be presigned
93
+ :param expires_in: expiration time of the presigned url in seconds
94
+ :returns: presigned url
95
+ :raises: :class:`NotImplementedError`
96
+ """
97
+ raise NotImplementedError(
98
+ f"presign_url is not implemented for plugin {type(self).__name__}"
99
+ )
@@ -25,6 +25,7 @@ from typing import TYPE_CHECKING, Optional
25
25
  import requests
26
26
  from requests.auth import AuthBase
27
27
 
28
+ from eodag.api.product._assets import Asset
28
29
  from eodag.plugins.authentication.base import Authentication
29
30
  from eodag.utils import HTTP_REQ_TIMEOUT, USER_AGENT, deepcopy, format_dict_items
30
31
  from eodag.utils.exceptions import AuthenticationError, TimeOutError
@@ -143,3 +144,17 @@ class SASAuth(Authentication):
143
144
  ssl_verify=ssl_verify,
144
145
  matching_url=matching_url,
145
146
  )
147
+
148
+ def presign_url(
149
+ self,
150
+ asset: Asset,
151
+ expires_in: int = 3600,
152
+ ) -> str:
153
+ """This method is used to presign a url to download an asset.
154
+
155
+ :param asset: asset for which the url shall be presigned
156
+ :param expires_in: expiration time of the presigned url in seconds
157
+ :returns: presigned url
158
+ """
159
+ url = asset["href"]
160
+ return self.config.auth_uri.format(url=url)
@@ -15,12 +15,19 @@
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 __future__ import annotations
19
+
18
20
  from typing import Optional
19
21
 
20
22
  from eodag import EOProduct
21
23
  from eodag.plugins.download.aws import AwsDownload
24
+ from eodag.utils import _deprecated
22
25
 
23
26
 
27
+ @_deprecated(
28
+ reason="Plugin that was used in creodias_s3 provider configuration, but not anymore",
29
+ version="3.10.0",
30
+ )
24
31
  class CreodiasS3Download(AwsDownload):
25
32
  """
26
33
  Download on creodias s3 from their VMs (extension of :class:`~eodag.plugins.download.aws.AwsDownload`)