eodag 3.0.0b1__py3-none-any.whl → 3.0.0b3__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.
- eodag/__init__.py +6 -8
- eodag/api/core.py +119 -171
- eodag/api/product/__init__.py +10 -4
- eodag/api/product/_assets.py +52 -14
- eodag/api/product/_product.py +59 -30
- eodag/api/product/drivers/__init__.py +7 -2
- eodag/api/product/drivers/base.py +0 -3
- eodag/api/product/metadata_mapping.py +0 -28
- eodag/api/search_result.py +31 -9
- eodag/config.py +45 -41
- eodag/plugins/apis/base.py +3 -3
- eodag/plugins/apis/ecmwf.py +2 -3
- eodag/plugins/apis/usgs.py +43 -14
- eodag/plugins/authentication/aws_auth.py +11 -2
- eodag/plugins/authentication/openid_connect.py +5 -4
- eodag/plugins/authentication/token.py +2 -1
- eodag/plugins/crunch/base.py +3 -1
- eodag/plugins/crunch/filter_date.py +3 -9
- eodag/plugins/crunch/filter_latest_intersect.py +0 -3
- eodag/plugins/crunch/filter_latest_tpl_name.py +1 -4
- eodag/plugins/crunch/filter_overlap.py +4 -8
- eodag/plugins/crunch/filter_property.py +5 -11
- eodag/plugins/download/aws.py +46 -78
- eodag/plugins/download/base.py +27 -68
- eodag/plugins/download/http.py +48 -57
- eodag/plugins/download/s3rest.py +17 -25
- eodag/plugins/manager.py +6 -18
- eodag/plugins/search/__init__.py +9 -9
- eodag/plugins/search/base.py +7 -26
- eodag/plugins/search/build_search_result.py +0 -13
- eodag/plugins/search/cop_marine.py +1 -3
- eodag/plugins/search/creodias_s3.py +0 -3
- eodag/plugins/search/data_request_search.py +10 -5
- eodag/plugins/search/qssearch.py +95 -53
- eodag/plugins/search/static_stac_search.py +6 -3
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +24 -0
- eodag/resources/providers.yml +198 -154
- eodag/resources/user_conf_template.yml +27 -27
- eodag/rest/core.py +11 -43
- eodag/rest/server.py +1 -6
- eodag/rest/stac.py +13 -87
- eodag/rest/types/eodag_search.py +4 -7
- eodag/rest/types/queryables.py +4 -12
- eodag/rest/types/stac_search.py +7 -11
- eodag/rest/utils/rfc3339.py +0 -1
- eodag/types/__init__.py +9 -3
- eodag/types/download_args.py +14 -5
- eodag/types/search_args.py +7 -8
- eodag/types/whoosh.py +0 -2
- eodag/utils/__init__.py +20 -79
- eodag/utils/constraints.py +0 -8
- eodag/utils/import_system.py +0 -4
- eodag/utils/logging.py +0 -3
- eodag/utils/notebook.py +4 -4
- eodag/utils/repr.py +113 -0
- eodag/utils/requests.py +12 -20
- eodag/utils/rest.py +0 -4
- eodag/utils/stac_reader.py +2 -14
- {eodag-3.0.0b1.dist-info → eodag-3.0.0b3.dist-info}/METADATA +33 -14
- eodag-3.0.0b3.dist-info/RECORD +110 -0
- {eodag-3.0.0b1.dist-info → eodag-3.0.0b3.dist-info}/WHEEL +1 -1
- eodag-3.0.0b1.dist-info/RECORD +0 -109
- {eodag-3.0.0b1.dist-info → eodag-3.0.0b3.dist-info}/LICENSE +0 -0
- {eodag-3.0.0b1.dist-info → eodag-3.0.0b3.dist-info}/entry_points.txt +0 -0
- {eodag-3.0.0b1.dist-info → eodag-3.0.0b3.dist-info}/top_level.txt +0 -0
eodag/api/product/__init__.py
CHANGED
|
@@ -16,11 +16,17 @@
|
|
|
16
16
|
# See the License for the specific language governing permissions and
|
|
17
17
|
# limitations under the License.
|
|
18
18
|
#
|
|
19
|
-
# type: ignore
|
|
20
19
|
"""EODAG product package"""
|
|
21
20
|
try:
|
|
22
21
|
# import from eodag-cube if installed
|
|
23
|
-
from eodag_cube.api.product import
|
|
22
|
+
from eodag_cube.api.product import ( # pyright: ignore[reportMissingImports]
|
|
23
|
+
Asset,
|
|
24
|
+
AssetsDict,
|
|
25
|
+
EOProduct,
|
|
26
|
+
)
|
|
24
27
|
except ImportError:
|
|
25
|
-
from ._assets import Asset, AssetsDict #
|
|
26
|
-
from ._product import EOProduct #
|
|
28
|
+
from ._assets import Asset, AssetsDict # type: ignore[assignment]
|
|
29
|
+
from ._product import EOProduct # type: ignore[assignment]
|
|
30
|
+
|
|
31
|
+
# exportable content
|
|
32
|
+
__all__ = ["Asset", "AssetsDict", "EOProduct"]
|
eodag/api/product/_assets.py
CHANGED
|
@@ -22,6 +22,7 @@ from collections import UserDict
|
|
|
22
22
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
|
23
23
|
|
|
24
24
|
from eodag.utils.exceptions import NotAvailableError
|
|
25
|
+
from eodag.utils.repr import dict_to_html_table
|
|
25
26
|
|
|
26
27
|
if TYPE_CHECKING:
|
|
27
28
|
from eodag.api.product import EOProduct
|
|
@@ -34,11 +35,8 @@ class AssetsDict(UserDict):
|
|
|
34
35
|
:class:`~eodag.api.product._product.EOProduct` resulting from a search.
|
|
35
36
|
|
|
36
37
|
:param product: Product resulting from a search
|
|
37
|
-
:type product: :class:`~eodag.api.product._product.EOProduct`
|
|
38
38
|
:param args: (optional) Arguments used to init the dictionary
|
|
39
|
-
:type args: Any
|
|
40
39
|
:param kwargs: (optional) Additional named-arguments used to init the dictionary
|
|
41
|
-
:type kwargs: Any
|
|
42
40
|
"""
|
|
43
41
|
|
|
44
42
|
product: EOProduct
|
|
@@ -55,17 +53,15 @@ class AssetsDict(UserDict):
|
|
|
55
53
|
|
|
56
54
|
:returns: The representation of a :class:`~eodag.api.product._assets.AssetsDict`
|
|
57
55
|
as a Python dict
|
|
58
|
-
:rtype: dict
|
|
59
56
|
"""
|
|
60
57
|
return {k: v.as_dict() for k, v in self.data.items()}
|
|
61
58
|
|
|
62
59
|
def get_values(self, asset_filter: str = "") -> List[Asset]:
|
|
63
60
|
"""
|
|
64
61
|
retrieves the assets matching the given filter
|
|
65
|
-
|
|
66
|
-
:
|
|
62
|
+
|
|
63
|
+
:param asset_filter: regex filter with which the assets should be matched
|
|
67
64
|
:return: list of assets
|
|
68
|
-
:rtype: List[Asset]
|
|
69
65
|
"""
|
|
70
66
|
if asset_filter:
|
|
71
67
|
filter_regex = re.compile(asset_filter)
|
|
@@ -84,19 +80,52 @@ class AssetsDict(UserDict):
|
|
|
84
80
|
else:
|
|
85
81
|
return [a for a in self.values() if "href" in a]
|
|
86
82
|
|
|
83
|
+
def _repr_html_(self, embeded=False):
|
|
84
|
+
thead = (
|
|
85
|
+
f"""<thead><tr><td style='text-align: left; color: grey;'>
|
|
86
|
+
{type(self).__name__} ({len(self)})
|
|
87
|
+
</td></tr></thead>
|
|
88
|
+
"""
|
|
89
|
+
if not embeded
|
|
90
|
+
else ""
|
|
91
|
+
)
|
|
92
|
+
tr_style = "style='background-color: transparent;'" if embeded else ""
|
|
93
|
+
return (
|
|
94
|
+
f"<table>{thead}"
|
|
95
|
+
+ "".join(
|
|
96
|
+
[
|
|
97
|
+
f"""<tr {tr_style}><td style='text-align: left;'>
|
|
98
|
+
<details><summary style='color: grey;'>
|
|
99
|
+
<span style='color: black'>'{k}'</span>: 
|
|
100
|
+
{{
|
|
101
|
+
{"'roles': '<span style='color: black'>"+str(v['roles'])+"</span>', "
|
|
102
|
+
if v.get("roles") else ""}
|
|
103
|
+
{"'type': '"+str(v['type'])+"', "
|
|
104
|
+
if v.get("type") else ""}
|
|
105
|
+
{"'title': '<span style='color: black'>"+str(v['title'])+"</span>', "
|
|
106
|
+
if v.get("title") else ""}
|
|
107
|
+
...
|
|
108
|
+
}}
|
|
109
|
+
</summary>
|
|
110
|
+
{dict_to_html_table(v, depth=1)}
|
|
111
|
+
</details>
|
|
112
|
+
</td></tr>
|
|
113
|
+
"""
|
|
114
|
+
for k, v in self.items()
|
|
115
|
+
]
|
|
116
|
+
)
|
|
117
|
+
+ "</table>"
|
|
118
|
+
)
|
|
119
|
+
|
|
87
120
|
|
|
88
121
|
class Asset(UserDict):
|
|
89
122
|
"""A UserDict object containg one of the assets of a
|
|
90
123
|
:class:`~eodag.api.product._product.EOProduct` resulting from a search.
|
|
91
124
|
|
|
92
125
|
:param product: Product resulting from a search
|
|
93
|
-
:type product: :class:`~eodag.api.product._product.EOProduct`
|
|
94
126
|
:param key: asset key
|
|
95
|
-
:type key: str
|
|
96
127
|
:param args: (optional) Arguments used to init the dictionary
|
|
97
|
-
:type args: Any
|
|
98
128
|
:param kwargs: (optional) Additional named-arguments used to init the dictionary
|
|
99
|
-
:type kwargs: Any
|
|
100
129
|
"""
|
|
101
130
|
|
|
102
131
|
product: EOProduct
|
|
@@ -114,7 +143,6 @@ class Asset(UserDict):
|
|
|
114
143
|
|
|
115
144
|
:returns: The representation of a :class:`~eodag.api.product._assets.Asset` as a
|
|
116
145
|
Python dict
|
|
117
|
-
:rtype: dict
|
|
118
146
|
"""
|
|
119
147
|
return self.data
|
|
120
148
|
|
|
@@ -122,8 +150,18 @@ class Asset(UserDict):
|
|
|
122
150
|
"""Downloads a single asset
|
|
123
151
|
|
|
124
152
|
:param kwargs: (optional) Additional named-arguments passed to `plugin.download()`
|
|
125
|
-
:type kwargs: Any
|
|
126
153
|
:returns: The absolute path to the downloaded product on the local filesystem
|
|
127
|
-
:rtype: str
|
|
128
154
|
"""
|
|
129
155
|
return self.product.download(asset=self.key, **kwargs)
|
|
156
|
+
|
|
157
|
+
def _repr_html_(self):
|
|
158
|
+
thead = f"""<thead><tr><td style='text-align: left; color: grey;'>
|
|
159
|
+
{type(self).__name__} - {self.key}
|
|
160
|
+
</td></tr></thead>
|
|
161
|
+
"""
|
|
162
|
+
return f"""<table>{thead}
|
|
163
|
+
<tr><td style='text-align: left;'>
|
|
164
|
+
{dict_to_html_table(self)}
|
|
165
|
+
</details>
|
|
166
|
+
</td></tr>
|
|
167
|
+
</table>"""
|
eodag/api/product/_product.py
CHANGED
|
@@ -32,9 +32,11 @@ from shapely.errors import ShapelyError
|
|
|
32
32
|
|
|
33
33
|
try:
|
|
34
34
|
# import from eodag-cube if installed
|
|
35
|
-
from eodag_cube.api.product import
|
|
35
|
+
from eodag_cube.api.product import ( # pyright: ignore[reportMissingImports]
|
|
36
|
+
AssetsDict,
|
|
37
|
+
)
|
|
36
38
|
except ImportError:
|
|
37
|
-
from eodag.api.product._assets import AssetsDict
|
|
39
|
+
from eodag.api.product._assets import AssetsDict
|
|
38
40
|
|
|
39
41
|
from eodag.api.product.drivers import DRIVERS, NoDriver
|
|
40
42
|
from eodag.api.product.metadata_mapping import (
|
|
@@ -51,6 +53,7 @@ from eodag.utils import (
|
|
|
51
53
|
get_geometry_from_various,
|
|
52
54
|
)
|
|
53
55
|
from eodag.utils.exceptions import DownloadError, MisconfiguredError
|
|
56
|
+
from eodag.utils.repr import dict_to_html_table
|
|
54
57
|
|
|
55
58
|
if TYPE_CHECKING:
|
|
56
59
|
from shapely.geometry.base import BaseGeometry
|
|
@@ -85,9 +88,7 @@ class EOProduct:
|
|
|
85
88
|
parameters that led to its creation.
|
|
86
89
|
|
|
87
90
|
:param provider: The provider from which the product originates
|
|
88
|
-
:type provider: str
|
|
89
91
|
:param properties: The metadata of the product
|
|
90
|
-
:type properties: dict
|
|
91
92
|
:ivar product_type: The product type
|
|
92
93
|
:vartype product_type: str
|
|
93
94
|
:ivar location: The path to the product, either remote or local if downloaded
|
|
@@ -179,7 +180,6 @@ class EOProduct:
|
|
|
179
180
|
|
|
180
181
|
:returns: The representation of a :class:`~eodag.api.product._product.EOProduct` as a
|
|
181
182
|
Python dict
|
|
182
|
-
:rtype: dict
|
|
183
183
|
"""
|
|
184
184
|
search_intersection = None
|
|
185
185
|
if self.search_intersection is not None:
|
|
@@ -211,9 +211,7 @@ class EOProduct:
|
|
|
211
211
|
|
|
212
212
|
:param feature: The representation of a :class:`~eodag.api.product._product.EOProduct`
|
|
213
213
|
as a Python dict
|
|
214
|
-
:type feature: dict
|
|
215
214
|
:returns: An instance of :class:`~eodag.api.product._product.EOProduct`
|
|
216
|
-
:rtype: :class:`~eodag.api.product._product.EOProduct`
|
|
217
215
|
"""
|
|
218
216
|
properties = feature["properties"]
|
|
219
217
|
properties["geometry"] = feature["geometry"]
|
|
@@ -247,11 +245,9 @@ class EOProduct:
|
|
|
247
245
|
"""Give to the product the information needed to download itself.
|
|
248
246
|
|
|
249
247
|
:param downloader: The download method that it can use
|
|
250
|
-
:type downloader: Concrete subclass of
|
|
251
248
|
:class:`~eodag.plugins.download.base.Download` or
|
|
252
249
|
:class:`~eodag.plugins.api.base.Api`
|
|
253
250
|
:param authenticator: The authentication method needed to perform the download
|
|
254
|
-
:type authenticator: Concrete subclass of
|
|
255
251
|
:class:`~eodag.plugins.authentication.base.Authentication`
|
|
256
252
|
"""
|
|
257
253
|
self.downloader = downloader
|
|
@@ -301,20 +297,15 @@ class EOProduct:
|
|
|
301
297
|
size as inputs and handle progress bar
|
|
302
298
|
creation and update to give the user a
|
|
303
299
|
feedback on the download progress
|
|
304
|
-
:type progress_callback: :class:`~eodag.utils.ProgressCallback` or None
|
|
305
300
|
:param wait: (optional) If download fails, wait time in minutes between
|
|
306
301
|
two download tries
|
|
307
|
-
:type wait: int
|
|
308
302
|
:param timeout: (optional) If download fails, maximum time in minutes
|
|
309
303
|
before stop retrying to download
|
|
310
|
-
:
|
|
311
|
-
:param kwargs: `outputs_prefix` (str), `extract` (bool), `delete_archive` (bool)
|
|
304
|
+
:param kwargs: `output_dir` (str), `extract` (bool), `delete_archive` (bool)
|
|
312
305
|
and `dl_url_params` (dict) can be provided as additional kwargs
|
|
313
306
|
and will override any other values defined in a configuration
|
|
314
307
|
file or with environment variables.
|
|
315
|
-
:type kwargs: Union[str, bool, dict]
|
|
316
308
|
:returns: The absolute path to the downloaded product on the local filesystem
|
|
317
|
-
:rtype: str
|
|
318
309
|
:raises: :class:`~eodag.utils.exceptions.PluginImplementationError`
|
|
319
310
|
:raises: :class:`RuntimeError`
|
|
320
311
|
"""
|
|
@@ -382,7 +373,7 @@ class EOProduct:
|
|
|
382
373
|
def get_quicklook(
|
|
383
374
|
self,
|
|
384
375
|
filename: Optional[str] = None,
|
|
385
|
-
|
|
376
|
+
output_dir: Optional[str] = None,
|
|
386
377
|
progress_callback: Optional[ProgressCallback] = None,
|
|
387
378
|
) -> str:
|
|
388
379
|
"""Download the quicklook image of a given EOProduct from its provider if it
|
|
@@ -390,18 +381,14 @@ class EOProduct:
|
|
|
390
381
|
|
|
391
382
|
:param filename: (optional) The name to give to the downloaded quicklook. If not
|
|
392
383
|
given, it defaults to the product's ID (without file extension).
|
|
393
|
-
:
|
|
394
|
-
:param base_dir: (optional) The absolute path of the directory where to store
|
|
384
|
+
:param output_dir: (optional) The absolute path of the directory where to store
|
|
395
385
|
the quicklooks in the filesystem. If not given, it defaults to the
|
|
396
|
-
`quicklooks` directory under this EO product downloader's ``
|
|
386
|
+
`quicklooks` directory under this EO product downloader's ``output_dir``
|
|
397
387
|
config param (e.g. '/tmp/quicklooks/')
|
|
398
|
-
:type base_dir: str
|
|
399
388
|
:param progress_callback: (optional) A method or a callable object which takes
|
|
400
389
|
a current size and a maximum size as inputs and handle progress bar
|
|
401
390
|
creation and update to give the user a feedback on the download progress
|
|
402
|
-
:type progress_callback: :class:`~eodag.utils.ProgressCallback` or None
|
|
403
391
|
:returns: The absolute path of the downloaded quicklook
|
|
404
|
-
:rtype: str
|
|
405
392
|
"""
|
|
406
393
|
|
|
407
394
|
def format_quicklook_address() -> None:
|
|
@@ -438,20 +425,20 @@ class EOProduct:
|
|
|
438
425
|
|
|
439
426
|
format_quicklook_address()
|
|
440
427
|
|
|
441
|
-
if
|
|
442
|
-
|
|
428
|
+
if output_dir is not None:
|
|
429
|
+
quicklooks_output_dir = os.path.abspath(os.path.realpath(output_dir))
|
|
443
430
|
else:
|
|
444
431
|
tempdir = tempfile.gettempdir()
|
|
445
|
-
|
|
446
|
-
getattr(self.downloader.config, "
|
|
432
|
+
downloader_output_dir = (
|
|
433
|
+
getattr(self.downloader.config, "output_dir", tempdir)
|
|
447
434
|
if self.downloader
|
|
448
435
|
else tempdir
|
|
449
436
|
)
|
|
450
|
-
|
|
451
|
-
if not os.path.isdir(
|
|
452
|
-
os.makedirs(
|
|
437
|
+
quicklooks_output_dir = os.path.join(downloader_output_dir, "quicklooks")
|
|
438
|
+
if not os.path.isdir(quicklooks_output_dir):
|
|
439
|
+
os.makedirs(quicklooks_output_dir)
|
|
453
440
|
quicklook_file = os.path.join(
|
|
454
|
-
|
|
441
|
+
quicklooks_output_dir,
|
|
455
442
|
filename if filename is not None else self.properties["id"],
|
|
456
443
|
)
|
|
457
444
|
|
|
@@ -517,3 +504,45 @@ class EOProduct:
|
|
|
517
504
|
)
|
|
518
505
|
pass
|
|
519
506
|
return NoDriver()
|
|
507
|
+
|
|
508
|
+
def _repr_html_(self):
|
|
509
|
+
thumbnail = self.properties.get("thumbnail", None)
|
|
510
|
+
thumbnail_html = (
|
|
511
|
+
f"<img src='{thumbnail}' width=100 alt='thumbnail'/>"
|
|
512
|
+
if thumbnail and not thumbnail.startswith("s3")
|
|
513
|
+
else ""
|
|
514
|
+
)
|
|
515
|
+
geom_style = "style='color: grey; text-align: center; min-width:100px; vertical-align: top;'"
|
|
516
|
+
thumbnail_style = (
|
|
517
|
+
"style='padding-top: 1.5em; min-width:100px; vertical-align: top;'"
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
return f"""<table>
|
|
521
|
+
<thead><tr style='background-color: transparent;'><td style='text-align: left; color: grey;'>
|
|
522
|
+
{type(self).__name__}
|
|
523
|
+
</td></tr></thead>
|
|
524
|
+
|
|
525
|
+
<tr style='background-color: transparent;'>
|
|
526
|
+
<td style='text-align: left; vertical-align: top;'>
|
|
527
|
+
{dict_to_html_table({
|
|
528
|
+
"provider": self.provider,
|
|
529
|
+
"product_type": self.product_type,
|
|
530
|
+
"properties["id"]": self.properties.get('id', None),
|
|
531
|
+
"properties["startTimeFromAscendingNode"]": self.properties.get(
|
|
532
|
+
'startTimeFromAscendingNode', None
|
|
533
|
+
),
|
|
534
|
+
"properties["completionTimeFromAscendingNode"]": self.properties.get(
|
|
535
|
+
'completionTimeFromAscendingNode', None
|
|
536
|
+
),
|
|
537
|
+
}, brackets=False)}
|
|
538
|
+
<details><summary style='color: grey; margin-top: 10px;'>properties: ({
|
|
539
|
+
len(self.properties)
|
|
540
|
+
})</summary>{dict_to_html_table(self.properties, depth=1)}</details>
|
|
541
|
+
<details><summary style='color: grey; margin-top: 10px;'>assets: ({
|
|
542
|
+
len(self.assets)
|
|
543
|
+
})</summary>{self.assets._repr_html_(embeded=True)}</details>
|
|
544
|
+
</td>
|
|
545
|
+
<td {geom_style} title='geometry'>geometry<br />{self.geometry._repr_svg_()}</td>
|
|
546
|
+
<td {thumbnail_style} title='properties["thumbnail"]'>{thumbnail_html}</td>
|
|
547
|
+
</tr>
|
|
548
|
+
</table>"""
|
|
@@ -16,9 +16,14 @@
|
|
|
16
16
|
# See the License for the specific language governing permissions and
|
|
17
17
|
# limitations under the License.
|
|
18
18
|
"""EODAG drivers package"""
|
|
19
|
-
from eodag.api.product.drivers.base import DatasetDriver, NoDriver
|
|
19
|
+
from eodag.api.product.drivers.base import DatasetDriver, NoDriver
|
|
20
20
|
|
|
21
21
|
try:
|
|
22
|
-
from eodag_cube.api.product.drivers import
|
|
22
|
+
from eodag_cube.api.product.drivers import ( # pyright: ignore[reportMissingImports]
|
|
23
|
+
DRIVERS,
|
|
24
|
+
)
|
|
23
25
|
except ImportError:
|
|
24
26
|
DRIVERS = []
|
|
27
|
+
|
|
28
|
+
# exportable content
|
|
29
|
+
__all__ = ["DRIVERS", "DatasetDriver", "NoDriver"]
|
|
@@ -30,11 +30,8 @@ class DatasetDriver(metaclass=type):
|
|
|
30
30
|
"""Retrieve the address of the dataset represented by `eo_product`.
|
|
31
31
|
|
|
32
32
|
:param eo_product: The product whom underlying dataset address is to be retrieved
|
|
33
|
-
:type eo_product: :class:`~eodag.api.product._product.EOProduct`
|
|
34
33
|
:param band: The band to retrieve (e.g: 'B01')
|
|
35
|
-
:type band: str
|
|
36
34
|
:returns: An address for the dataset
|
|
37
|
-
:rtype: str
|
|
38
35
|
:raises: :class:`~eodag.utils.exceptions.AddressNotFound`
|
|
39
36
|
:raises: :class:`~eodag.utils.exceptions.UnsupportedDatasetAddressScheme`
|
|
40
37
|
"""
|
|
@@ -120,10 +120,8 @@ def get_metadata_path(
|
|
|
120
120
|
in the provider search config. For example, it is the list
|
|
121
121
|
`['productType', '$.properties.productType']` with the sample
|
|
122
122
|
above. Or the string `$.properties.id`.
|
|
123
|
-
:type map_value: str or list(str)
|
|
124
123
|
:returns: Either, None and the path to the metadata value, or a list of converter
|
|
125
124
|
and its args, and the path to the metadata value.
|
|
126
|
-
:rtype: tuple(list(str) or None, str)
|
|
127
125
|
"""
|
|
128
126
|
path = get_metadata_path_value(map_value)
|
|
129
127
|
try:
|
|
@@ -147,9 +145,7 @@ def get_search_param(map_value: List[str]) -> str:
|
|
|
147
145
|
|
|
148
146
|
:param map_value: The value originating from the definition of `metadata_mapping`
|
|
149
147
|
in the provider search config
|
|
150
|
-
:type map_value: list
|
|
151
148
|
:returns: The value of the search parameter as defined in the provider config
|
|
152
|
-
:rtype: str
|
|
153
149
|
"""
|
|
154
150
|
# Assume that caller will pass in the value as a list
|
|
155
151
|
return map_value[0]
|
|
@@ -190,13 +186,9 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
|
|
|
190
186
|
- ``get_ecmwf_time``: get the time of a datetime string in the ECMWF format
|
|
191
187
|
|
|
192
188
|
:param search_param: The string to be formatted
|
|
193
|
-
:type search_param: str
|
|
194
189
|
:param args: (optional) Additional arguments to use in the formatting process
|
|
195
|
-
:type args: tuple
|
|
196
190
|
:param kwargs: (optional) Additional named-arguments to use when formatting
|
|
197
|
-
:type kwargs: Any
|
|
198
191
|
:returns: The formatted string
|
|
199
|
-
:rtype: str
|
|
200
192
|
"""
|
|
201
193
|
|
|
202
194
|
class MetadataFormatter(Formatter):
|
|
@@ -926,7 +918,6 @@ def properties_from_json(
|
|
|
926
918
|
"""Extract properties from a provider json result.
|
|
927
919
|
|
|
928
920
|
:param json: The representation of a provider result as a json object
|
|
929
|
-
:type json: dict
|
|
930
921
|
:param mapping: A mapping between :class:`~eodag.api.product._product.EOProduct`'s metadata
|
|
931
922
|
keys and the location of the values of these properties in the json
|
|
932
923
|
representation, expressed as a
|
|
@@ -934,9 +925,7 @@ def properties_from_json(
|
|
|
934
925
|
:param discovery_config: (optional) metadata discovery configuration dict, accepting among other items
|
|
935
926
|
`discovery_pattern` (Regex pattern for metadata key discovery, e.g. "^[a-zA-Z]+$"),
|
|
936
927
|
`discovery_path` (String representation of jsonpath)
|
|
937
|
-
:type discovery_config: dict
|
|
938
928
|
:returns: The metadata of the :class:`~eodag.api.product._product.EOProduct`
|
|
939
|
-
:rtype: dict
|
|
940
929
|
"""
|
|
941
930
|
properties: Dict[str, Any] = {}
|
|
942
931
|
templates = {}
|
|
@@ -1073,7 +1062,6 @@ def properties_from_xml(
|
|
|
1073
1062
|
"""Extract properties from a provider xml result.
|
|
1074
1063
|
|
|
1075
1064
|
:param xml_as_text: The representation of a provider result as xml
|
|
1076
|
-
:type xml_as_text: str
|
|
1077
1065
|
:param mapping: A mapping between :class:`~eodag.api.product._product.EOProduct`'s metadata
|
|
1078
1066
|
keys and the location of the values of these properties in the xml
|
|
1079
1067
|
representation, expressed as a
|
|
@@ -1083,13 +1071,10 @@ def properties_from_xml(
|
|
|
1083
1071
|
not supporting empty namespace prefix. The
|
|
1084
1072
|
xpath in `mapping` must use this value to be able to
|
|
1085
1073
|
correctly reach empty-namespace prefixed elements
|
|
1086
|
-
:type empty_ns_prefix: str
|
|
1087
1074
|
:param discovery_config: (optional) metadata discovery configuration dict, accepting among other items
|
|
1088
1075
|
`discovery_pattern` (Regex pattern for metadata key discovery, e.g. "^[a-zA-Z]+$"),
|
|
1089
1076
|
`discovery_path` (String representation of xpath)
|
|
1090
|
-
:type discovery_config: dict
|
|
1091
1077
|
:returns: the metadata of the :class:`~eodag.api.product._product.EOProduct`
|
|
1092
|
-
:rtype: dict
|
|
1093
1078
|
"""
|
|
1094
1079
|
properties: Dict[str, Any] = {}
|
|
1095
1080
|
templates = {}
|
|
@@ -1228,11 +1213,8 @@ def mtd_cfg_as_conversion_and_querypath(
|
|
|
1228
1213
|
or from xpath_str to tuple `(conversion, xpath_str)`
|
|
1229
1214
|
|
|
1230
1215
|
:param src_dict: Input dict containing jsonpath str as values
|
|
1231
|
-
:type src_dict: dict
|
|
1232
1216
|
:param dest_dict: (optional) Output dict containing jsonpath objects as values
|
|
1233
|
-
:type dest_dict: dict
|
|
1234
1217
|
:returns: dest_dict
|
|
1235
|
-
:rtype: dict
|
|
1236
1218
|
"""
|
|
1237
1219
|
# check if the configuration has already been converted
|
|
1238
1220
|
some_configured_value = (
|
|
@@ -1476,11 +1458,8 @@ def get_queryable_from_provider(
|
|
|
1476
1458
|
"""Get EODAG configured queryable parameter from provider queryable parameter
|
|
1477
1459
|
|
|
1478
1460
|
:param provider_queryable: provider queryable parameter
|
|
1479
|
-
:type provider_queryable: str
|
|
1480
1461
|
:param metadata_mapping: metadata-mapping configuration
|
|
1481
|
-
:type metadata_mapping: Dict[str, Union[str, List[str]]])
|
|
1482
1462
|
:returns: EODAG configured queryable parameter or None
|
|
1483
|
-
:rtype: Optional[str]
|
|
1484
1463
|
"""
|
|
1485
1464
|
pattern = rf"\b{provider_queryable}\b"
|
|
1486
1465
|
for param, param_conf in metadata_mapping.items():
|
|
@@ -1495,11 +1474,8 @@ def get_provider_queryable_path(
|
|
|
1495
1474
|
"""Get EODAG configured queryable path from its parameter
|
|
1496
1475
|
|
|
1497
1476
|
:param queryable: eodag queryable parameter
|
|
1498
|
-
:type queryable: str
|
|
1499
1477
|
:param metadata_mapping: metadata-mapping configuration
|
|
1500
|
-
:type metadata_mapping: Dict[str, Union[str, List[str]]])
|
|
1501
1478
|
:returns: EODAG configured queryable path or None
|
|
1502
|
-
:rtype: Optional[str]
|
|
1503
1479
|
"""
|
|
1504
1480
|
parameter_conf = metadata_mapping.get(queryable, None)
|
|
1505
1481
|
if isinstance(parameter_conf, list):
|
|
@@ -1515,13 +1491,9 @@ def get_provider_queryable_key(
|
|
|
1515
1491
|
) -> str:
|
|
1516
1492
|
"""finds the provider queryable corresponding to the given eodag key based on the metadata mapping
|
|
1517
1493
|
:param eodag_key: key in eodag
|
|
1518
|
-
:type eodag_key: str
|
|
1519
1494
|
:param provider_queryables: queryables returned from the provider
|
|
1520
|
-
:type provider_queryables: dict
|
|
1521
1495
|
:param metadata_mapping: metadata mapping from which the keys are retrieved
|
|
1522
|
-
:type metadata_mapping: Dict[str, Union[List[Any], str]]
|
|
1523
1496
|
:returns: provider queryable key
|
|
1524
|
-
:rtype: str
|
|
1525
1497
|
"""
|
|
1526
1498
|
if eodag_key not in metadata_mapping:
|
|
1527
1499
|
return ""
|
eodag/api/search_result.py
CHANGED
|
@@ -39,9 +39,10 @@ class SearchResult(UserList):
|
|
|
39
39
|
"""An object representing a collection of :class:`~eodag.api.product._product.EOProduct` resulting from a search.
|
|
40
40
|
|
|
41
41
|
:param products: A list of products resulting from a search
|
|
42
|
-
:type products: list(:class:`~eodag.api.product._product.EOProduct`)
|
|
43
42
|
:param number_matched: (optional) the estimated total number of matching results
|
|
44
|
-
|
|
43
|
+
|
|
44
|
+
:cvar data: List of products
|
|
45
|
+
:ivar number_matched: Estimated total number of matching results
|
|
45
46
|
"""
|
|
46
47
|
|
|
47
48
|
data: List[EOProduct]
|
|
@@ -56,11 +57,8 @@ class SearchResult(UserList):
|
|
|
56
57
|
"""Do some crunching with the underlying EO products.
|
|
57
58
|
|
|
58
59
|
:param cruncher: The plugin instance to use to work on the products
|
|
59
|
-
:type cruncher: subclass of :class:`~eodag.plugins.crunch.base.Crunch`
|
|
60
60
|
:param search_params: The criteria that have been used to produce this result
|
|
61
|
-
:type search_params: dict
|
|
62
61
|
:returns: The result of the application of the crunching method to the EO products
|
|
63
|
-
:rtype: :class:`~eodag.api.search_result.SearchResult`
|
|
64
62
|
"""
|
|
65
63
|
crunched_results = cruncher.proceed(self.data, **search_params)
|
|
66
64
|
return SearchResult(crunched_results)
|
|
@@ -135,9 +133,7 @@ class SearchResult(UserList):
|
|
|
135
133
|
"""Builds an :class:`~eodag.api.search_result.SearchResult` object from its representation as geojson
|
|
136
134
|
|
|
137
135
|
:param feature_collection: A collection representing a search result.
|
|
138
|
-
:type feature_collection: dict
|
|
139
136
|
:returns: An eodag representation of a search result
|
|
140
|
-
:rtype: :class:`~eodag.api.search_result.SearchResult`
|
|
141
137
|
"""
|
|
142
138
|
return SearchResult(
|
|
143
139
|
[
|
|
@@ -154,7 +150,7 @@ class SearchResult(UserList):
|
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
def as_shapely_geometry_object(self) -> GeometryCollection:
|
|
157
|
-
""":class:`shapely.
|
|
153
|
+
""":class:`shapely.GeometryCollection` representation of SearchResult"""
|
|
158
154
|
return GeometryCollection(
|
|
159
155
|
[
|
|
160
156
|
shape(feature["geometry"]).buffer(0)
|
|
@@ -174,12 +170,38 @@ class SearchResult(UserList):
|
|
|
174
170
|
"""
|
|
175
171
|
return self.as_geojson_object()
|
|
176
172
|
|
|
173
|
+
def _repr_html_(self):
|
|
174
|
+
total_count = f"/{self.number_matched}" if self.number_matched else ""
|
|
175
|
+
return (
|
|
176
|
+
f"""<table>
|
|
177
|
+
<thead><tr><td style='text-align: left; color: grey;'>
|
|
178
|
+
{type(self).__name__} ({len(self)}{total_count})
|
|
179
|
+
</td></tr></thead>
|
|
180
|
+
"""
|
|
181
|
+
+ "".join(
|
|
182
|
+
[
|
|
183
|
+
f"""<tr><td style='text-align: left;'>
|
|
184
|
+
<details><summary style='color: grey; font-family: monospace;'>
|
|
185
|
+
{i} 
|
|
186
|
+
{type(p).__name__}(id=<span style='color: black;'>{
|
|
187
|
+
p.properties['id']
|
|
188
|
+
}</span>, provider={p.provider})
|
|
189
|
+
</summary>
|
|
190
|
+
{p._repr_html_()}
|
|
191
|
+
</details>
|
|
192
|
+
</td></tr>
|
|
193
|
+
"""
|
|
194
|
+
for i, p in enumerate(self)
|
|
195
|
+
]
|
|
196
|
+
)
|
|
197
|
+
+ "</table>"
|
|
198
|
+
)
|
|
199
|
+
|
|
177
200
|
|
|
178
201
|
class RawSearchResult(UserList):
|
|
179
202
|
"""An object representing a collection of raw/unparsed search results obtained from a provider.
|
|
180
203
|
|
|
181
204
|
:param results: A list of raw/unparsed search results
|
|
182
|
-
:type results: List[Any]
|
|
183
205
|
"""
|
|
184
206
|
|
|
185
207
|
data: List[Any]
|