eodag 3.0.1__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 (87) hide show
  1. eodag/api/core.py +164 -127
  2. eodag/api/product/_assets.py +11 -11
  3. eodag/api/product/_product.py +45 -30
  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 +101 -85
  10. eodag/api/search_result.py +13 -23
  11. eodag/cli.py +26 -5
  12. eodag/config.py +78 -81
  13. eodag/plugins/apis/base.py +1 -1
  14. eodag/plugins/apis/ecmwf.py +46 -22
  15. eodag/plugins/apis/usgs.py +16 -15
  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 +16 -16
  22. eodag/plugins/authentication/sas_auth.py +4 -4
  23. eodag/plugins/authentication/token.py +41 -10
  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 +6 -7
  32. eodag/plugins/download/aws.py +58 -78
  33. eodag/plugins/download/base.py +38 -56
  34. eodag/plugins/download/creodias_s3.py +29 -0
  35. eodag/plugins/download/http.py +173 -183
  36. eodag/plugins/download/s3rest.py +10 -11
  37. eodag/plugins/manager.py +10 -20
  38. eodag/plugins/search/__init__.py +6 -5
  39. eodag/plugins/search/base.py +87 -44
  40. eodag/plugins/search/build_search_result.py +1067 -329
  41. eodag/plugins/search/cop_marine.py +22 -12
  42. eodag/plugins/search/creodias_s3.py +9 -73
  43. eodag/plugins/search/csw.py +11 -11
  44. eodag/plugins/search/data_request_search.py +16 -15
  45. eodag/plugins/search/qssearch.py +103 -187
  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 +663 -304
  50. eodag/resources/providers.yml +823 -1749
  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 +112 -82
  56. eodag/rest/errors.py +5 -5
  57. eodag/rest/server.py +33 -14
  58. eodag/rest/stac.py +40 -38
  59. eodag/rest/types/collections_search.py +3 -3
  60. eodag/rest/types/eodag_search.py +29 -23
  61. eodag/rest/types/queryables.py +15 -16
  62. eodag/rest/types/stac_search.py +15 -25
  63. eodag/rest/utils/__init__.py +14 -21
  64. eodag/rest/utils/cql_evaluate.py +6 -6
  65. eodag/rest/utils/rfc3339.py +2 -2
  66. eodag/types/__init__.py +75 -28
  67. eodag/types/bbox.py +2 -2
  68. eodag/types/download_args.py +3 -3
  69. eodag/types/queryables.py +183 -72
  70. eodag/types/search_args.py +4 -4
  71. eodag/types/whoosh.py +127 -3
  72. eodag/utils/__init__.py +152 -50
  73. eodag/utils/exceptions.py +28 -21
  74. eodag/utils/import_system.py +2 -2
  75. eodag/utils/repr.py +65 -6
  76. eodag/utils/requests.py +13 -13
  77. eodag/utils/rest.py +2 -2
  78. eodag/utils/s3.py +208 -0
  79. eodag/utils/stac_reader.py +10 -10
  80. {eodag-3.0.1.dist-info → eodag-3.1.0b2.dist-info}/METADATA +77 -76
  81. eodag-3.1.0b2.dist-info/RECORD +113 -0
  82. {eodag-3.0.1.dist-info → eodag-3.1.0b2.dist-info}/WHEEL +1 -1
  83. {eodag-3.0.1.dist-info → eodag-3.1.0b2.dist-info}/entry_points.txt +4 -2
  84. eodag/utils/constraints.py +0 -244
  85. eodag-3.0.1.dist-info/RECORD +0 -109
  86. {eodag-3.0.1.dist-info → eodag-3.1.0b2.dist-info}/LICENSE +0 -0
  87. {eodag-3.0.1.dist-info → eodag-3.1.0b2.dist-info}/top_level.txt +0 -0
eodag/utils/requests.py CHANGED
@@ -19,7 +19,7 @@ from __future__ import annotations
19
19
 
20
20
  import logging
21
21
  import os
22
- from typing import Any, Optional, Tuple
22
+ from typing import Any, Optional
23
23
 
24
24
  import requests
25
25
 
@@ -30,7 +30,7 @@ logger = logging.getLogger("eodag.utils.requests")
30
30
 
31
31
 
32
32
  def fetch_json(
33
- file_url: str,
33
+ url: str,
34
34
  req_session: Optional[requests.Session] = None,
35
35
  auth: Optional[requests.auth.AuthBase] = None,
36
36
  timeout: float = HTTP_REQ_TIMEOUT,
@@ -38,32 +38,32 @@ def fetch_json(
38
38
  """
39
39
  Fetches http/distant or local json file
40
40
 
41
- :param file_url: url from which the file can be fetched
41
+ :param url: url from which the file can be fetched
42
42
  :param req_session: (optional) requests session
43
43
  :param auth: (optional) authenticated object if request needs authentication
44
44
  :param timeout: (optional) authenticated object
45
45
  :returns: json file content
46
46
  """
47
47
  if req_session is None:
48
- req_session = requests.Session()
48
+ req_session = requests.sessions.Session()
49
49
  try:
50
- if not file_url.lower().startswith("http"):
51
- file_url = path_to_uri(os.path.abspath(file_url))
50
+ if not url.lower().startswith("http"):
51
+ url = path_to_uri(os.path.abspath(url))
52
52
  req_session.mount("file://", LocalFileAdapter())
53
53
 
54
54
  headers = USER_AGENT
55
- logger.debug(f"fetching {file_url}")
55
+ logger.debug(f"fetching {url}")
56
56
  res = req_session.get(
57
- file_url,
57
+ url,
58
58
  headers=headers,
59
59
  auth=auth,
60
60
  timeout=timeout,
61
61
  )
62
62
  res.raise_for_status()
63
63
  except requests.exceptions.Timeout as exc:
64
- raise TimeOutError(exc, timeout=HTTP_REQ_TIMEOUT) from exc
64
+ raise TimeOutError(exc, timeout=timeout) from exc
65
65
  except requests.exceptions.RequestException as exc:
66
- raise RequestError.from_error(exc, f"Unable to fetch {file_url}") from exc
66
+ raise RequestError.from_error(exc, f"Unable to fetch {url}") from exc
67
67
  else:
68
68
  return res.json()
69
69
 
@@ -75,7 +75,7 @@ class LocalFileAdapter(requests.adapters.BaseAdapter):
75
75
  """
76
76
 
77
77
  @staticmethod
78
- def _chkpath(method: str, path: str) -> Tuple[int, str]:
78
+ def _chkpath(method: str, path: str) -> tuple[int, str]:
79
79
  """Return an HTTP status for the given filesystem path.
80
80
 
81
81
  :param method: method of the request
@@ -100,8 +100,8 @@ class LocalFileAdapter(requests.adapters.BaseAdapter):
100
100
  ) -> requests.Response:
101
101
  """Wraps a file, described in request, in a Response object.
102
102
 
103
- :param req: The PreparedRequest being "sent".
104
- :param kwargs: (not used) additionnal arguments of the request
103
+ :param request: The PreparedRequest being "sent".
104
+ :param kwargs: (not used) additional arguments of the request
105
105
  :returns: a Response object containing the file
106
106
  """
107
107
  response = requests.Response()
eodag/utils/rest.py CHANGED
@@ -21,7 +21,7 @@ from __future__ import annotations
21
21
 
22
22
  import datetime
23
23
  import re
24
- from typing import Any, Dict, Optional, Tuple
24
+ from typing import Any, Optional
25
25
 
26
26
  import dateutil.parser
27
27
  from dateutil import tz
@@ -35,7 +35,7 @@ RFC3339_PATTERN = (
35
35
  )
36
36
 
37
37
 
38
- def get_datetime(arguments: Dict[str, Any]) -> Tuple[Optional[str], Optional[str]]:
38
+ 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
eodag/utils/s3.py ADDED
@@ -0,0 +1,208 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2024, CS GROUP - France, https://www.csgroup.eu/
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 io
21
+ import logging
22
+ import os
23
+ import zipfile
24
+ from typing import TYPE_CHECKING, List, Optional
25
+ from urllib.parse import urlparse
26
+
27
+ import boto3
28
+ import botocore
29
+
30
+ from eodag.plugins.authentication.aws_auth import AwsAuth
31
+ from eodag.utils import get_bucket_name_and_prefix, guess_file_type
32
+ from eodag.utils.exceptions import (
33
+ AuthenticationError,
34
+ MisconfiguredError,
35
+ NotAvailableError,
36
+ )
37
+
38
+ if TYPE_CHECKING:
39
+ from zipfile import ZipInfo
40
+
41
+ from mypy_boto3_s3.client import S3Client
42
+
43
+ from eodag.api.product import EOProduct # type: ignore
44
+
45
+ logger = logging.getLogger("eodag.utils.s3")
46
+
47
+
48
+ def fetch(
49
+ bucket_name: str, key_name: str, start: int, len: int, client_s3: S3Client
50
+ ) -> bytes:
51
+ """
52
+ Range-fetches a S3 key.
53
+
54
+ :param bucket_name: Bucket name of the object to fetch
55
+ :param key_name: Key name of the object to fetch
56
+ :param start: Bucket name to fetch
57
+ :param len: Bucket name to fetch
58
+ :param client_s3: s3 client used to fetch the object
59
+ :returns: Object bytes
60
+ """
61
+ end = start + len - 1
62
+ s3_object = client_s3.get_object(
63
+ Bucket=bucket_name, Key=key_name, Range="bytes=%d-%d" % (start, end)
64
+ )
65
+ return s3_object["Body"].read()
66
+
67
+
68
+ def parse_int(bytes: bytes) -> int:
69
+ """
70
+ Parses 2 or 4 little-endian bits into their corresponding integer value.
71
+
72
+ :param bytes: bytes to parse
73
+ :returns: parsed int
74
+ """
75
+ val = (bytes[0]) + ((bytes[1]) << 8)
76
+ if len(bytes) > 3:
77
+ val += ((bytes[2]) << 16) + ((bytes[3]) << 24)
78
+ return val
79
+
80
+
81
+ def list_files_in_s3_zipped_object(
82
+ bucket_name: str, key_name: str, client_s3: S3Client
83
+ ) -> List[ZipInfo]:
84
+ """
85
+ List files in s3 zipped object, without downloading it.
86
+
87
+ See https://stackoverflow.com/questions/41789176/how-to-count-files-inside-zip-in-aws-s3-without-downloading-it;
88
+ Based on https://stackoverflow.com/questions/51351000/read-zip-files-from-s3-without-downloading-the-entire-file
89
+
90
+ :param bucket_name: Bucket name of the object to fetch
91
+ :param key_name: Key name of the object to fetch
92
+ :param client_s3: s3 client used to fetch the object
93
+ :returns: List of files in zip
94
+ """
95
+ response = client_s3.head_object(Bucket=bucket_name, Key=key_name)
96
+ size = response["ContentLength"]
97
+
98
+ # End Of Central Directory bytes
99
+ eocd = fetch(bucket_name, key_name, size - 22, 22, client_s3)
100
+
101
+ # start offset and size of the central directory
102
+ cd_start = parse_int(eocd[16:20])
103
+ cd_size = parse_int(eocd[12:16])
104
+
105
+ # fetch central directory, append EOCD, and open as zipfile
106
+ cd = fetch(bucket_name, key_name, cd_start, cd_size, client_s3)
107
+ zip = zipfile.ZipFile(io.BytesIO(cd + eocd))
108
+
109
+ logger.debug("Found %s files in %s" % (len(zip.filelist), key_name))
110
+
111
+ return zip.filelist
112
+
113
+
114
+ def update_assets_from_s3(
115
+ product: EOProduct,
116
+ auth: AwsAuth,
117
+ s3_endpoint: Optional[str] = None,
118
+ content_url: Optional[str] = None,
119
+ ) -> None:
120
+ """Update ``EOProduct.assets`` using content listed in its ``remote_location`` or given
121
+ ``content_url``.
122
+
123
+ If url points to a zipped archive, its content will also be be listed.
124
+
125
+ :param product: product to update
126
+ :param auth: Authentication plugin
127
+ :param s3_endpoint: s3 endpoint if not hosted on AWS
128
+ :param content_url: s3 URL pointing to the content that must be listed (defaults to
129
+ ``product.remote_location`` if empty)
130
+ """
131
+ required_creds = ["aws_access_key_id", "aws_secret_access_key"]
132
+
133
+ if content_url is None:
134
+ content_url = product.remote_location
135
+
136
+ bucket, prefix = get_bucket_name_and_prefix(content_url)
137
+
138
+ if bucket is None or prefix is None:
139
+ logger.debug(f"No s3 prefix could guessed from {content_url}")
140
+ return None
141
+
142
+ try:
143
+ auth_dict = auth.authenticate()
144
+
145
+ if not all(x in auth_dict for x in required_creds):
146
+ raise MisconfiguredError(
147
+ f"Incomplete credentials for {product.provider}, missing "
148
+ f"{[x for x in required_creds if x not in auth_dict]}"
149
+ )
150
+ if not getattr(auth, "s3_client", None):
151
+ auth.s3_client = boto3.client(
152
+ service_name="s3",
153
+ endpoint_url=s3_endpoint,
154
+ aws_access_key_id=auth_dict.get("aws_access_key_id"),
155
+ aws_secret_access_key=auth_dict.get("aws_secret_access_key"),
156
+ aws_session_token=auth_dict.get("aws_session_token"),
157
+ )
158
+
159
+ logger.debug("Listing assets in %s", prefix)
160
+
161
+ if prefix.endswith(".zip"):
162
+ # List prefix zip content
163
+ assets_urls = [
164
+ f"zip+s3://{bucket}/{prefix}!{f.filename}"
165
+ for f in list_files_in_s3_zipped_object(bucket, prefix, auth.s3_client)
166
+ ]
167
+ else:
168
+ # List files in prefix
169
+ assets_urls = [
170
+ f"s3://{bucket}/{obj['Key']}"
171
+ for obj in auth.s3_client.list_objects(
172
+ Bucket=bucket, Prefix=prefix, MaxKeys=300
173
+ ).get("Contents", [])
174
+ ]
175
+
176
+ for asset_url in assets_urls:
177
+ out_of_zip_url = asset_url.split("!")[-1]
178
+ key, roles = product.driver.guess_asset_key_and_roles(
179
+ out_of_zip_url, product
180
+ )
181
+ parsed_url = urlparse(out_of_zip_url)
182
+ title = os.path.basename(parsed_url.path)
183
+
184
+ if key and key not in product.assets:
185
+ product.assets[key] = {
186
+ "title": title,
187
+ "roles": roles,
188
+ "href": asset_url,
189
+ }
190
+ if mime_type := guess_file_type(asset_url):
191
+ product.assets[key]["type"] = mime_type
192
+
193
+ # sort assets
194
+ product.assets.data = dict(sorted(product.assets.data.items()))
195
+
196
+ # update driver
197
+ product.driver = product.get_driver()
198
+
199
+ except botocore.exceptions.ClientError as e:
200
+ if hasattr(auth.config, "auth_error_code") and str(
201
+ auth.config.auth_error_code
202
+ ) in str(e):
203
+ raise AuthenticationError(
204
+ f"Authentication failed on {s3_endpoint} s3"
205
+ ) from e
206
+ raise NotAvailableError(
207
+ f"assets for product {prefix} could not be found"
208
+ ) from e
@@ -20,7 +20,7 @@ from __future__ import annotations
20
20
  import logging
21
21
  import re
22
22
  import socket
23
- from typing import Any, Callable, Dict, List, Optional, Union
23
+ from typing import Any, Callable, Optional, Union
24
24
  from urllib.error import URLError
25
25
  from urllib.request import urlopen
26
26
 
@@ -108,7 +108,7 @@ def fetch_stac_items(
108
108
  max_connections: int = 100,
109
109
  timeout: int = HTTP_REQ_TIMEOUT,
110
110
  ssl_verify: bool = True,
111
- ) -> List[Dict[str, Any]]:
111
+ ) -> list[dict[str, Any]]:
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
@@ -142,13 +142,13 @@ def _fetch_stac_items_from_catalog(
142
142
  recursive: bool,
143
143
  max_connections: int,
144
144
  _text_opener: Callable[[str, bool], Any],
145
- ) -> List[Any]:
145
+ ) -> list[Any]:
146
146
  """Fetch items from a STAC catalog"""
147
- items: List[Dict[Any, Any]] = []
147
+ items: list[dict[Any, Any]] = []
148
148
 
149
149
  # pystac cannot yet return links from a single file catalog, see:
150
150
  # https://github.com/stac-utils/pystac/issues/256
151
- extensions: Optional[Union[List[str], str]] = getattr(cat, "stac_extensions", None)
151
+ extensions: Optional[Union[list[str], str]] = getattr(cat, "stac_extensions", None)
152
152
  if extensions:
153
153
  extensions = extensions if isinstance(extensions, list) else [extensions]
154
154
  if "single-file-stac" in extensions:
@@ -157,7 +157,7 @@ def _fetch_stac_items_from_catalog(
157
157
 
158
158
  # Making the links absolutes allow for both relative and absolute links to be handled.
159
159
  if not recursive:
160
- hrefs: List[Optional[str]] = [
160
+ hrefs: list[Optional[str]] = [
161
161
  link.get_absolute_href() for link in cat.get_item_links()
162
162
  ]
163
163
  else:
@@ -188,7 +188,7 @@ def fetch_stac_collections(
188
188
  max_connections: int = 100,
189
189
  timeout: int = HTTP_REQ_TIMEOUT,
190
190
  ssl_verify: bool = True,
191
- ) -> List[Dict[str, Any]]:
191
+ ) -> list[dict[str, Any]]:
192
192
  """Fetch STAC collection(s) from a catalog.
193
193
 
194
194
  :param stac_path: A STAC object filepath
@@ -217,12 +217,12 @@ def _fetch_stac_collections_from_catalog(
217
217
  collection: Optional[str],
218
218
  max_connections: int,
219
219
  _text_opener: Callable[[str, bool], Any],
220
- ) -> List[Any]:
220
+ ) -> list[Any]:
221
221
  """Fetch collections from a STAC catalog"""
222
- collections: List[Dict[Any, Any]] = []
222
+ collections: list[dict[Any, Any]] = []
223
223
 
224
224
  # Making the links absolutes allow for both relative and absolute links to be handled.
225
- hrefs: List[Optional[str]] = [
225
+ hrefs: list[Optional[str]] = [
226
226
  link.get_absolute_href()
227
227
  for link in cat.get_child_links()
228
228
  if collection is not None and link.title == collection
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: eodag
3
- Version: 3.0.1
3
+ Version: 3.1.0b2
4
4
  Summary: Earth Observation Data Access Gateway
5
5
  Home-page: https://github.com/CS-SI/eodag
6
6
  Author: CS GROUP - France
@@ -36,95 +36,96 @@ Requires-Dist: boto3
36
36
  Requires-Dist: botocore
37
37
  Requires-Dist: click
38
38
  Requires-Dist: geojson
39
- Requires-Dist: jsonpath-ng <1.6.0
39
+ Requires-Dist: jsonpath-ng<1.6.0
40
40
  Requires-Dist: lxml
41
- Requires-Dist: pydantic >=2.1.0
42
- Requires-Dist: pydantic-core
43
- Requires-Dist: PyJWT >=2.5.0
44
- Requires-Dist: pyproj >=2.1.0
41
+ Requires-Dist: orjson<3.10.0; python_version >= "3.12" and platform_system == "Windows"
42
+ Requires-Dist: orjson; python_version < "3.12" or platform_system != "Windows"
43
+ Requires-Dist: pydantic!=2.10.0,>=2.1.0
44
+ Requires-Dist: pydantic_core
45
+ Requires-Dist: PyJWT[crypto]>=2.5.0
46
+ Requires-Dist: pyproj>=2.1.0
45
47
  Requires-Dist: pyshp
46
- Requires-Dist: pystac >=1.0.0b1
48
+ Requires-Dist: pystac>=1.0.0b1
47
49
  Requires-Dist: python-dateutil
48
50
  Requires-Dist: PyYAML
49
51
  Requires-Dist: requests
50
52
  Requires-Dist: setuptools
51
- Requires-Dist: shapely >=2.0.6
53
+ Requires-Dist: shapely>=2.0.6
52
54
  Requires-Dist: stream-zip
53
55
  Requires-Dist: tqdm
54
- Requires-Dist: typing-extensions >=4.8.0
56
+ Requires-Dist: typing_extensions>=4.8.0
55
57
  Requires-Dist: urllib3
56
58
  Requires-Dist: Whoosh
57
- Requires-Dist: orjson ; python_version < "3.12" or platform_system != "Windows"
58
- Requires-Dist: orjson <3.10.0 ; python_version >= "3.12" and platform_system == "Windows"
59
59
  Provides-Extra: all
60
- Requires-Dist: eodag[all-providers,csw,server,tutorials] ; extra == 'all'
60
+ Requires-Dist: eodag[all-providers,csw,server,tutorials]; extra == "all"
61
61
  Provides-Extra: all-providers
62
- Requires-Dist: eodag[ecmwf,usgs] ; extra == 'all-providers'
62
+ Requires-Dist: eodag[ecmwf,usgs]; extra == "all-providers"
63
63
  Provides-Extra: csw
64
- Requires-Dist: OWSLib >=0.27.1 ; extra == 'csw'
65
- Provides-Extra: dev
66
- Requires-Dist: eodag[all-providers,csw,server,stubs] ; extra == 'dev'
67
- Requires-Dist: pytest ; extra == 'dev'
68
- Requires-Dist: pytest-cov ; extra == 'dev'
69
- Requires-Dist: py >=1.8.2 ; extra == 'dev'
70
- Requires-Dist: pytest-html <3.2.0 ; extra == 'dev'
71
- Requires-Dist: pytest-xdist ; extra == 'dev'
72
- Requires-Dist: pytest-socket ; extra == 'dev'
73
- Requires-Dist: pytest-instafail ; extra == 'dev'
74
- Requires-Dist: tox ; extra == 'dev'
75
- Requires-Dist: tox-uv ; extra == 'dev'
76
- Requires-Dist: faker ; extra == 'dev'
77
- Requires-Dist: moto ; extra == 'dev'
78
- Requires-Dist: twine ; extra == 'dev'
79
- Requires-Dist: wheel ; extra == 'dev'
80
- Requires-Dist: flake8 ; extra == 'dev'
81
- Requires-Dist: pre-commit ; extra == 'dev'
82
- Requires-Dist: responses <0.24.0 ; extra == 'dev'
83
- Requires-Dist: fastapi[all] ; extra == 'dev'
84
- Requires-Dist: stdlib-list ; extra == 'dev'
85
- Requires-Dist: mypy ; extra == 'dev'
86
- Provides-Extra: docs
87
- Requires-Dist: eodag[all,stubs] ; extra == 'docs'
88
- Requires-Dist: sphinx ; extra == 'docs'
89
- Requires-Dist: sphinx-book-theme >=1.0.0 ; extra == 'docs'
90
- Requires-Dist: sphinx-copybutton ; extra == 'docs'
91
- Requires-Dist: sphinx-tabs ; extra == 'docs'
92
- Requires-Dist: nbsphinx ; extra == 'docs'
93
- Requires-Dist: sphinx-autodoc-typehints ; extra == 'docs'
94
- Requires-Dist: sphinxemoji ; extra == 'docs'
64
+ Requires-Dist: OWSLib>=0.27.1; extra == "csw"
95
65
  Provides-Extra: ecmwf
96
- Requires-Dist: ecmwf-api-client ; extra == 'ecmwf'
97
- Provides-Extra: notebook
98
- Requires-Dist: tqdm[notebook] ; extra == 'notebook'
66
+ Requires-Dist: ecmwf-api-client; extra == "ecmwf"
67
+ Provides-Extra: usgs
68
+ Requires-Dist: usgs>=0.3.1; extra == "usgs"
99
69
  Provides-Extra: server
100
- Requires-Dist: fastapi >=0.93.0 ; extra == 'server'
101
- Requires-Dist: pygeofilter ; extra == 'server'
102
- Requires-Dist: starlette ; extra == 'server'
103
- Requires-Dist: uvicorn[standard] ; extra == 'server'
104
- Requires-Dist: pydantic-settings ; extra == 'server'
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'
70
+ Requires-Dist: fastapi>=0.93.0; extra == "server"
71
+ Requires-Dist: pygeofilter; extra == "server"
72
+ Requires-Dist: starlette; extra == "server"
73
+ Requires-Dist: uvicorn[standard]; extra == "server"
74
+ Requires-Dist: pydantic-settings; extra == "server"
75
+ Requires-Dist: cachetools; extra == "server"
76
+ Provides-Extra: notebook
77
+ Requires-Dist: tqdm[notebook]; extra == "notebook"
115
78
  Provides-Extra: tutorials
116
- Requires-Dist: eodag[ecmwf,notebook] ; extra == 'tutorials'
117
- Requires-Dist: eodag-cube >=0.2.0 ; extra == 'tutorials'
118
- Requires-Dist: jupyter ; extra == 'tutorials'
119
- Requires-Dist: ipyleaflet >=0.10.0 ; extra == 'tutorials'
120
- Requires-Dist: ipywidgets ; extra == 'tutorials'
121
- Requires-Dist: matplotlib ; extra == 'tutorials'
122
- Requires-Dist: folium ; extra == 'tutorials'
123
- Requires-Dist: imageio ; extra == 'tutorials'
124
- Requires-Dist: rasterio ; extra == 'tutorials'
125
- Requires-Dist: netcdf4 ; extra == 'tutorials'
126
- Provides-Extra: usgs
127
- Requires-Dist: usgs >=0.3.1 ; extra == 'usgs'
79
+ Requires-Dist: eodag[ecmwf,notebook]; extra == "tutorials"
80
+ Requires-Dist: eodag-cube>=0.6.0b1; extra == "tutorials"
81
+ Requires-Dist: jupyter; extra == "tutorials"
82
+ Requires-Dist: ipyleaflet>=0.10.0; extra == "tutorials"
83
+ Requires-Dist: ipywidgets; extra == "tutorials"
84
+ Requires-Dist: matplotlib; extra == "tutorials"
85
+ Requires-Dist: folium; extra == "tutorials"
86
+ Requires-Dist: imageio; extra == "tutorials"
87
+ Requires-Dist: rasterio; extra == "tutorials"
88
+ Requires-Dist: netcdf4; extra == "tutorials"
89
+ Requires-Dist: cartopy; extra == "tutorials"
90
+ Provides-Extra: dev
91
+ Requires-Dist: eodag[all-providers,csw,server,stubs]; extra == "dev"
92
+ Requires-Dist: pytest; extra == "dev"
93
+ Requires-Dist: pytest-cov; extra == "dev"
94
+ Requires-Dist: py>=1.8.2; extra == "dev"
95
+ Requires-Dist: pytest-html<3.2.0; extra == "dev"
96
+ Requires-Dist: pytest-xdist; extra == "dev"
97
+ Requires-Dist: pytest-socket; extra == "dev"
98
+ Requires-Dist: pytest-instafail; extra == "dev"
99
+ Requires-Dist: tox; extra == "dev"
100
+ Requires-Dist: tox-uv; extra == "dev"
101
+ Requires-Dist: faker; extra == "dev"
102
+ Requires-Dist: moto>=5; extra == "dev"
103
+ Requires-Dist: twine; extra == "dev"
104
+ Requires-Dist: wheel; extra == "dev"
105
+ Requires-Dist: flake8; extra == "dev"
106
+ Requires-Dist: pre-commit; extra == "dev"
107
+ Requires-Dist: responses<0.24.0; extra == "dev"
108
+ Requires-Dist: fastapi[all]; extra == "dev"
109
+ Requires-Dist: stdlib-list; extra == "dev"
110
+ Requires-Dist: mypy; extra == "dev"
111
+ Provides-Extra: stubs
112
+ Requires-Dist: boto3-stubs[essential]; extra == "stubs"
113
+ Requires-Dist: types-lxml; extra == "stubs"
114
+ Requires-Dist: types-cachetools; extra == "stubs"
115
+ Requires-Dist: types-requests; extra == "stubs"
116
+ Requires-Dist: types-python-dateutil; extra == "stubs"
117
+ Requires-Dist: types-setuptools; extra == "stubs"
118
+ Requires-Dist: types-tqdm; extra == "stubs"
119
+ Requires-Dist: types-urllib3; extra == "stubs"
120
+ Provides-Extra: docs
121
+ Requires-Dist: eodag[all,stubs]; extra == "docs"
122
+ Requires-Dist: sphinx; extra == "docs"
123
+ Requires-Dist: sphinx-book-theme>=1.0.0; extra == "docs"
124
+ Requires-Dist: sphinx-copybutton; extra == "docs"
125
+ Requires-Dist: sphinx-tabs; extra == "docs"
126
+ Requires-Dist: nbsphinx; extra == "docs"
127
+ Requires-Dist: sphinx_autodoc_typehints; extra == "docs"
128
+ Requires-Dist: sphinxemoji; extra == "docs"
128
129
 
129
130
  .. image:: https://eodag.readthedocs.io/en/latest/_static/eodag_bycs.png
130
131
  :target: https://github.com/CS-SI/eodag
@@ -315,7 +316,7 @@ An eodag instance can be exposed through a STAC compliant REST api from the comm
315
316
 
316
317
  .. code-block:: bash
317
318
 
318
- docker run -p 5000:5000 --rm csspace/eodag-server:3.0.1
319
+ docker run -p 5000:5000 --rm csspace/eodag-server:3.1.0b2
319
320
 
320
321
  You can also browse over your STAC API server using `STAC Browser <https://github.com/radiantearth/stac-browser>`_.
321
322
  Simply run: