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
@@ -41,15 +41,10 @@ def get_constraint_queryables_with_additional_params(
41
41
  gets the queryables from the constraints using the given parameters
42
42
  For all queryables only values matching the given parameters based on the constraints will be returned
43
43
  :param constraints: list of constraints fetched from the provider
44
- :type constraints: List[Any]
45
44
  :param input_params: conditions the constraints should fulfil
46
- :type input_params: dict
47
45
  :param plugin: search or api plugin that is used
48
- :type plugin: Union[Search, Api]
49
46
  :param product_type: product type for which the data should be fetched
50
- :type product_type: str
51
47
  :returns: dict containing queryable data
52
- :rtype: Dict[str, Dict[str, Set[Any]]]
53
48
  """
54
49
  defaults = copy.deepcopy(input_params)
55
50
  constraint_matches = {}
@@ -174,11 +169,8 @@ def fetch_constraints(
174
169
  """
175
170
  fetches the constraints from a provider
176
171
  :param constraints_url: url from which the constraints can be fetched
177
- :type constraints_url: str
178
172
  :param plugin: api or search plugin of the provider
179
- :type plugin: Union[Search, Api]
180
173
  :returns: list of constraints fetched from the provider
181
- :rtype: List[Dict[Any, Any]]
182
174
  """
183
175
  auth = (
184
176
  plugin.auth
eodag/utils/exceptions.py CHANGED
@@ -17,10 +17,12 @@
17
17
  # limitations under the License.
18
18
  from __future__ import annotations
19
19
 
20
- from typing import TYPE_CHECKING
20
+ from typing import TYPE_CHECKING, Annotated
21
21
 
22
22
  if TYPE_CHECKING:
23
- from typing import Optional, Set, Tuple
23
+ from typing import Optional, Set
24
+
25
+ from typing_extensions import Doc
24
26
 
25
27
 
26
28
  class EodagError(Exception):
@@ -84,14 +86,26 @@ class RequestError(EodagError):
84
86
  """An error indicating that a request has failed. Usually eodag functions
85
87
  and methods should catch and skip this"""
86
88
 
87
- history: Set[Tuple[str, Exception]] = set()
88
- parameters: Set[str] = set()
89
+ status_code: Annotated[Optional[int], Doc("HTTP status code")] = None
90
+
91
+ @classmethod
92
+ def from_error(cls, error: Exception, msg: Optional[str] = None):
93
+ """Generate a RequestError from an Exception"""
94
+ status_code = getattr(error, "code", None)
95
+ text = getattr(error, "msg", None)
96
+
97
+ response = getattr(error, "response", None)
98
+ # Explicitly test for None because response objects are considered false if they
99
+ # have a status code other than 200
100
+ if response is not None:
101
+ status_code = response.status_code
102
+ text = response.text
103
+
104
+ text = text or str(error)
89
105
 
90
- def __str__(self):
91
- repr = super().__str__()
92
- for err_tuple in self.history:
93
- repr += f"- {str(err_tuple)}"
94
- return repr
106
+ e = cls(msg, text) if msg else cls(text)
107
+ e.status_code = status_code
108
+ return e
95
109
 
96
110
 
97
111
  class NoMatchingProductType(EodagError):
@@ -52,12 +52,9 @@ def import_all_modules(
52
52
  import_all_modules(base_package)
53
53
 
54
54
  :param base_package: The package from where we must import all the modules
55
- :type base_package: `module`
56
55
  :param depth: (optional) If `base_package` has sub packages, import all the modules recursively up to this level.
57
56
  Defaults to 1 (limits to the level of `base_package`)
58
- :type depth: int
59
57
  :param exclude: (optional) The sub packages and modules to ignore while importing. Empty by default
60
- :type exclude: tuple(str, ...)
61
58
 
62
59
  .. note::
63
60
  if `package` and `subpackage` have a module of the same name and this name is included in the exclude
@@ -88,7 +85,6 @@ def patch_owslib_requests(verify: bool = True) -> Generator[None, Any, None]:
88
85
  these functions in `owslib <https://geopython.github.io/OWSLib/>`_.
89
86
 
90
87
  :param verify: (optional) Whether to verify the use of https or not
91
- :type verify: bool
92
88
  """
93
89
  from owslib.util import requests
94
90
 
eodag/utils/logging.py CHANGED
@@ -32,95 +32,53 @@ def setup_logging(verbose: int, no_progress_bar: bool = False) -> None:
32
32
  * 1: no logging but still displays progress bars
33
33
  * 2: INFO level
34
34
  * 3: DEBUG level
35
- :type verbose: int
36
35
  :param no_progress_bar: (optional) Disable progress bars
37
- :type no_progress_bar: bool
38
36
  """
39
37
  global disable_tqdm
40
38
  disable_tqdm = no_progress_bar
41
39
 
40
+ if verbose > 3:
41
+ raise ValueError("'verbose' must be one of: 0, 1, 2, 3")
42
+
42
43
  if verbose < 1:
43
44
  disable_tqdm = True
44
45
 
45
- if verbose <= 1:
46
- logging.config.dictConfig(
47
- {
48
- "version": 1,
49
- "disable_existing_loggers": False,
50
- "handlers": {
51
- "null": {"level": "DEBUG", "class": "logging.NullHandler"}
52
- },
53
- "loggers": {
54
- "eodag": {"handlers": ["null"], "propagate": True, "level": "INFO"}
55
- },
56
- }
57
- )
58
- elif verbose == 2:
59
- logging.config.dictConfig(
60
- {
61
- "version": 1,
62
- "disable_existing_loggers": False,
63
- "formatters": {
64
- "standard": {
65
- "format": "%(asctime)-15s %(name)-32s [%(levelname)-8s] %(message)s"
66
- }
67
- },
68
- "handlers": {
69
- "console": {
70
- "level": "DEBUG",
71
- "class": "logging.StreamHandler",
72
- "formatter": "standard",
73
- }
74
- },
75
- "loggers": {
76
- "eodag": {
77
- "handlers": ["console"],
78
- "propagate": True,
79
- "level": "INFO",
80
- },
81
- "sentinelsat": {
82
- "handlers": ["console"],
83
- "propagate": True,
84
- "level": "INFO",
85
- },
86
- },
87
- }
88
- )
89
- elif verbose == 3:
90
- logging.config.dictConfig(
91
- {
92
- "version": 1,
93
- "disable_existing_loggers": False,
94
- "formatters": {
95
- "verbose": {
96
- "format": (
97
- "%(asctime)-15s %(name)-32s [%(levelname)-8s] (tid=%(thread)d) %(message)s"
98
- )
99
- }
100
- },
101
- "handlers": {
102
- "console": {
103
- "level": "DEBUG",
104
- "class": "logging.StreamHandler",
105
- "formatter": "verbose",
106
- }
46
+ level = "DEBUG" if verbose == 3 else "INFO"
47
+
48
+ handlers = {
49
+ "console": {
50
+ "level": level,
51
+ "class": "logging.StreamHandler",
52
+ "formatter": "standard",
53
+ },
54
+ "null": {"level": level, "class": "logging.NullHandler"},
55
+ }
56
+ handler = "console" if verbose > 1 else "null"
57
+
58
+ logging.config.dictConfig(
59
+ {
60
+ "version": 1,
61
+ "disable_existing_loggers": False,
62
+ "formatters": {
63
+ "standard": {
64
+ "format": "%(asctime)-15s %(name)-32s [%(levelname)-8s] %(message)s"
65
+ }
66
+ },
67
+ "handlers": handlers,
68
+ "loggers": {
69
+ "eodag": {
70
+ "handlers": [handler],
71
+ "propagate": True,
72
+ "level": f"{level}",
107
73
  },
108
- "loggers": {
109
- "eodag": {
110
- "handlers": ["console"],
111
- "propagate": True,
112
- "level": "DEBUG",
113
- },
114
- "sentinelsat": {
115
- "handlers": ["console"],
116
- "propagate": True,
117
- "level": "DEBUG",
118
- },
74
+ "eodag-cube": {
75
+ "handlers": [handler],
76
+ "propagate": True,
77
+ "level": f"{level}",
119
78
  },
120
- }
121
- )
122
- else:
123
- raise ValueError("'verbose' must be one of: 0, 1, 2, 3")
79
+ },
80
+ }
81
+ )
124
82
 
125
83
 
126
84
  def get_logging_verbose() -> Optional[int]:
@@ -142,7 +100,6 @@ def get_logging_verbose() -> Optional[int]:
142
100
  3
143
101
 
144
102
  :returns: Verbose level in ``[0, 1, 2, 3]`` or None if not set
145
- :rtype: int or None
146
103
  """
147
104
  global disable_tqdm
148
105
  logger = logging.getLogger("eodag")
eodag/utils/notebook.py CHANGED
@@ -23,7 +23,7 @@ from typing import Any, Optional
23
23
  def check_ipython() -> bool:
24
24
  """Check if called from ipython"""
25
25
  try:
26
- __IPYTHON__
26
+ __IPYTHON__ # type: ignore[name-defined]
27
27
  return True
28
28
  except NameError:
29
29
  return False
@@ -32,7 +32,7 @@ def check_ipython() -> bool:
32
32
  def check_notebook() -> bool:
33
33
  """Check if called from a notebook"""
34
34
  try:
35
- shell = get_ipython().__class__.__name__
35
+ shell = get_ipython().__class__.__name__ # type: ignore[name-defined]
36
36
  if shell == "ZMQInteractiveShell":
37
37
  return True # Jupyter notebook or qtconsole
38
38
  elif shell == "TerminalInteractiveShell":
@@ -69,7 +69,7 @@ class NotebookWidgets:
69
69
  if not self.is_notebook:
70
70
  return None
71
71
 
72
- self.html_box.data = html_value
72
+ setattr(self.html_box, "data", html_value)
73
73
 
74
74
  if not self.html_box_shown:
75
75
  self._html_handle = self.display(self.html_box, display_id=True)
@@ -83,5 +83,5 @@ class NotebookWidgets:
83
83
  if not self.is_notebook:
84
84
  return None
85
85
 
86
- self.html_box.data = ""
86
+ setattr(self.html_box, "data", "")
87
87
  self._update_display(self.html_box, display_id=self._html_handle.display_id)
eodag/utils/requests.py CHANGED
@@ -32,22 +32,17 @@ logger = logging.getLogger("eodag.utils.requests")
32
32
  def fetch_json(
33
33
  file_url: str,
34
34
  req_session: Optional[requests.Session] = None,
35
- auth: Optional[requests.AuthBase] = None,
35
+ auth: Optional[requests.auth.AuthBase] = None,
36
36
  timeout: float = HTTP_REQ_TIMEOUT,
37
37
  ) -> Any:
38
38
  """
39
39
  Fetches http/distant or local json file
40
40
 
41
41
  :param file_url: url from which the file can be fetched
42
- :type file_url: str
43
42
  :param req_session: (optional) requests session
44
- :type req_session: requests.Session
45
43
  :param auth: (optional) authenticated object if request needs authentication
46
- :type auth: Optional[requests.AuthBase]
47
44
  :param timeout: (optional) authenticated object
48
- :type timeout: float
49
45
  :returns: json file content
50
- :rtype: Any
51
46
  """
52
47
  if req_session is None:
53
48
  req_session = requests.Session()
@@ -68,9 +63,7 @@ def fetch_json(
68
63
  except requests.exceptions.Timeout as exc:
69
64
  raise TimeOutError(exc, timeout=HTTP_REQ_TIMEOUT) from exc
70
65
  except requests.exceptions.RequestException as exc:
71
- raise RequestError(
72
- f"Unable to fetch {file_url}: {str(exc)}",
73
- ) from exc
66
+ raise RequestError.from_error(exc, f"Unable to fetch {file_url}") from exc
74
67
  else:
75
68
  return res.json()
76
69
 
@@ -86,11 +79,8 @@ class LocalFileAdapter(requests.adapters.BaseAdapter):
86
79
  """Return an HTTP status for the given filesystem path.
87
80
 
88
81
  :param method: method of the request
89
- :type method: str
90
82
  :param path: path of the given file
91
- :type path: str
92
83
  :returns: HTTP status and its associated message
93
- :rtype: Tuple[int, str]
94
84
  """
95
85
  if method.lower() in ("put", "delete"):
96
86
  return 501, "Not Implemented" # TODO
@@ -105,31 +95,31 @@ class LocalFileAdapter(requests.adapters.BaseAdapter):
105
95
  else:
106
96
  return 200, "OK"
107
97
 
108
- def send(self, req: requests.PreparedRequest, **kwargs: Any) -> requests.Response:
98
+ def send(
99
+ self, request: requests.PreparedRequest, *args: Any, **kwargs: Any
100
+ ) -> requests.Response:
109
101
  """Wraps a file, described in request, in a Response object.
110
102
 
111
103
  :param req: The PreparedRequest being "sent".
112
- :type req: :class:`~requests.PreparedRequest`
113
104
  :param kwargs: (not used) additionnal arguments of the request
114
- :type kwargs: Any
115
105
  :returns: a Response object containing the file
116
- :rtype: :class:`~requests.Response`
117
106
  """
118
107
  response = requests.Response()
119
108
 
120
- path_url = uri_to_path(req.url)
121
-
122
- if req.method is None or req.url is None:
109
+ if request.method is None or request.url is None:
123
110
  raise RequestError("Method or url of the request is missing")
124
- response.status_code, response.reason = self._chkpath(req.method, path_url)
125
- if response.status_code == 200 and req.method.lower() != "head":
111
+
112
+ path_url = uri_to_path(request.url)
113
+
114
+ response.status_code, response.reason = self._chkpath(request.method, path_url)
115
+ if response.status_code == 200 and request.method.lower() != "head":
126
116
  try:
127
117
  response.raw = open(path_url, "rb")
128
118
  except (OSError, IOError) as err:
129
119
  response.status_code = 500
130
120
  response.reason = str(err)
131
- response.url = req.url
132
- response.request = req
121
+ response.url = request.url
122
+ response.request = request
133
123
 
134
124
  return response
135
125
 
eodag/utils/rest.py CHANGED
@@ -39,9 +39,7 @@ def get_datetime(arguments: Dict[str, Any]) -> Tuple[Optional[str], Optional[str
39
39
  """Get start and end dates from a dict containing `/` separated dates in `datetime` item
40
40
 
41
41
  :param arguments: dict containing a single date or `/` separated dates in `datetime` item
42
- :type arguments: dict
43
42
  :returns: Start date and end date from datetime string (duplicate value if only one date as input)
44
- :rtype: Tuple[Optional[str], Optional[str]]
45
43
  """
46
44
  datetime_str = arguments.pop("datetime", None)
47
45
 
@@ -86,10 +84,8 @@ def rfc3339_str_to_datetime(s: str) -> datetime.datetime:
86
84
  """Convert a string conforming to RFC 3339 to a :class:`datetime.datetime`.
87
85
 
88
86
  :param s: The string to convert to :class:`datetime.datetime`
89
- :type s: str
90
87
 
91
88
  :returns: The datetime represented by the ISO8601 (RFC 3339) formatted string
92
- :rtype: :class:`datetime.datetime`
93
89
 
94
90
  raises: :class:`ValidationError`
95
91
  """
@@ -112,23 +112,17 @@ def fetch_stac_items(
112
112
  """Fetch STAC item from a single item file or items from a catalog.
113
113
 
114
114
  :param stac_path: A STAC object filepath
115
- :type stac_path: str
116
115
  :param recursive: (optional) Browse recursively in child nodes if True
117
- :type recursive: bool
118
- :param max_connections: (optional) Maximum number of connections for HTTP requests
119
- :type max_connections: int
116
+ :param max_connections: (optional) Maximum number of connections for concurrent HTTP requests
120
117
  :param timeout: (optional) Timeout in seconds for each internal HTTP request
121
- :type timeout: int
122
118
  :param ssl_verify: (optional) SSL Verification for HTTP request
123
- :type ssl_verify: bool
124
119
  :returns: The items found in `stac_path`
125
- :rtype: :class:`list`
126
120
  """
127
121
 
128
122
  # URI opener used by PySTAC internally, instantiated here
129
123
  # to retrieve the timeout.
130
124
  _text_opener = _TextOpener(timeout, ssl_verify)
131
- pystac.StacIO.read_text = _text_opener
125
+ pystac.StacIO.read_text = _text_opener # type: ignore[assignment]
132
126
 
133
127
  stac_obj = pystac.read_file(stac_path)
134
128
  # Single STAC item
@@ -198,22 +192,16 @@ def fetch_stac_collections(
198
192
  """Fetch STAC collection(s) from a catalog.
199
193
 
200
194
  :param stac_path: A STAC object filepath
201
- :type stac_path: str
202
195
  :param collection: the collection to fetch
203
- :type collection: Optional[str]
204
196
  :param max_connections: (optional) Maximum number of connections for HTTP requests
205
- :type max_connections: int
206
197
  :param timeout: (optional) Timeout in seconds for each internal HTTP request
207
- :type timeout: int
208
198
  :param ssl_verify: (optional) SSL Verification for HTTP request
209
- :type ssl_verify: bool
210
199
  :returns: The collection(s) found in `stac_path`
211
- :rtype: :class:`list`
212
200
  """
213
201
 
214
202
  # URI opener used by PySTAC internally, instantiated here to retrieve the timeout.
215
203
  _text_opener = _TextOpener(timeout, ssl_verify)
216
- pystac.StacIO.read_text = _text_opener
204
+ pystac.StacIO.read_text = _text_opener # type: ignore[assignment]
217
205
 
218
206
  stac_obj = pystac.read_file(stac_path)
219
207
  if isinstance(stac_obj, pystac.Catalog):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eodag
3
- Version: 3.0.0b2
3
+ Version: 3.0.1
4
4
  Summary: Earth Observation Data Access Gateway
5
5
  Home-page: https://github.com/CS-SI/eodag
6
6
  Author: CS GROUP - France
@@ -18,15 +18,16 @@ Classifier: Operating System :: Microsoft :: Windows
18
18
  Classifier: Operating System :: POSIX :: Linux
19
19
  Classifier: Programming Language :: Python
20
20
  Classifier: Programming Language :: Python :: 3
21
- Classifier: Programming Language :: Python :: 3.8
22
21
  Classifier: Programming Language :: Python :: 3.9
23
22
  Classifier: Programming Language :: Python :: 3.10
24
23
  Classifier: Programming Language :: Python :: 3.11
25
24
  Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
26
  Classifier: Programming Language :: Python :: Implementation :: CPython
27
27
  Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
28
28
  Classifier: Topic :: Scientific/Engineering :: GIS
29
29
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
30
+ Classifier: Typing :: Typed
30
31
  Requires-Python: >=3.6
31
32
  Description-Content-Type: text/x-rst
32
33
  License-File: LICENSE
@@ -39,6 +40,7 @@ Requires-Dist: jsonpath-ng <1.6.0
39
40
  Requires-Dist: lxml
40
41
  Requires-Dist: pydantic >=2.1.0
41
42
  Requires-Dist: pydantic-core
43
+ Requires-Dist: PyJWT >=2.5.0
42
44
  Requires-Dist: pyproj >=2.1.0
43
45
  Requires-Dist: pyshp
44
46
  Requires-Dist: pystac >=1.0.0b1
@@ -46,7 +48,7 @@ Requires-Dist: python-dateutil
46
48
  Requires-Dist: PyYAML
47
49
  Requires-Dist: requests
48
50
  Requires-Dist: setuptools
49
- Requires-Dist: shapely >=2.0.0
51
+ Requires-Dist: shapely >=2.0.6
50
52
  Requires-Dist: stream-zip
51
53
  Requires-Dist: tqdm
52
54
  Requires-Dist: typing-extensions >=4.8.0
@@ -61,7 +63,7 @@ Requires-Dist: eodag[ecmwf,usgs] ; extra == 'all-providers'
61
63
  Provides-Extra: csw
62
64
  Requires-Dist: OWSLib >=0.27.1 ; extra == 'csw'
63
65
  Provides-Extra: dev
64
- Requires-Dist: eodag[all-providers,csw,server] ; extra == 'dev'
66
+ Requires-Dist: eodag[all-providers,csw,server,stubs] ; extra == 'dev'
65
67
  Requires-Dist: pytest ; extra == 'dev'
66
68
  Requires-Dist: pytest-cov ; extra == 'dev'
67
69
  Requires-Dist: py >=1.8.2 ; extra == 'dev'
@@ -70,6 +72,7 @@ Requires-Dist: pytest-xdist ; extra == 'dev'
70
72
  Requires-Dist: pytest-socket ; extra == 'dev'
71
73
  Requires-Dist: pytest-instafail ; extra == 'dev'
72
74
  Requires-Dist: tox ; extra == 'dev'
75
+ Requires-Dist: tox-uv ; extra == 'dev'
73
76
  Requires-Dist: faker ; extra == 'dev'
74
77
  Requires-Dist: moto ; extra == 'dev'
75
78
  Requires-Dist: twine ; extra == 'dev'
@@ -79,15 +82,16 @@ Requires-Dist: pre-commit ; extra == 'dev'
79
82
  Requires-Dist: responses <0.24.0 ; extra == 'dev'
80
83
  Requires-Dist: fastapi[all] ; extra == 'dev'
81
84
  Requires-Dist: stdlib-list ; extra == 'dev'
82
- Requires-Dist: boto3-stubs[essential] ; extra == 'dev'
83
- Requires-Dist: types-lxml ; extra == 'dev'
85
+ Requires-Dist: mypy ; extra == 'dev'
84
86
  Provides-Extra: docs
85
- Requires-Dist: eodag[all] ; extra == 'docs'
87
+ Requires-Dist: eodag[all,stubs] ; extra == 'docs'
86
88
  Requires-Dist: sphinx ; extra == 'docs'
87
- Requires-Dist: sphinx-book-theme ; extra == 'docs'
89
+ Requires-Dist: sphinx-book-theme >=1.0.0 ; extra == 'docs'
88
90
  Requires-Dist: sphinx-copybutton ; extra == 'docs'
89
91
  Requires-Dist: sphinx-tabs ; extra == 'docs'
90
92
  Requires-Dist: nbsphinx ; extra == 'docs'
93
+ Requires-Dist: sphinx-autodoc-typehints ; extra == 'docs'
94
+ Requires-Dist: sphinxemoji ; extra == 'docs'
91
95
  Provides-Extra: ecmwf
92
96
  Requires-Dist: ecmwf-api-client ; extra == 'ecmwf'
93
97
  Provides-Extra: notebook
@@ -99,8 +103,17 @@ Requires-Dist: starlette ; extra == 'server'
99
103
  Requires-Dist: uvicorn[standard] ; extra == 'server'
100
104
  Requires-Dist: pydantic-settings ; extra == 'server'
101
105
  Requires-Dist: cachetools ; extra == 'server'
106
+ Provides-Extra: stubs
107
+ Requires-Dist: boto3-stubs[essential] ; extra == 'stubs'
108
+ Requires-Dist: types-lxml ; extra == 'stubs'
109
+ Requires-Dist: types-cachetools ; extra == 'stubs'
110
+ Requires-Dist: types-requests ; extra == 'stubs'
111
+ Requires-Dist: types-python-dateutil ; extra == 'stubs'
112
+ Requires-Dist: types-setuptools ; extra == 'stubs'
113
+ Requires-Dist: types-tqdm ; extra == 'stubs'
114
+ Requires-Dist: types-urllib3 ; extra == 'stubs'
102
115
  Provides-Extra: tutorials
103
- Requires-Dist: eodag[notebook] ; extra == 'tutorials'
116
+ Requires-Dist: eodag[ecmwf,notebook] ; extra == 'tutorials'
104
117
  Requires-Dist: eodag-cube >=0.2.0 ; extra == 'tutorials'
105
118
  Requires-Dist: jupyter ; extra == 'tutorials'
106
119
  Requires-Dist: ipyleaflet >=0.10.0 ; extra == 'tutorials'
@@ -138,8 +151,6 @@ Requires-Dist: usgs >=0.3.1 ; extra == 'usgs'
138
151
 
139
152
  |pypi-badge| |conda-badge| |rtd-badge| |gha-badge| |ghi-badge| |binder-badge|
140
153
 
141
- |
142
-
143
154
  .. |license-badge| image:: https://img.shields.io/pypi/l/eodag.svg
144
155
  :target: https://pypi.org/project/eodag/
145
156
 
@@ -199,8 +210,14 @@ And with ``conda`` from the `conda-forge channel <https://anaconda.org/conda-for
199
210
 
200
211
  conda install -c conda-forge eodag
201
212
 
202
- **[New in v3.0.0]** Please note that EODAG comes with a minimal set of dependencies. If you want more features, please install using one of
203
- the `available extras <https://eodag.readthedocs.io/en/latest/getting_started_guide/install.html#optional-dependencies>`_.
213
+ ..
214
+
215
+ [!IMPORTANT]
216
+
217
+ `Breaking change <https://eodag.readthedocs.io/en/latest/breaking_changes.html>`_ **in v3.0.0**:
218
+ Please note that EODAG
219
+ comes with a minimal set of dependencies. If you want more features, please install using one of the
220
+ `available extras <https://eodag.readthedocs.io/en/latest/getting_started_guide/install.html#optional-dependencies>`_.
204
221
 
205
222
  Usage
206
223
  =====
@@ -234,8 +251,13 @@ This will search for Sentinel 2 level-1C products on the default provider and re
234
251
  an estimated total number of products matching the search criteria. And then it will download these products. Please
235
252
  check the `Python API User Guide <https://eodag.readthedocs.io/en/latest/api_user_guide.html>`_ for more details.
236
253
 
237
- **[New in v3.0.0]** `search() <https://eodag.readthedocs.io/en/latest/notebooks/api_user_guide/4_search.html#search()>`_
238
- method now returns only a single ``SearchResult`` instead of a 2 values tuple.
254
+ ..
255
+
256
+ [!IMPORTANT]
257
+
258
+ `Breaking change <https://eodag.readthedocs.io/en/latest/breaking_changes.html>`_ **in v3.0.0**:
259
+ `search() <https://eodag.readthedocs.io/en/latest/api_reference/core.html#eodag.api.core.EODataAccessGateway.search>`_ method now returns
260
+ only a single ``SearchResult`` instead of a 2 values tuple.
239
261
 
240
262
  STAC REST API
241
263
  -------------
@@ -280,25 +302,20 @@ An eodag instance can be exposed through a STAC compliant REST api from the comm
280
302
  | jq ".numberMatched"
281
303
  6
282
304
 
283
- # browse for items
284
- $ curl "http://127.0.0.1:5000/catalogs/S2_MSI_L1C/country/FRA/year/2021/month/01/day/25/cloud_cover/10/items" \
285
- | jq ".numberMatched"
286
- 9
287
-
288
305
  # get download link
289
- $ curl "http://127.0.0.1:5000/catalogs/S2_MSI_L1C/country/FRA/year/2021/month/01/day/25/cloud_cover/10/items" \
306
+ $ curl "http://127.0.0.1:5000/collections/S2_MSI_L1C/items" \
290
307
  | jq ".features[0].assets.downloadLink.href"
291
- "http://127.0.0.1:5000/catalogs/S2_MSI_L1C/country/FRA/year/2021/month/01/day/25/cloud_cover/10/items/S2A_MSIL1C_20210125T105331_N0209_R051_T31UCR_20210125T130733/download"
308
+ "http://127.0.0.1:5002/collections/S2_MSI_L1C/items/S2B_MSIL1C_20240917T115259_N0511_R137_T21CWS_20240917T145134/download"
292
309
 
293
310
  # download
294
- $ wget "http://127.0.0.1:5000/catalogs/S2_MSI_L1C/country/FRA/year/2021/month/01/day/25/cloud_cover/10/items/S2A_MSIL1C_20210125T105331_N0209_R051_T31UCR_20210125T130733/download"
311
+ $ wget "http://127.0.0.1:5002/collections/S2_MSI_L1C/items/S2B_MSIL1C_20240917T115259_N0511_R137_T21CWS_20240917T145134/download"
295
312
 
296
313
 
297
314
  ``eodag-server`` is available on `https://hub.docker.com/r/csspace/eodag-server <https://hub.docker.com/r/csspace/eodag-server>`_:
298
315
 
299
316
  .. code-block:: bash
300
317
 
301
- docker run -p 5000:5000 --rm csspace/eodag-server:3.0.0b2
318
+ docker run -p 5000:5000 --rm csspace/eodag-server:3.0.1
302
319
 
303
320
  You can also browse over your STAC API server using `STAC Browser <https://github.com/radiantearth/stac-browser>`_.
304
321
  Simply run: