[Git][debian-gis-team/eodag][master] 6 commits: New upstream version 3.10.0+ds

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sun Nov 2 12:08:28 GMT 2025



Antonio Valentino pushed to branch master at Debian GIS Project / eodag


Commits:
cd72b9af by Antonio Valentino at 2025-10-23T05:24:49+00:00
New upstream version 3.10.0+ds
- - - - -
e80023e3 by Antonio Valentino at 2025-10-23T05:24:56+00:00
Update upstream source from tag 'upstream/3.10.0+ds'

Update to upstream version '3.10.0+ds'
with Debian dir 940ee5a4111e2c9539d349b648efc565201e722e
- - - - -
889e9fb8 by Antonio Valentino at 2025-10-23T05:25:43+00:00
New upstream release

- - - - -
145d5e98 by Antonio Valentino at 2025-10-23T05:44:28+00:00
Refresh all patches

- - - - -
2c4b7537 by Antonio Valentino at 2025-10-23T05:44:49+00:00
Set distribution to unstable

- - - - -
f7b398b2 by Antonio Valentino at 2025-11-02T12:07:11+00:00
Merge remote-tracking branch 'origin/master'

- - - - -


20 changed files:

- CHANGES.rst
- README.rst
- charts/eodag-server/Chart.yaml
- debian/changelog
- debian/patches/0002-System-importlib.metadata.patch
- debian/patches/0003-no-mypy-boto3-s3.patch
- docs/conf.py
- docs/plugins.rst
- docs/stac_rest.rst
- eodag/plugins/authentication/aws_auth.py
- eodag/plugins/authentication/base.py
- eodag/plugins/authentication/sas_auth.py
- eodag/plugins/download/creodias_s3.py
- + eodag/resources/ext_collections.json
- eodag/resources/ext_product_types.json
- eodag/resources/providers.yml
- pyproject.toml
- setup.cfg
- tests/units/test_auth_plugins.py
- tests/units/test_download_plugins.py


Changes:

=====================================
CHANGES.rst
=====================================
@@ -3,6 +3,40 @@ Release history
 ===============
 
 
+v3.10.0 (2025-10-20)
+====================
+
+Features
+--------
+
+* **plugins**: Possibility to create presigned urls (`#1845`_, `d002c38`_)
+
+Bug Fixes
+---------
+
+* **providers**: Added month/year mapping and default values for CMIP6_CLIMATE_PROJECT (`#1872`_,
+  `dcdca60`_)
+
+Build System
+------------
+
+* Pin pydantic < 2.12.0 to prevent sphinx failures (`#1873`_, `1b17b4a`_)
+
+Refactoring
+-----------
+
+* **plugins**: Deprecate CreodiasS3Download (`#1884`_, `5f6966b`_)
+
+.. _#1845: https://github.com/CS-SI/eodag/pull/1845
+.. _#1872: https://github.com/CS-SI/eodag/pull/1872
+.. _#1873: https://github.com/CS-SI/eodag/pull/1873
+.. _#1884: https://github.com/CS-SI/eodag/pull/1884
+.. _1b17b4a: https://github.com/CS-SI/eodag/commit/1b17b4af5f898ed608dd132e49477d28466f9451
+.. _5f6966b: https://github.com/CS-SI/eodag/commit/5f6966bc52db1e19ad3f959bab41aca25804c3e5
+.. _d002c38: https://github.com/CS-SI/eodag/commit/d002c38126f566f52903fb0e5012a22e771c3200
+.. _dcdca60: https://github.com/CS-SI/eodag/commit/dcdca6012736f751418725312da736f61767ec36
+
+
 v3.9.1 (2025-10-07)
 ===================
 


=====================================
README.rst
=====================================
@@ -185,7 +185,7 @@ An eodag instance can be exposed through a STAC compliant REST api from the comm
 
 .. code-block:: bash
 
-    docker run -p 5000:5000 --rm csspace/eodag-server:3.9.1
+    docker run -p 5000:5000 --rm csspace/eodag-server:3.10.0
 
 You can also browse over your STAC API server using `STAC Browser <https://github.com/radiantearth/stac-browser>`_.
 Simply run:


=====================================
charts/eodag-server/Chart.yaml
=====================================
@@ -1,5 +1,5 @@
 apiVersion: v2
-appVersion: 3.9.1
+appVersion: 3.10.0
 dependencies:
 - name: common
   repository:  oci://registry-1.docker.io/bitnamicharts
@@ -15,4 +15,4 @@ name: eodag-server
 sources:
 - https://github.com/CS-SI/eodag
 type: application
-version: 3.9.1
+version: 3.10.0


=====================================
debian/changelog
=====================================
@@ -1,10 +1,18 @@
-eodag (3.9.1+ds-2) UNRELEASED; urgency=medium
+eodag (3.10.1+ds-2) UNRELEASED; urgency=medium
 
   * Team upload.
   * Use test-build-validate-cleanup instead of test-build-twice.
 
  -- Bas Couwenberg <sebastic at debian.org>  Sat, 25 Oct 2025 12:55:57 +0200
 
+eodag (3.10.0+ds-1) unstable; urgency=medium
+
+  * New upstream release.
+  * debian/patches:
+    - Refresh all patches.
+
+ -- Antonio Valentino <antonio.valentino at tiscali.it>  Thu, 23 Oct 2025 05:44:35 +0000
+
 eodag (3.9.1+ds-1) unstable; urgency=medium
 
   [ Bas Couwenberg ]


=====================================
debian/patches/0002-System-importlib.metadata.patch
=====================================
@@ -33,7 +33,7 @@ index f66b5f9..1049af9 100644
              ):
                  try:
 diff --git a/setup.cfg b/setup.cfg
-index ce11547..793fb06 100644
+index 405810b..021734c 100644
 --- a/setup.cfg
 +++ b/setup.cfg
 @@ -43,7 +43,6 @@ install_requires =


=====================================
debian/patches/0003-no-mypy-boto3-s3.patch
=====================================
@@ -8,12 +8,12 @@ Forwarded: not-needed
  1 file changed, 7 insertions(+), 1 deletion(-)
 
 diff --git a/tests/units/test_auth_plugins.py b/tests/units/test_auth_plugins.py
-index 2f60914..123dc06 100644
+index 791c426..0bd8e1e 100644
 --- a/tests/units/test_auth_plugins.py
 +++ b/tests/units/test_auth_plugins.py
-@@ -22,7 +22,12 @@ from datetime import datetime, timedelta
- from unittest import mock
+@@ -23,7 +23,12 @@ from unittest import mock
  
+ import boto3
  import responses
 -from mypy_boto3_s3.service_resource import BucketObjectsCollection
 +try:
@@ -25,7 +25,7 @@ index 2f60914..123dc06 100644
  from pystac.utils import now_in_utc
  from requests import Request, Response, Timeout
  from requests.auth import AuthBase
-@@ -688,6 +693,7 @@ class TestAuthPluginAwsAuth(BaseAuthPluginTest):
+@@ -691,6 +696,7 @@ class TestAuthPluginAwsAuth(BaseAuthPluginTest):
          keys_dict = {"aws_profile": self.profile_name}
          self.assertDictEqual(keys_dict, plugin_auth_profile.config.credentials)
  


=====================================
docs/conf.py
=====================================
@@ -258,6 +258,7 @@ intersphinx_mapping = {
     "rasterio": ("https://rasterio.readthedocs.io/en/stable/", None),
     "rioxarray": ("https://corteva.github.io/rioxarray/stable/", None),
     "fsspec": ("https://filesystem-spec.readthedocs.io/en/stable/", None),
+    "pydantic": ("https://docs.pydantic.dev/latest", None),
 }
 
 suppress_warnings = ["misc.copy_overwrite"]


=====================================
docs/plugins.rst
=====================================
@@ -46,6 +46,8 @@ The providers are implemented with a triplet of *Search/Authentication/Download*
 +------------------------+------------------------------------+---------------------------------+------------------+
 | ``creodias``           | |QueryStringSearch|                | |KeycloakOIDCPasswordAuth|      | |HTTPDownload|   |
 +------------------------+------------------------------------+---------------------------------+------------------+
+| ``creodias_s3``        | |QueryStringSearch|                | |AwsAuth|                       | |AwsDownload|    |
++------------------------+------------------------------------+---------------------------------+------------------+
 | ``dedl``               | |StacSearch|                       | |OIDCTokenExchangeAuth|         | |HTTPDownload|   |
 +------------------------+------------------------------------+---------------------------------+------------------+
 | ``dedt_lumi``          | |ECMWFSearch|                      | |OIDCAuthorizationCodeFlowAuth| | |HTTPDownload|   |
@@ -98,7 +100,6 @@ The providers are implemented with a triplet of *Search/Authentication/Download*
 
 .. |AwsDownload| replace:: :class:`~eodag.plugins.download.aws.AwsDownload`
 .. |HTTPDownload| replace:: :class:`~eodag.plugins.download.http.HTTPDownload`
-.. |CreodiasS3Download| replace:: :class:`~eodag.plugins.download.creodias_s3.CreodiasS3Download`
 
 .. |QueryStringSearch| replace:: :class:`~eodag.plugins.search.qssearch.QueryStringSearch`
 .. |ODataV4Search| replace:: :class:`~eodag.plugins.search.qssearch.ODataV4Search`


=====================================
docs/stac_rest.rst
=====================================
@@ -99,7 +99,7 @@ available on `https://hub.docker.com/r/csspace/eodag-server <https://hub.docker.
 
 .. code-block:: bash
 
-    $ docker run -p 5000:5000 --rm csspace/eodag-server:3.9.1
+    $ docker run -p 5000:5000 --rm csspace/eodag-server:3.10.0
 
 Example
 -------


=====================================
eodag/plugins/authentication/aws_auth.py
=====================================
@@ -24,9 +24,11 @@ import boto3
 from botocore.exceptions import ClientError, ProfileNotFound
 from botocore.handlers import disable_signing
 
+from eodag.api.product._assets import Asset
 from eodag.plugins.authentication.base import Authentication
 from eodag.types import S3SessionKwargs
-from eodag.utils.exceptions import AuthenticationError
+from eodag.utils import get_bucket_name_and_prefix
+from eodag.utils.exceptions import AuthenticationError, EodagError
 
 if TYPE_CHECKING:
     from mypy_boto3_s3 import S3Client, S3ServiceResource
@@ -283,3 +285,36 @@ class AwsAuth(Authentication):
             "session": self.s3_session,
             **rio_env_kwargs,
         }
+
+    def presign_url(
+        self,
+        asset: Asset,
+        expires_in: int = 3600,
+    ) -> str:
+        """This method is used to presign a url to download an asset from S3.
+
+        :param asset: asset for which the url shall be presigned
+        :param expires_in: expiration time of the presigned url in seconds
+        :returns: presigned url
+        :raises: :class:`~eodag.utils.exceptions.EodagError`
+        :raises: :class:`NotImplementedError`
+        """
+        if not getattr(self.config, "support_presign_url", True):
+            raise NotImplementedError(
+                f"presign_url is not supported for provider {self.provider}"
+            )
+
+        s3_client = self.get_s3_client()
+        bucket, prefix = get_bucket_name_and_prefix(asset["href"])
+        try:
+            presigned_url = s3_client.generate_presigned_url(
+                "get_object",
+                Params={
+                    "Bucket": bucket,
+                    "Key": prefix,
+                },
+                ExpiresIn=expires_in,
+            )
+            return presigned_url
+        except ClientError:
+            raise EodagError(f"Couldn't get a presigned URL for '{asset}'.")


=====================================
eodag/plugins/authentication/base.py
=====================================
@@ -19,6 +19,7 @@ from __future__ import annotations
 
 from typing import TYPE_CHECKING, Any, Optional, Union
 
+from eodag.api.product._assets import Asset
 from eodag.plugins.base import PluginTopic
 from eodag.utils.exceptions import MisconfiguredError
 
@@ -80,3 +81,19 @@ class Authentication(PluginTopic):
         Authenticates with s3 and retrieves the available objects
         """
         raise NotImplementedError
+
+    def presign_url(
+        self,
+        asset: Asset,
+        expires_in: int = 3600,
+    ) -> str:
+        """This method is used to presign a url to download an asset from S3.
+
+        :param asset: asset for which the url shall be presigned
+        :param expires_in: expiration time of the presigned url in seconds
+        :returns: presigned url
+        :raises: :class:`NotImplementedError`
+        """
+        raise NotImplementedError(
+            f"presign_url is not implemented for plugin {type(self).__name__}"
+        )


=====================================
eodag/plugins/authentication/sas_auth.py
=====================================
@@ -25,6 +25,7 @@ from typing import TYPE_CHECKING, Optional
 import requests
 from requests.auth import AuthBase
 
+from eodag.api.product._assets import Asset
 from eodag.plugins.authentication.base import Authentication
 from eodag.utils import HTTP_REQ_TIMEOUT, USER_AGENT, deepcopy, format_dict_items
 from eodag.utils.exceptions import AuthenticationError, TimeOutError
@@ -143,3 +144,17 @@ class SASAuth(Authentication):
             ssl_verify=ssl_verify,
             matching_url=matching_url,
         )
+
+    def presign_url(
+        self,
+        asset: Asset,
+        expires_in: int = 3600,
+    ) -> str:
+        """This method is used to presign a url to download an asset.
+
+        :param asset: asset for which the url shall be presigned
+        :param expires_in: expiration time of the presigned url in seconds
+        :returns: presigned url
+        """
+        url = asset["href"]
+        return self.config.auth_uri.format(url=url)


=====================================
eodag/plugins/download/creodias_s3.py
=====================================
@@ -15,12 +15,19 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+from __future__ import annotations
+
 from typing import Optional
 
 from eodag import EOProduct
 from eodag.plugins.download.aws import AwsDownload
+from eodag.utils import _deprecated
 
 
+ at _deprecated(
+    reason="Plugin that was used in creodias_s3 provider configuration, but not anymore",
+    version="3.10.0",
+)
 class CreodiasS3Download(AwsDownload):
     """
     Download on creodias s3 from their VMs (extension of :class:`~eodag.plugins.download.aws.AwsDownload`)


=====================================
eodag/resources/ext_collections.json
=====================================
The diff for this file was not included because it is too large.

=====================================
eodag/resources/ext_product_types.json
=====================================
The diff for this file was not included because it is too large.

=====================================
eodag/resources/providers.yml
=====================================
@@ -1498,6 +1498,7 @@
     type: AwsAuth
     matching_url: s3://
     s3_endpoint: https://storage.googleapis.com
+    support_presign_url: False
     matching_conf:
       s3_endpoint: https://storage.googleapis.com
 ---
@@ -2078,6 +2079,14 @@
       period: 1_5_c
     CMIP6_CLIMATE_PROJECTIONS:
       dataset: projections-cmip6
+      experiment: historical
+      variable: air_temperature
+      model: access_cm2
+      level: ["1"]
+      year: ["1850"]
+      month: ["01"]
+      metadata_mapping:
+        <<: *month_year
     GENERIC_PRODUCT_TYPE:
       dataset: '{productType}'
 ---
@@ -4295,7 +4304,7 @@
       quicklook: '$.Assets[?(@.Type="QUICKLOOK")].DownloadLink'
       thumbnail: '$.Assets[?(@.Type="QUICKLOOK")].DownloadLink'
   download: !plugin
-    type: CreodiasS3Download
+    type: AwsDownload
     s3_endpoint: 'https://eodata.cloudferro.com'
     s3_bucket: 'eodata'
     ssl_verify: true
@@ -4303,6 +4312,7 @@
     type: AwsAuth
     auth_error_code: 403
     s3_endpoint: 'https://eodata.cloudferro.com'
+    support_presign_url: False
     matching_conf:
       s3_endpoint: 'https://eodata.cloudferro.com'
   products:


=====================================
pyproject.toml
=====================================
@@ -3,7 +3,7 @@ requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"]
 build-backend = "setuptools.build_meta"
 
 [tool.setuptools_scm]
-fallback_version = "3.9.2.dev0"
+fallback_version = "3.10.1.dev0"
 
 [tool.coverage.report]
 exclude_lines = [


=====================================
setup.cfg
=====================================
@@ -47,7 +47,7 @@ install_requires =
     jsonpath-ng
     lxml
     orjson
-    pydantic >= 2.1.0, != 2.10.0
+    pydantic >= 2.1.0, != 2.10.0, < 2.12.0
     pydantic_core
     PyJWT[crypto] >= 2.5.0
     pyproj >= 2.1.0


=====================================
tests/units/test_auth_plugins.py
=====================================
@@ -21,6 +21,7 @@ import unittest
 from datetime import datetime, timedelta
 from unittest import mock
 
+import boto3
 import responses
 from mypy_boto3_s3.service_resource import BucketObjectsCollection
 from pystac.utils import now_in_utc
@@ -28,6 +29,7 @@ from requests import Request, Response, Timeout
 from requests.auth import AuthBase
 from requests.exceptions import RequestException
 
+from eodag.api.product._product import EOProduct
 from eodag.config import override_config_from_mapping
 from eodag.plugins.authentication.openid_connect import CodeAuthorizedAuth
 from eodag.utils import MockResponse
@@ -587,6 +589,7 @@ class TestAuthPluginAwsAuth(BaseAuthPluginTest):
                             "aws_access_key_id": cls.aws_access_key_id,
                             "aws_secret_access_key": cls.aws_secret_access_key,
                         },
+                        "s3_endpoint": "https://s3.abc.test.com",
                     },
                 },
                 "provider_with_auth_keys_session": {
@@ -728,6 +731,40 @@ class TestAuthPluginAwsAuth(BaseAuthPluginTest):
         auth_objects = plugin.authenticate_objects(buckets_prefixes)
         self.assertDictEqual({"a": auth_objects_a, "b": auth_objects_b}, auth_objects)
 
+    @mock.patch(
+        "eodag.plugins.authentication.aws_auth.AwsAuth._create_s3_resource",
+        autospec=True,
+    )
+    def test_plugins_download_aws_presigned_url(self, mock_s3_resource):
+        """should create a presigned url to download from S3"""
+        # provider with no credentials required
+        provider = "provider_with_auth_keys"
+        product_type = "foo_product"
+        product = EOProduct(
+            provider,
+            dict(
+                geometry="POINT (0 0)",
+                title="dummy_product",
+                id="dummy",
+            ),
+            productType=product_type,
+        )
+        product.assets.update({"a1": {"href": "https://s3.abc.test.com/b1/a1/a1.json"}})
+        product.assets.update({"a2": {"href": "https://s3.abc.test.com/b1/a2/a2.json"}})
+        mock_s3_resource.return_value = boto3.resource(
+            service_name="s3",
+            endpoint_url="https://s3.abc.test.com",
+            aws_access_key_id=self.aws_access_key_id,
+            aws_secret_access_key=self.aws_secret_access_key,
+        )
+
+        auth_plugin = self.get_auth_plugin("provider_with_auth_keys")
+        auth_plugin.authenticate()
+        url = auth_plugin.presign_url(product.assets["a1"])
+        self.assertIn("https://s3.abc.test.com/b1/a1/a1.json", url)
+        self.assertIn("AWSAccessKeyId=my_access_key", url)
+        self.assertIn("Expires", url)
+
 
 class TestAuthPluginHTTPHeaderAuth(BaseAuthPluginTest):
     @classmethod
@@ -993,6 +1030,29 @@ class TestAuthPluginSASAuth(BaseAuthPluginTest):
         with self.assertRaises(AuthenticationError):
             auth(req)
 
+    def test_plugins_download_http_presign_url(self):
+        """should create a presigned url to download via HTTP"""
+        provider = "foo_provider"
+        product_type = "LANDSAT_C2_L1"
+        product = EOProduct(
+            provider,
+            dict(
+                geometry="POINT (0 0)",
+                title="dummy_product",
+                id="dummy",
+            ),
+            productType=product_type,
+        )
+        product.assets.update({"a1": {"href": "http://foo.bar.com/b1/a1/a1.json"}})
+        product.assets.update({"a2": {"href": "http://foo.bar.com/b1/a2/a2.json"}})
+
+        auth_plugin = self.get_auth_plugin("foo_provider")
+        url = auth_plugin.presign_url(product.assets["a1"])
+        expected_url = "http://foo.bar?href={url}".format(
+            url="http://foo.bar.com/b1/a1/a1.json"
+        )
+        self.assertEqual(expected_url, url)
+
 
 class TestAuthPluginKeycloakOIDCPasswordAuth(BaseAuthPluginTest):
     @classmethod


=====================================
tests/units/test_download_plugins.py
=====================================
@@ -2627,72 +2627,3 @@ class TestDownloadPluginCreodiasS3(BaseDownloadPluginTest):
         self.assertEqual(mock_finalize_s2_safe_product.call_count, 0)
         self.assertEqual(mock_check_manifest_file_list.call_count, 0)
         self.assertEqual(mock_flatten_top_directories.call_count, 1)
-
-    @mock.patch("eodag.plugins.download.aws.flatten_top_directories", autospec=True)
-    @mock.patch(
-        "eodag.plugins.download.aws.AwsDownload.check_manifest_file_list", autospec=True
-    )
-    @mock.patch(
-        "eodag.plugins.download.aws.AwsDownload.finalize_s2_safe_product", autospec=True
-    )
-    @mock.patch(
-        "eodag.plugins.download.aws.AwsDownload.get_chunk_dest_path", autospec=True
-    )
-    @mock.patch(
-        "eodag.plugins.authentication.aws_auth.AwsAuth._get_authenticated_objects",
-        autospec=True,
-    )
-    @mock.patch(
-        "eodag.plugins.authentication.aws_auth.create_s3_session",
-        autospec=True,
-    )
-    @mock.patch(
-        "eodag.plugins.authentication.aws_auth.AwsAuth._create_s3_resource",
-        autospec=True,
-    )
-    @mock.patch(
-        "eodag.plugins.authentication.aws_auth.AwsAuth.get_s3_client",
-        autospec=True,
-    )
-    @mock.patch("eodag.plugins.download.aws.requests.get", autospec=True)
-    def test_plugins_download_creodias_s3_without_assets(
-        self,
-        mock_requests_get,
-        mock_s3_client,
-        mock_s3_resource,
-        mock_s3_session,
-        mock_get_authenticated_objects,
-        mock_get_chunk_dest_path,
-        mock_finalize_s2_safe_product,
-        mock_check_manifest_file_list,
-        mock_flatten_top_directories,
-    ):
-        product = EOProduct(
-            "creodias_s3",
-            dict(
-                geometry="POINT (0 0)",
-                title="dummy_product",
-                id="dummy",
-                productIdentifier="/eodata/01/a.tar",
-            ),
-        )
-        product.location = product.remote_location = "a"
-        plugin = self.get_download_plugin(product)
-        auth_plugin = self.get_auth_plugin(associated_plugin=plugin, product=product)
-        product.downloader_auth = auth_plugin
-        product.properties["tileInfo"] = "http://example.com/tileInfo.json"
-        # authenticated objects mock
-        mock_get_authenticated_objects.return_value.keys.return_value = ["a.tar"]
-        mock_get_authenticated_objects.return_value.filter.side_effect = (
-            lambda *x, **y: [mock.Mock(size=0, key=y["Prefix"])]
-        )
-
-        plugin.download(product, output_dir=self.output_dir, auth={})
-
-        mock_get_authenticated_objects.assert_called_once_with(
-            auth_plugin, "eodata", "01"
-        )
-        self.assertEqual(mock_get_chunk_dest_path.call_count, 1)
-        self.assertEqual(mock_finalize_s2_safe_product.call_count, 0)
-        self.assertEqual(mock_check_manifest_file_list.call_count, 0)
-        self.assertEqual(mock_flatten_top_directories.call_count, 1)



View it on GitLab: https://salsa.debian.org/debian-gis-team/eodag/-/compare/0d3abb767bed64f0f0310365a3bbffd6a28563d7...f7b398b247a30db9f6cc293645190cec7c367f26

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/eodag/-/compare/0d3abb767bed64f0f0310365a3bbffd6a28563d7...f7b398b247a30db9f6cc293645190cec7c367f26
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20251102/b24dcd2c/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list