eodag 3.1.0b1__py3-none-any.whl → 3.1.0b2__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 (85) hide show
  1. eodag/api/core.py +59 -52
  2. eodag/api/product/_assets.py +5 -5
  3. eodag/api/product/_product.py +27 -12
  4. eodag/api/product/drivers/__init__.py +81 -4
  5. eodag/api/product/drivers/base.py +65 -4
  6. eodag/api/product/drivers/generic.py +65 -0
  7. eodag/api/product/drivers/sentinel1.py +97 -0
  8. eodag/api/product/drivers/sentinel2.py +95 -0
  9. eodag/api/product/metadata_mapping.py +62 -74
  10. eodag/api/search_result.py +13 -23
  11. eodag/cli.py +4 -4
  12. eodag/config.py +66 -69
  13. eodag/plugins/apis/base.py +1 -1
  14. eodag/plugins/apis/ecmwf.py +10 -9
  15. eodag/plugins/apis/usgs.py +11 -10
  16. eodag/plugins/authentication/aws_auth.py +16 -13
  17. eodag/plugins/authentication/base.py +5 -3
  18. eodag/plugins/authentication/header.py +3 -3
  19. eodag/plugins/authentication/keycloak.py +4 -4
  20. eodag/plugins/authentication/oauth.py +7 -3
  21. eodag/plugins/authentication/openid_connect.py +14 -14
  22. eodag/plugins/authentication/sas_auth.py +4 -4
  23. eodag/plugins/authentication/token.py +7 -7
  24. eodag/plugins/authentication/token_exchange.py +1 -1
  25. eodag/plugins/base.py +4 -4
  26. eodag/plugins/crunch/base.py +4 -4
  27. eodag/plugins/crunch/filter_date.py +4 -4
  28. eodag/plugins/crunch/filter_latest_intersect.py +6 -6
  29. eodag/plugins/crunch/filter_latest_tpl_name.py +7 -7
  30. eodag/plugins/crunch/filter_overlap.py +4 -4
  31. eodag/plugins/crunch/filter_property.py +4 -4
  32. eodag/plugins/download/aws.py +47 -66
  33. eodag/plugins/download/base.py +8 -17
  34. eodag/plugins/download/creodias_s3.py +2 -2
  35. eodag/plugins/download/http.py +30 -32
  36. eodag/plugins/download/s3rest.py +5 -4
  37. eodag/plugins/manager.py +10 -20
  38. eodag/plugins/search/__init__.py +6 -5
  39. eodag/plugins/search/base.py +35 -40
  40. eodag/plugins/search/build_search_result.py +69 -68
  41. eodag/plugins/search/cop_marine.py +22 -12
  42. eodag/plugins/search/creodias_s3.py +8 -78
  43. eodag/plugins/search/csw.py +11 -11
  44. eodag/plugins/search/data_request_search.py +16 -15
  45. eodag/plugins/search/qssearch.py +56 -52
  46. eodag/plugins/search/stac_list_assets.py +85 -0
  47. eodag/plugins/search/static_stac_search.py +3 -3
  48. eodag/resources/ext_product_types.json +1 -1
  49. eodag/resources/product_types.yml +288 -288
  50. eodag/resources/providers.yml +146 -6
  51. eodag/resources/stac_api.yml +2 -2
  52. eodag/resources/user_conf_template.yml +11 -0
  53. eodag/rest/cache.py +2 -2
  54. eodag/rest/config.py +3 -3
  55. eodag/rest/core.py +24 -24
  56. eodag/rest/errors.py +5 -5
  57. eodag/rest/server.py +3 -11
  58. eodag/rest/stac.py +40 -38
  59. eodag/rest/types/collections_search.py +3 -3
  60. eodag/rest/types/eodag_search.py +23 -23
  61. eodag/rest/types/queryables.py +13 -13
  62. eodag/rest/types/stac_search.py +15 -25
  63. eodag/rest/utils/__init__.py +11 -21
  64. eodag/rest/utils/cql_evaluate.py +6 -6
  65. eodag/rest/utils/rfc3339.py +2 -2
  66. eodag/types/__init__.py +24 -18
  67. eodag/types/bbox.py +2 -2
  68. eodag/types/download_args.py +2 -2
  69. eodag/types/queryables.py +5 -2
  70. eodag/types/search_args.py +4 -4
  71. eodag/types/whoosh.py +1 -3
  72. eodag/utils/__init__.py +81 -40
  73. eodag/utils/exceptions.py +2 -2
  74. eodag/utils/import_system.py +2 -2
  75. eodag/utils/requests.py +2 -2
  76. eodag/utils/rest.py +2 -2
  77. eodag/utils/s3.py +208 -0
  78. eodag/utils/stac_reader.py +10 -10
  79. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/METADATA +5 -4
  80. eodag-3.1.0b2.dist-info/RECORD +113 -0
  81. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/entry_points.txt +1 -0
  82. eodag-3.1.0b1.dist-info/RECORD +0 -108
  83. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/LICENSE +0 -0
  84. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/WHEEL +0 -0
  85. {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/top_level.txt +0 -0
@@ -17,15 +17,72 @@
17
17
  # limitations under the License.
18
18
  from __future__ import annotations
19
19
 
20
- from typing import TYPE_CHECKING
20
+ import logging
21
+ import re
22
+ from typing import TYPE_CHECKING, Optional, TypedDict
23
+
24
+ from eodag.utils import _deprecated
21
25
 
22
26
  if TYPE_CHECKING:
23
27
  from eodag.api.product import EOProduct
24
28
 
25
29
 
30
+ class AssetPatterns(TypedDict):
31
+ """Asset patterns definition"""
32
+
33
+ #: pattern to match and extract asset key
34
+ pattern: re.Pattern
35
+ #: roles associated to the asset key
36
+ roles: list[str]
37
+
38
+
39
+ logger = logging.getLogger("eodag.driver.base")
40
+
41
+
26
42
  class DatasetDriver(metaclass=type):
27
- """Dataset driver"""
43
+ """Parent class for all dataset drivers.
44
+
45
+ Drivers will provide methods adapted to a given :class:`~eodag.api.product._product.EOProduct` related to predefined
46
+ criteria.
47
+ """
48
+
49
+ #: legacy driver for deprecated :meth:`~eodag_cube.api.product._product.EOProduct.get_data` method usage
50
+ legacy: DatasetDriver
28
51
 
52
+ #: list of patterns to match asset keys and roles
53
+ ASSET_KEYS_PATTERNS_ROLES: list[AssetPatterns] = []
54
+
55
+ #: strip non-alphanumeric characters at the beginning and end of the key
56
+ STRIP_SPECIAL_PATTERN = re.compile(r"^[^A-Z0-9]+|[^A-Z0-9]+$", re.IGNORECASE)
57
+
58
+ def _normalize_key(self, key, eo_product):
59
+ # default cleanup
60
+ norm_key = key.replace(eo_product.properties.get("id", ""), "")
61
+ norm_key = re.sub(self.STRIP_SPECIAL_PATTERN, "", norm_key)
62
+
63
+ return norm_key
64
+
65
+ def guess_asset_key_and_roles(
66
+ self, href: str, eo_product: EOProduct
67
+ ) -> tuple[Optional[str], Optional[list[str]]]:
68
+ """Guess the asset key and roles from the given href.
69
+
70
+ :param href: The asset href
71
+ :param eo_product: The product to which the asset belongs
72
+ :returns: The asset key and roles
73
+ """
74
+ for pattern_dict in self.ASSET_KEYS_PATTERNS_ROLES:
75
+ if matched := pattern_dict["pattern"].match(href):
76
+ extracted_key, roles = (
77
+ "".join([m for m in matched.groups() if m is not None]),
78
+ pattern_dict.get("roles"),
79
+ )
80
+ normalized_key = self._normalize_key(extracted_key, eo_product)
81
+ return normalized_key or extracted_key, roles
82
+ logger.debug(f"No key & roles could be guessed for {href}")
83
+ return None, None
84
+
85
+ @_deprecated(reason="Method used by deprecated get_data", version="3.1.0")
29
86
  def get_data_address(self, eo_product: EOProduct, band: str) -> str:
30
87
  """Retrieve the address of the dataset represented by `eo_product`.
31
88
 
@@ -34,12 +91,16 @@ class DatasetDriver(metaclass=type):
34
91
  :returns: An address for the dataset
35
92
  :raises: :class:`~eodag.utils.exceptions.AddressNotFound`
36
93
  :raises: :class:`~eodag.utils.exceptions.UnsupportedDatasetAddressScheme`
94
+
95
+ .. deprecated:: 3.1.0
96
+ Method used by deprecated :meth:`~eodag_cube.api.product._product.EOProduct.get_data`
37
97
  """
38
98
  raise NotImplementedError
39
99
 
40
100
 
41
101
  class NoDriver(DatasetDriver):
42
- """A default driver that does not implement any of the methods it should implement, used for all product types for
43
- which the :meth:`~eodag.api.product._product.EOProduct.get_data` method is not yet implemented in eodag. Expect a
102
+ """A default :attr:`~eodag.api.product.drivers.base.DatasetDriver.legacy` driver that does not implement any of the
103
+ methods it should implement, used for all product types for which the deprecated
104
+ :meth:`~eodag_cube.api.product._product.EOProduct.get_data` method is not implemented. Expect a
44
105
  :exc:`NotImplementedError` when trying to get the data in that case.
45
106
  """
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2021, CS GROUP - France, http://www.c-s.fr
3
+ #
4
+ # This file is part of EODAG project
5
+ # https://www.github.com/CS-SI/EODAG
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ from __future__ import annotations
19
+
20
+ import logging
21
+ import re
22
+
23
+ from eodag.api.product.drivers.base import AssetPatterns, DatasetDriver
24
+
25
+ logger = logging.getLogger("eodag.driver.generic")
26
+
27
+
28
+ class GenericDriver(DatasetDriver):
29
+ """Generic default Driver"""
30
+
31
+ #: list of patterns to match asset keys and roles
32
+ ASSET_KEYS_PATTERNS_ROLES: list[AssetPatterns] = [
33
+ # data
34
+ {
35
+ "pattern": re.compile(
36
+ r"^(?:.*[/\\])?([^/\\]+)(\.jp2|\.tiff?|\.dat|\.nc|\.grib2?)$",
37
+ re.IGNORECASE,
38
+ ),
39
+ "roles": ["data"],
40
+ },
41
+ # metadata
42
+ {
43
+ "pattern": re.compile(
44
+ r"^(?:.*[/\\])?([^/\\]+)(\.xml|\.xsd|\.safe|\.json)$", re.IGNORECASE
45
+ ),
46
+ "roles": ["metadata"],
47
+ },
48
+ # thumbnail
49
+ {
50
+ "pattern": re.compile(
51
+ r"^(?:.*[/\\])?(thumbnail)(\.jpg|\.jpeg|\.png)$", re.IGNORECASE
52
+ ),
53
+ "roles": ["thumbnail"],
54
+ },
55
+ # quicklook
56
+ {
57
+ "pattern": re.compile(
58
+ r"^(?:.*[/\\])?([^/\\]+-ql|preview|quick-?look)(\.jpg|\.jpeg|\.png)$",
59
+ re.IGNORECASE,
60
+ ),
61
+ "roles": ["overview"],
62
+ },
63
+ # default
64
+ {"pattern": re.compile(r"^(?:.*[/\\])?([^/\\]+)$"), "roles": ["auxiliary"]},
65
+ ]
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2025, CS GROUP - France, http://www.c-s.fr
3
+ #
4
+ # This file is part of EODAG project
5
+ # https://www.github.com/CS-SI/EODAG
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ from __future__ import annotations
19
+
20
+ import re
21
+ from typing import TYPE_CHECKING
22
+
23
+ from eodag.api.product.drivers.base import AssetPatterns, DatasetDriver
24
+
25
+ if TYPE_CHECKING:
26
+ from eodag.api.product._product import EOProduct
27
+
28
+
29
+ class Sentinel1Driver(DatasetDriver):
30
+ """Driver for Sentinel1 products"""
31
+
32
+ #: pattern to match data-role keys
33
+ DATA_PATTERN = re.compile(r"[vh]{2}", re.IGNORECASE)
34
+
35
+ #: list of patterns to replace in asset keys
36
+ REPLACE_PATTERNS = [
37
+ (re.compile(r"s1a?", re.IGNORECASE), ""),
38
+ (re.compile(r"grd", re.IGNORECASE), ""),
39
+ (re.compile(r"slc", re.IGNORECASE), ""),
40
+ (re.compile(r"ocn", re.IGNORECASE), ""),
41
+ (re.compile(r"iw", re.IGNORECASE), ""),
42
+ (re.compile(r"ew", re.IGNORECASE), ""),
43
+ (re.compile(r"wv", re.IGNORECASE), ""),
44
+ (re.compile(r"sm", re.IGNORECASE), ""),
45
+ (re.compile(r"raw([-_]s)?", re.IGNORECASE), ""),
46
+ (re.compile(r"[t?0-9]{3,}", re.IGNORECASE), ""),
47
+ (re.compile(r"-+"), "-"),
48
+ (re.compile(r"-+\."), "."),
49
+ (re.compile(r"_+"), "_"),
50
+ (re.compile(r"_+\."), "."),
51
+ ]
52
+
53
+ #: list of patterns to match asset keys and roles
54
+ ASSET_KEYS_PATTERNS_ROLES: list[AssetPatterns] = [
55
+ # data
56
+ {
57
+ "pattern": re.compile(
58
+ r"^.*?([vh]{2}).*\.(?:jp2|tiff?|dat)$", re.IGNORECASE
59
+ ),
60
+ "roles": ["data"],
61
+ },
62
+ # metadata
63
+ {
64
+ "pattern": re.compile(
65
+ r"^(?:.*[/\\])?([^/\\]+)(\.xml|\.xsd|\.safe|\.json)$", re.IGNORECASE
66
+ ),
67
+ "roles": ["metadata"],
68
+ },
69
+ # thumbnail
70
+ {
71
+ "pattern": re.compile(
72
+ r"^(?:.*[/\\])?(thumbnail)(\.jpe?g|\.png)$", re.IGNORECASE
73
+ ),
74
+ "roles": ["thumbnail"],
75
+ },
76
+ # quicklook
77
+ {
78
+ "pattern": re.compile(
79
+ r"^(?:.*[/\\])?([^/\\]+-ql|preview|quick-?look)(\.jpe?g|\.png)$",
80
+ re.IGNORECASE,
81
+ ),
82
+ "roles": ["overview"],
83
+ },
84
+ # default
85
+ {"pattern": re.compile(r"^(?:.*[/\\])?([^/\\]+)$"), "roles": ["auxiliary"]},
86
+ ]
87
+
88
+ def _normalize_key(self, key: str, eo_product: EOProduct) -> str:
89
+ if self.DATA_PATTERN.fullmatch(key):
90
+ return key.upper()
91
+
92
+ key = super()._normalize_key(key, eo_product)
93
+
94
+ for pattern, replacement in self.REPLACE_PATTERNS:
95
+ key = pattern.sub(replacement, key)
96
+
97
+ return super()._normalize_key(key, eo_product)
@@ -0,0 +1,95 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2021, CS GROUP - France, http://www.c-s.fr
3
+ #
4
+ # This file is part of EODAG project
5
+ # https://www.github.com/CS-SI/EODAG
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ from __future__ import annotations
19
+
20
+ import re
21
+ from typing import TYPE_CHECKING
22
+
23
+ from eodag.api.product.drivers.base import AssetPatterns, DatasetDriver
24
+
25
+ if TYPE_CHECKING:
26
+ from eodag.api.product._product import EOProduct
27
+
28
+
29
+ class Sentinel2Driver(DatasetDriver):
30
+ """Driver for Sentinel2 products"""
31
+
32
+ #: Band keys associated with their default Ground Sampling Distance (GSD)
33
+ BANDS_DEFAULT_GSD = {
34
+ "10M": ("B02", "B03", "B04", "B08", "TCI"),
35
+ "20M": ("B05", "B06", "B07", "B11", "B12", "B8A"),
36
+ "60M": ("B01", "B09", "B10"),
37
+ }
38
+
39
+ #: list of patterns to match asset keys and roles
40
+ ASSET_KEYS_PATTERNS_ROLES: list[AssetPatterns] = [
41
+ # masks
42
+ {
43
+ "pattern": re.compile(r"^.*?(MSK_[^/\\]+)\.(?:jp2|tiff?)$", re.IGNORECASE),
44
+ "roles": ["data-mask"],
45
+ },
46
+ # visual
47
+ {
48
+ "pattern": re.compile(
49
+ r"^.*?(TCI)(_[0-9]+m)?\.(?:jp2|tiff?)$", re.IGNORECASE
50
+ ),
51
+ "roles": ["visual"],
52
+ },
53
+ # bands
54
+ {
55
+ "pattern": re.compile(
56
+ r"^.*?([A-Z]+[0-9]*[A-Z]?)(_[0-9]+m)?\.(?:jp2|tiff?)$", re.IGNORECASE
57
+ ),
58
+ "roles": ["data"],
59
+ },
60
+ # metadata
61
+ {
62
+ "pattern": re.compile(
63
+ r"^(?:.*[/\\])?([^/\\]+)(\.xml|\.xsd|\.safe|\.json)$", re.IGNORECASE
64
+ ),
65
+ "roles": ["metadata"],
66
+ },
67
+ # thumbnail
68
+ {
69
+ "pattern": re.compile(
70
+ r"^(?:.*[/\\])?(thumbnail)(\.jpe?g|\.png)$", re.IGNORECASE
71
+ ),
72
+ "roles": ["thumbnail"],
73
+ },
74
+ # quicklook
75
+ {
76
+ "pattern": re.compile(
77
+ r"^(?:.*[/\\])?[^/\\]+(-ql|preview|quick-?look)(\.jpe?g|\.png)$",
78
+ re.IGNORECASE,
79
+ ),
80
+ "roles": ["overview"],
81
+ },
82
+ # default
83
+ {"pattern": re.compile(r"^(?:.*[/\\])?([^/\\]+)$"), "roles": ["auxiliary"]},
84
+ ]
85
+
86
+ def _normalize_key(self, key: str, eo_product: EOProduct) -> str:
87
+ upper_key = key.upper()
88
+ # check if key matched any normalized
89
+ for res in self.BANDS_DEFAULT_GSD:
90
+ if res in upper_key:
91
+ for norm_key in self.BANDS_DEFAULT_GSD[res]:
92
+ if norm_key in upper_key:
93
+ return norm_key
94
+
95
+ return super()._normalize_key(key, eo_product)