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.
- eodag/api/core.py +59 -52
- eodag/api/product/_assets.py +5 -5
- eodag/api/product/_product.py +27 -12
- eodag/api/product/drivers/__init__.py +81 -4
- eodag/api/product/drivers/base.py +65 -4
- eodag/api/product/drivers/generic.py +65 -0
- eodag/api/product/drivers/sentinel1.py +97 -0
- eodag/api/product/drivers/sentinel2.py +95 -0
- eodag/api/product/metadata_mapping.py +62 -74
- eodag/api/search_result.py +13 -23
- eodag/cli.py +4 -4
- eodag/config.py +66 -69
- eodag/plugins/apis/base.py +1 -1
- eodag/plugins/apis/ecmwf.py +10 -9
- eodag/plugins/apis/usgs.py +11 -10
- eodag/plugins/authentication/aws_auth.py +16 -13
- eodag/plugins/authentication/base.py +5 -3
- eodag/plugins/authentication/header.py +3 -3
- eodag/plugins/authentication/keycloak.py +4 -4
- eodag/plugins/authentication/oauth.py +7 -3
- eodag/plugins/authentication/openid_connect.py +14 -14
- eodag/plugins/authentication/sas_auth.py +4 -4
- eodag/plugins/authentication/token.py +7 -7
- eodag/plugins/authentication/token_exchange.py +1 -1
- eodag/plugins/base.py +4 -4
- eodag/plugins/crunch/base.py +4 -4
- eodag/plugins/crunch/filter_date.py +4 -4
- eodag/plugins/crunch/filter_latest_intersect.py +6 -6
- eodag/plugins/crunch/filter_latest_tpl_name.py +7 -7
- eodag/plugins/crunch/filter_overlap.py +4 -4
- eodag/plugins/crunch/filter_property.py +4 -4
- eodag/plugins/download/aws.py +47 -66
- eodag/plugins/download/base.py +8 -17
- eodag/plugins/download/creodias_s3.py +2 -2
- eodag/plugins/download/http.py +30 -32
- eodag/plugins/download/s3rest.py +5 -4
- eodag/plugins/manager.py +10 -20
- eodag/plugins/search/__init__.py +6 -5
- eodag/plugins/search/base.py +35 -40
- eodag/plugins/search/build_search_result.py +69 -68
- eodag/plugins/search/cop_marine.py +22 -12
- eodag/plugins/search/creodias_s3.py +8 -78
- eodag/plugins/search/csw.py +11 -11
- eodag/plugins/search/data_request_search.py +16 -15
- eodag/plugins/search/qssearch.py +56 -52
- eodag/plugins/search/stac_list_assets.py +85 -0
- eodag/plugins/search/static_stac_search.py +3 -3
- eodag/resources/ext_product_types.json +1 -1
- eodag/resources/product_types.yml +288 -288
- eodag/resources/providers.yml +146 -6
- eodag/resources/stac_api.yml +2 -2
- eodag/resources/user_conf_template.yml +11 -0
- eodag/rest/cache.py +2 -2
- eodag/rest/config.py +3 -3
- eodag/rest/core.py +24 -24
- eodag/rest/errors.py +5 -5
- eodag/rest/server.py +3 -11
- eodag/rest/stac.py +40 -38
- eodag/rest/types/collections_search.py +3 -3
- eodag/rest/types/eodag_search.py +23 -23
- eodag/rest/types/queryables.py +13 -13
- eodag/rest/types/stac_search.py +15 -25
- eodag/rest/utils/__init__.py +11 -21
- eodag/rest/utils/cql_evaluate.py +6 -6
- eodag/rest/utils/rfc3339.py +2 -2
- eodag/types/__init__.py +24 -18
- eodag/types/bbox.py +2 -2
- eodag/types/download_args.py +2 -2
- eodag/types/queryables.py +5 -2
- eodag/types/search_args.py +4 -4
- eodag/types/whoosh.py +1 -3
- eodag/utils/__init__.py +81 -40
- eodag/utils/exceptions.py +2 -2
- eodag/utils/import_system.py +2 -2
- eodag/utils/requests.py +2 -2
- eodag/utils/rest.py +2 -2
- eodag/utils/s3.py +208 -0
- eodag/utils/stac_reader.py +10 -10
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/METADATA +5 -4
- eodag-3.1.0b2.dist-info/RECORD +113 -0
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/entry_points.txt +1 -0
- eodag-3.1.0b1.dist-info/RECORD +0 -108
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/LICENSE +0 -0
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/WHEEL +0 -0
- {eodag-3.1.0b1.dist-info → eodag-3.1.0b2.dist-info}/top_level.txt +0 -0
eodag/resources/providers.yml
CHANGED
|
@@ -1886,7 +1886,7 @@
|
|
|
1886
1886
|
"ecmwf:expver": prod
|
|
1887
1887
|
"ecmwf:type": cf
|
|
1888
1888
|
"ecmwf:levtype": sfc
|
|
1889
|
-
"ecmwf:origin":
|
|
1889
|
+
"ecmwf:origin": ecmwf
|
|
1890
1890
|
"ecmwf:grid": 0.5/0.5
|
|
1891
1891
|
"ecmwf:param": 59/134/136/146/147/151/165/166/167/168/172/176/177/179/189/235/228002/228039/228139/228141/228144/228164/228228
|
|
1892
1892
|
"ecmwf:step": 0
|
|
@@ -4550,7 +4550,7 @@
|
|
|
4550
4550
|
- '{$.Footprint#from_ewkt}'
|
|
4551
4551
|
# The url to download the product "as is" (literal or as a template to be completed either after the search result
|
|
4552
4552
|
# is obtained from the provider or during the eodag download phase)
|
|
4553
|
-
downloadLink: '
|
|
4553
|
+
downloadLink: '$.S3Path.`sub(/^(.*)$/, s3:/\\1)`'
|
|
4554
4554
|
# storageStatus: must be one of ONLINE, STAGING, OFFLINE
|
|
4555
4555
|
storageStatus: '{$.Online#get_group_name((?P<ONLINE>True)|(?P<OFFLINE>False))}'
|
|
4556
4556
|
collection:
|
|
@@ -4558,8 +4558,6 @@
|
|
|
4558
4558
|
- $.null
|
|
4559
4559
|
quicklook: '$.Assets[?(@.Type="QUICKLOOK")].DownloadLink'
|
|
4560
4560
|
thumbnail: '$.Assets[?(@.Type="QUICKLOOK")].DownloadLink'
|
|
4561
|
-
# Additional metadata provided by the providers but that don't appear in the reference spec
|
|
4562
|
-
productIdentifier: '$.S3Path'
|
|
4563
4561
|
download: !plugin
|
|
4564
4562
|
type: CreodiasS3Download
|
|
4565
4563
|
s3_endpoint: 'https://eodata.cloudferro.com'
|
|
@@ -4785,6 +4783,7 @@
|
|
|
4785
4783
|
search: !plugin
|
|
4786
4784
|
type: ECMWFSearch
|
|
4787
4785
|
ssl_verify: true
|
|
4786
|
+
dates_required: True
|
|
4788
4787
|
discover_queryables:
|
|
4789
4788
|
fetch_url: null
|
|
4790
4789
|
product_type_fetch_url: null
|
|
@@ -5887,6 +5886,9 @@
|
|
|
5887
5886
|
completionTimeFromAscendingNode: temporal:endDate
|
|
5888
5887
|
platformSerialIdentifier: spaceborne:satellitePlatform
|
|
5889
5888
|
cloudCover: spaceborne:cloudCover
|
|
5889
|
+
sort_order_mapping:
|
|
5890
|
+
ascending: asc
|
|
5891
|
+
descending: desc
|
|
5890
5892
|
metadata_mapping:
|
|
5891
5893
|
uid: '$.id'
|
|
5892
5894
|
# OpenSearch Parameters for Collection Search (Table 3)
|
|
@@ -5907,8 +5909,11 @@
|
|
|
5907
5909
|
keyword: '$.properties."spaceborne:keywords"'
|
|
5908
5910
|
# OpenSearch Parameters for Product Search (Table 5)
|
|
5909
5911
|
orbitNumber:
|
|
5910
|
-
- '{{"query":{{"spaceborne:absoluteOrbitID":{{"eq":
|
|
5912
|
+
- '{{"query":{{"spaceborne:absoluteOrbitID":{{"eq":{orbitNumber}}}}}}}'
|
|
5911
5913
|
- '$.properties."spaceborne:absoluteOrbitID"'
|
|
5914
|
+
relativeOrbitNumber:
|
|
5915
|
+
- '{{"query":{{"spaceborne:orbitID":{{"eq":{relativeOrbitNumber}}}}}}}'
|
|
5916
|
+
- '$.properties."spaceborne:orbitID"'
|
|
5912
5917
|
orbitDirection:
|
|
5913
5918
|
- '{{"query":{{"spaceborne:orbitDirection":{{"eq":"{orbitDirection}"}}}}}}'
|
|
5914
5919
|
- '$.properties."spaceborne:orbitDirection"'
|
|
@@ -5916,7 +5921,7 @@
|
|
|
5916
5921
|
- '{{"query":{{"spaceborne:swath":{{"eq":"{swathIdentifier}"}}}}}}'
|
|
5917
5922
|
- '$.properties."spaceborne:swath"'
|
|
5918
5923
|
cloudCover:
|
|
5919
|
-
- '{{"query":{{"spaceborne:cloudCover":{{"lte":
|
|
5924
|
+
- '{{"query":{{"spaceborne:cloudCover":{{"lte":{cloudCover}}}}}}}'
|
|
5920
5925
|
- '$.properties."spaceborne:cloudCover"'
|
|
5921
5926
|
sensorMode:
|
|
5922
5927
|
- '{{"query":{{"spaceborne:sensorMode":{{"eq":"{sensorMode}"}}}}}}'
|
|
@@ -5982,6 +5987,141 @@
|
|
|
5982
5987
|
headers:
|
|
5983
5988
|
X-API-Key: "{apikey}"
|
|
5984
5989
|
|
|
5990
|
+
---
|
|
5991
|
+
!provider # MARK: geodes_s3
|
|
5992
|
+
name: geodes_s3
|
|
5993
|
+
priority: 0
|
|
5994
|
+
roles:
|
|
5995
|
+
- host
|
|
5996
|
+
description: French National Space Agency (CNES) Earth Observation portal with internal s3 Datalake
|
|
5997
|
+
url: https://geodes.cnes.fr
|
|
5998
|
+
search: !plugin
|
|
5999
|
+
type: StacListAssets
|
|
6000
|
+
api_endpoint: https://geodes-portal.cnes.fr/api/stac/search
|
|
6001
|
+
s3_endpoint: https://s3.datalake.cnes.fr
|
|
6002
|
+
need_auth: true
|
|
6003
|
+
ssl_verify: false
|
|
6004
|
+
discover_queryables:
|
|
6005
|
+
fetch_url: null
|
|
6006
|
+
product_type_fetch_url: null
|
|
6007
|
+
discover_product_types:
|
|
6008
|
+
fetch_url: https://geodes-portal.cnes.fr/api/stac/collections
|
|
6009
|
+
fetch_method: POST
|
|
6010
|
+
fetch_body:
|
|
6011
|
+
limit: 10000
|
|
6012
|
+
pagination:
|
|
6013
|
+
total_items_nb_key_path: '$.context.matched'
|
|
6014
|
+
# 1000 is ok and 2000 fails
|
|
6015
|
+
max_items_per_page: 1000
|
|
6016
|
+
sort:
|
|
6017
|
+
sort_by_tpl: '{{"sortBy": [ {{"field": "{sort_param}", "direction": "{sort_order}" }} ] }}'
|
|
6018
|
+
sort_by_default:
|
|
6019
|
+
- !!python/tuple [startTimeFromAscendingNode, ASC]
|
|
6020
|
+
sort_param_mapping:
|
|
6021
|
+
id: spaceborne:s2TakeId
|
|
6022
|
+
startTimeFromAscendingNode: temporal:startDate
|
|
6023
|
+
completionTimeFromAscendingNode: temporal:endDate
|
|
6024
|
+
platformSerialIdentifier: spaceborne:satellitePlatform
|
|
6025
|
+
cloudCover: spaceborne:cloudCover
|
|
6026
|
+
sort_order_mapping:
|
|
6027
|
+
ascending: asc
|
|
6028
|
+
descending: desc
|
|
6029
|
+
metadata_mapping:
|
|
6030
|
+
uid: '$.id'
|
|
6031
|
+
# OpenSearch Parameters for Collection Search (Table 3)
|
|
6032
|
+
productType:
|
|
6033
|
+
- '{{"query":{{"dataType":{{"eq":"{productType}"}}}}}}'
|
|
6034
|
+
- '$.properties."dataType"'
|
|
6035
|
+
processingLevel:
|
|
6036
|
+
- '{{"query":{{"spaceborne:productLevel":{{"eq":"{processingLevel}"}}}}}}'
|
|
6037
|
+
- '$.properties."spaceborne:productLevel"'
|
|
6038
|
+
platformSerialIdentifier:
|
|
6039
|
+
- '{{"query":{{"spaceborne:satellitePlatform":{{"eq":"{platformSerialIdentifier}"}}}}}}'
|
|
6040
|
+
- '$.properties."spaceborne:satellitePlatform"'
|
|
6041
|
+
instrument:
|
|
6042
|
+
- '{{"query":{{"spaceborne:satelliteSensor":{{"eq":"{instrument}"}}}}}}'
|
|
6043
|
+
- '$.properties."spaceborne:satelliteSensor"'
|
|
6044
|
+
# INSPIRE obligated OpenSearch Parameters for Collection Search (Table 4)
|
|
6045
|
+
title: '$.properties.identifier'
|
|
6046
|
+
keyword: '$.properties."spaceborne:keywords"'
|
|
6047
|
+
# OpenSearch Parameters for Product Search (Table 5)
|
|
6048
|
+
orbitNumber:
|
|
6049
|
+
- '{{"query":{{"spaceborne:absoluteOrbitID":{{"eq":{orbitNumber}}}}}}}'
|
|
6050
|
+
- '$.properties."spaceborne:absoluteOrbitID"'
|
|
6051
|
+
relativeOrbitNumber:
|
|
6052
|
+
- '{{"query":{{"spaceborne:orbitID":{{"eq":{relativeOrbitNumber}}}}}}}'
|
|
6053
|
+
- '$.properties."spaceborne:orbitID"'
|
|
6054
|
+
orbitDirection:
|
|
6055
|
+
- '{{"query":{{"spaceborne:orbitDirection":{{"eq":"{orbitDirection}"}}}}}}'
|
|
6056
|
+
- '$.properties."spaceborne:orbitDirection"'
|
|
6057
|
+
swathIdentifier:
|
|
6058
|
+
- '{{"query":{{"spaceborne:swath":{{"eq":"{swathIdentifier}"}}}}}}'
|
|
6059
|
+
- '$.properties."spaceborne:swath"'
|
|
6060
|
+
cloudCover:
|
|
6061
|
+
- '{{"query":{{"spaceborne:cloudCover":{{"lte":{cloudCover}}}}}}}'
|
|
6062
|
+
- '$.properties."spaceborne:cloudCover"'
|
|
6063
|
+
sensorMode:
|
|
6064
|
+
- '{{"query":{{"spaceborne:sensorMode":{{"eq":"{sensorMode}"}}}}}}'
|
|
6065
|
+
- '$.properties."spaceborne:sensorMode"'
|
|
6066
|
+
# OpenSearch Parameters for Acquistion Parameters Search (Table 6)
|
|
6067
|
+
startTimeFromAscendingNode:
|
|
6068
|
+
- '{{"query":{{"temporal:endDate":{{"gte":"{startTimeFromAscendingNode#to_iso_utc_datetime}"}}}}}}'
|
|
6069
|
+
- '$.properties."temporal:startDate"'
|
|
6070
|
+
completionTimeFromAscendingNode:
|
|
6071
|
+
- '{{"query":{{"temporal:startDate":{{"lte":"{completionTimeFromAscendingNode#to_iso_utc_datetime}"}}}}}}'
|
|
6072
|
+
- '$.properties."temporal:endDate"'
|
|
6073
|
+
polarizationChannels:
|
|
6074
|
+
- '{{"query":{{"spaceborne:polarization":{{"eq":"{polarizationChannels}"}}}}}}'
|
|
6075
|
+
- '$.properties."spaceborne:polarization"'
|
|
6076
|
+
# Custom parameters (not defined in the base document referenced above)
|
|
6077
|
+
id:
|
|
6078
|
+
- '{{"query":{{"identifier":{{"eq":"{id}"}}}}}}'
|
|
6079
|
+
- '$.properties.identifier'
|
|
6080
|
+
tileIdentifier:
|
|
6081
|
+
- '{{"query":{{"spaceborne:tile":{{"contains":"{tileIdentifier}"}}}}}}'
|
|
6082
|
+
- '{$.properties."spaceborne:tile"#replace_str(r"^T?(.*)$",r"\1")}'
|
|
6083
|
+
geometry:
|
|
6084
|
+
- '{{"intersects":{geometry#to_geojson}}}'
|
|
6085
|
+
- '($.geometry.`str()`.`sub(/^None$/, POLYGON((180 -90, 180 90, -180 90, -180 -90, 180 -90)))`)|($.geometry[*])'
|
|
6086
|
+
providerProductType:
|
|
6087
|
+
- '{{"query":{{"spaceborne:productType":{{"eq":"{providerProductType}"}}}}}}'
|
|
6088
|
+
- '$.null'
|
|
6089
|
+
downloadLink: '$.properties["accessService:endpointURL"]'
|
|
6090
|
+
quicklook: '$.assets[?(@.roles[0] == "overview")].href.`sub(/^(.*)$/, \\1?scope=gdh)`'
|
|
6091
|
+
thumbnail: '$.assets[?(@.roles[0] == "overview")].href.`sub(/^(.*)$/, \\1?scope=gdh)`'
|
|
6092
|
+
# storageStatus set to ONLINE for consistency between providers
|
|
6093
|
+
storageStatus: '{$.null#replace_str("Not Available","ONLINE")}'
|
|
6094
|
+
products:
|
|
6095
|
+
S1_SAR_OCN:
|
|
6096
|
+
providerProductType: OCN
|
|
6097
|
+
productType: PEPS_S1_L2
|
|
6098
|
+
metadata_mapping:
|
|
6099
|
+
cloudCover: '$.null'
|
|
6100
|
+
S1_SAR_GRD:
|
|
6101
|
+
providerProductType: GRD
|
|
6102
|
+
productType: PEPS_S1_L1
|
|
6103
|
+
metadata_mapping:
|
|
6104
|
+
cloudCover: '$.null'
|
|
6105
|
+
S1_SAR_SLC:
|
|
6106
|
+
providerProductType: SLC
|
|
6107
|
+
productType: PEPS_S1_L1
|
|
6108
|
+
metadata_mapping:
|
|
6109
|
+
cloudCover: '$.null'
|
|
6110
|
+
S2_MSI_L1C:
|
|
6111
|
+
productType: PEPS_S2_L1C
|
|
6112
|
+
S2_MSI_L2A_MAJA:
|
|
6113
|
+
productType: MUSCATE_SENTINEL2_SENTINEL2_L2A
|
|
6114
|
+
GENERIC_PRODUCT_TYPE:
|
|
6115
|
+
productType: '{productType}'
|
|
6116
|
+
download: !plugin
|
|
6117
|
+
type: AwsDownload
|
|
6118
|
+
s3_endpoint: https://s3.datalake.cnes.fr
|
|
6119
|
+
auth: !plugin
|
|
6120
|
+
type: AwsAuth
|
|
6121
|
+
auth_error_code: 403
|
|
6122
|
+
matching_conf:
|
|
6123
|
+
s3_endpoint: https://s3.datalake.cnes.fr
|
|
6124
|
+
|
|
5985
6125
|
---
|
|
5986
6126
|
!provider # MARK: cop_ewds
|
|
5987
6127
|
name: cop_ewds
|
eodag/resources/stac_api.yml
CHANGED
|
@@ -799,7 +799,7 @@ components:
|
|
|
799
799
|
description: |
|
|
800
800
|
Sentinel-2 is a wide-swath, high-resolution, multi-spectral
|
|
801
801
|
imaging mission...
|
|
802
|
-
license:
|
|
802
|
+
license: other
|
|
803
803
|
keywords:
|
|
804
804
|
- copernicus
|
|
805
805
|
- esa
|
|
@@ -1416,7 +1416,7 @@ components:
|
|
|
1416
1416
|
description: |-
|
|
1417
1417
|
License(s) of the data as a SPDX
|
|
1418
1418
|
[License identifier](https://spdx.org/licenses/). Alternatively, use
|
|
1419
|
-
`
|
|
1419
|
+
`other` if the license is not on the SPDX license list or
|
|
1420
1420
|
`various` if multiple licenses apply. In these two cases links to the
|
|
1421
1421
|
license texts SHOULD be added, see the `license` link relation type.
|
|
1422
1422
|
|
|
@@ -157,6 +157,17 @@ geodes:
|
|
|
157
157
|
download:
|
|
158
158
|
extract:
|
|
159
159
|
output_dir:
|
|
160
|
+
geodes:
|
|
161
|
+
priority: # Lower value means lower priority (Default: 0)
|
|
162
|
+
search: # Search parameters configuration
|
|
163
|
+
auth:
|
|
164
|
+
credentials:
|
|
165
|
+
aws_access_key_id:
|
|
166
|
+
aws_secret_access_key:
|
|
167
|
+
aws_session_token:
|
|
168
|
+
download:
|
|
169
|
+
extract:
|
|
170
|
+
output_dir:
|
|
160
171
|
hydroweb_next:
|
|
161
172
|
priority: # Lower value means lower priority (Default: 0)
|
|
162
173
|
search: # Search parameters configuration
|
eodag/rest/cache.py
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# See the License for the specific language governing permissions and
|
|
17
17
|
# limitations under the License.
|
|
18
18
|
import logging
|
|
19
|
-
from typing import Any, Callable, Coroutine,
|
|
19
|
+
from typing import Any, Callable, Coroutine, TypeVar, cast
|
|
20
20
|
|
|
21
21
|
import orjson
|
|
22
22
|
from cachetools import LRUCache
|
|
@@ -48,7 +48,7 @@ async def cached(
|
|
|
48
48
|
host_cache_key = f"{cache_key}:{host}"
|
|
49
49
|
|
|
50
50
|
try:
|
|
51
|
-
c:
|
|
51
|
+
c: dict[str, Any] = request.app.state.cache
|
|
52
52
|
|
|
53
53
|
if cached := c.get(host_cache_key):
|
|
54
54
|
logger.debug("Cache result hit")
|
eodag/rest/config.py
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
from functools import lru_cache
|
|
21
|
-
from typing import Annotated,
|
|
21
|
+
from typing import Annotated, Union
|
|
22
22
|
|
|
23
23
|
from pydantic import Field
|
|
24
24
|
from pydantic.functional_validators import BeforeValidator
|
|
@@ -28,7 +28,7 @@ from typing_extensions import Doc
|
|
|
28
28
|
from eodag.rest.constants import DEFAULT_MAXSIZE, DEFAULT_TTL
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def str2liststr(raw: Union[str,
|
|
31
|
+
def str2liststr(raw: Union[str, list[str]]) -> list[str]:
|
|
32
32
|
"""Convert str to list[str]"""
|
|
33
33
|
if isinstance(raw, list):
|
|
34
34
|
return raw
|
|
@@ -49,7 +49,7 @@ class Settings(BaseSettings):
|
|
|
49
49
|
stac_api_landing_id: str = "eodag-stac-api"
|
|
50
50
|
|
|
51
51
|
origin_url_blacklist: Annotated[
|
|
52
|
-
Union[str,
|
|
52
|
+
Union[str, list[str]],
|
|
53
53
|
BeforeValidator(str2liststr),
|
|
54
54
|
Doc(
|
|
55
55
|
"Hide from clients items assets' alternative URLs starting with URLs from the list"
|
eodag/rest/core.py
CHANGED
|
@@ -77,7 +77,7 @@ from eodag.utils.exceptions import (
|
|
|
77
77
|
)
|
|
78
78
|
|
|
79
79
|
if TYPE_CHECKING:
|
|
80
|
-
from typing import Any,
|
|
80
|
+
from typing import Any, Optional, Union
|
|
81
81
|
|
|
82
82
|
from fastapi import Request
|
|
83
83
|
from requests.auth import AuthBase
|
|
@@ -116,12 +116,12 @@ def get_home_page_content(base_url: str, ipp: Optional[int] = None) -> str:
|
|
|
116
116
|
reason="Function internally used by get_home_page_content, also deprecated",
|
|
117
117
|
version="2.6.1",
|
|
118
118
|
)
|
|
119
|
-
def format_product_types(product_types:
|
|
119
|
+
def format_product_types(product_types: list[dict[str, Any]]) -> str:
|
|
120
120
|
"""Format product_types
|
|
121
121
|
|
|
122
122
|
:param product_types: A list of EODAG product types as returned by the core api
|
|
123
123
|
"""
|
|
124
|
-
result:
|
|
124
|
+
result: list[str] = []
|
|
125
125
|
for pt in product_types:
|
|
126
126
|
result.append(f'* *__{pt["ID"]}__*: {pt["abstract"]}')
|
|
127
127
|
return "\n".join(sorted(result))
|
|
@@ -130,7 +130,7 @@ def format_product_types(product_types: List[Dict[str, Any]]) -> str:
|
|
|
130
130
|
def search_stac_items(
|
|
131
131
|
request: Request,
|
|
132
132
|
search_request: SearchPostRequest,
|
|
133
|
-
) ->
|
|
133
|
+
) -> dict[str, Any]:
|
|
134
134
|
"""
|
|
135
135
|
Search and retrieve STAC items based on the given search request.
|
|
136
136
|
|
|
@@ -309,8 +309,8 @@ def download_stac_item(
|
|
|
309
309
|
|
|
310
310
|
def _order_and_update(
|
|
311
311
|
product: EOProduct,
|
|
312
|
-
auth: Union[AuthBase,
|
|
313
|
-
query_args:
|
|
312
|
+
auth: Union[AuthBase, dict[str, str], None],
|
|
313
|
+
query_args: dict[str, Any],
|
|
314
314
|
) -> None:
|
|
315
315
|
"""Order product if needed and update given kwargs with order-status-dict"""
|
|
316
316
|
if product.properties.get("storageStatus") != ONLINE_STATUS and hasattr(
|
|
@@ -353,7 +353,7 @@ def _order_and_update(
|
|
|
353
353
|
|
|
354
354
|
|
|
355
355
|
@lru_cache(maxsize=1)
|
|
356
|
-
def get_detailled_collections_list() ->
|
|
356
|
+
def get_detailled_collections_list() -> list[dict[str, Any]]:
|
|
357
357
|
"""Returns detailled collections / product_types list as a list of
|
|
358
358
|
config dicts
|
|
359
359
|
|
|
@@ -370,7 +370,7 @@ async def all_collections(
|
|
|
370
370
|
instrument: Optional[str] = None,
|
|
371
371
|
constellation: Optional[str] = None,
|
|
372
372
|
datetime: Optional[str] = None,
|
|
373
|
-
) ->
|
|
373
|
+
) -> dict[str, Any]:
|
|
374
374
|
"""Build STAC collections
|
|
375
375
|
|
|
376
376
|
:param url: Requested URL
|
|
@@ -380,7 +380,7 @@ async def all_collections(
|
|
|
380
380
|
:returns: Collections dictionary
|
|
381
381
|
"""
|
|
382
382
|
|
|
383
|
-
async def _fetch() ->
|
|
383
|
+
async def _fetch() -> dict[str, Any]:
|
|
384
384
|
stac_collection = StacCollection(
|
|
385
385
|
url=request.state.url,
|
|
386
386
|
stac_config=stac_config,
|
|
@@ -422,7 +422,7 @@ async def all_collections(
|
|
|
422
422
|
|
|
423
423
|
async def get_collection(
|
|
424
424
|
request: Request, collection_id: str, provider: Optional[str] = None
|
|
425
|
-
) ->
|
|
425
|
+
) -> dict[str, Any]:
|
|
426
426
|
"""Build STAC collection by id
|
|
427
427
|
|
|
428
428
|
:param url: Requested URL
|
|
@@ -432,7 +432,7 @@ async def get_collection(
|
|
|
432
432
|
:returns: Collection dictionary
|
|
433
433
|
"""
|
|
434
434
|
|
|
435
|
-
async def _fetch() ->
|
|
435
|
+
async def _fetch() -> dict[str, Any]:
|
|
436
436
|
stac_collection = StacCollection(
|
|
437
437
|
url=request.state.url,
|
|
438
438
|
stac_config=stac_config,
|
|
@@ -455,7 +455,7 @@ async def get_stac_catalogs(
|
|
|
455
455
|
request: Request,
|
|
456
456
|
url: str,
|
|
457
457
|
provider: Optional[str] = None,
|
|
458
|
-
) ->
|
|
458
|
+
) -> dict[str, Any]:
|
|
459
459
|
"""Build STAC catalog
|
|
460
460
|
|
|
461
461
|
:param url: Requested URL
|
|
@@ -464,7 +464,7 @@ async def get_stac_catalogs(
|
|
|
464
464
|
:returns: Catalog dictionary
|
|
465
465
|
"""
|
|
466
466
|
|
|
467
|
-
async def _fetch() ->
|
|
467
|
+
async def _fetch() -> dict[str, Any]:
|
|
468
468
|
return StacCatalog(
|
|
469
469
|
url=url,
|
|
470
470
|
stac_config=stac_config,
|
|
@@ -523,7 +523,7 @@ def time_interval_overlap(eodag_args: EODAGSearch, catalog: StacCatalog) -> bool
|
|
|
523
523
|
|
|
524
524
|
|
|
525
525
|
@lru_cache(maxsize=1)
|
|
526
|
-
def get_stac_conformance() ->
|
|
526
|
+
def get_stac_conformance() -> dict[str, str]:
|
|
527
527
|
"""Build STAC conformance
|
|
528
528
|
|
|
529
529
|
:returns: conformance dictionary
|
|
@@ -540,7 +540,7 @@ def get_stac_api_version() -> str:
|
|
|
540
540
|
|
|
541
541
|
|
|
542
542
|
@lru_cache(maxsize=1)
|
|
543
|
-
def get_stac_extension_oseo(url: str) ->
|
|
543
|
+
def get_stac_extension_oseo(url: str) -> dict[str, str]:
|
|
544
544
|
"""Build STAC OGC / OpenSearch Extension for EO
|
|
545
545
|
|
|
546
546
|
:param url: Requested URL
|
|
@@ -571,14 +571,14 @@ async def get_queryables(
|
|
|
571
571
|
request: Request,
|
|
572
572
|
params: QueryablesGetParams,
|
|
573
573
|
provider: Optional[str] = None,
|
|
574
|
-
) ->
|
|
574
|
+
) -> dict[str, Any]:
|
|
575
575
|
"""Fetch the queryable properties for a collection.
|
|
576
576
|
|
|
577
577
|
:param collection_id: The ID of the collection.
|
|
578
578
|
:returns: A set containing the STAC standardized queryable properties for a collection.
|
|
579
579
|
"""
|
|
580
580
|
|
|
581
|
-
async def _fetch() ->
|
|
581
|
+
async def _fetch() -> dict[str, Any]:
|
|
582
582
|
python_queryables = eodag_api.list_queryables(
|
|
583
583
|
provider=provider,
|
|
584
584
|
fetch_providers=False,
|
|
@@ -589,8 +589,8 @@ async def get_queryables(
|
|
|
589
589
|
by_alias=True
|
|
590
590
|
)
|
|
591
591
|
|
|
592
|
-
properties:
|
|
593
|
-
required:
|
|
592
|
+
properties: dict[str, Any] = python_queryables_json["properties"]
|
|
593
|
+
required: list[str] = python_queryables_json.get("required") or []
|
|
594
594
|
|
|
595
595
|
# productType is either simply removed or replaced by collection later.
|
|
596
596
|
if "productType" in properties:
|
|
@@ -598,7 +598,7 @@ async def get_queryables(
|
|
|
598
598
|
if "productType" in required:
|
|
599
599
|
required.remove("productType")
|
|
600
600
|
|
|
601
|
-
stac_properties:
|
|
601
|
+
stac_properties: dict[str, Any] = {}
|
|
602
602
|
|
|
603
603
|
# get stac default properties to set prefixes
|
|
604
604
|
stac_item_properties = list(stac_config["item"]["properties"].values())
|
|
@@ -687,7 +687,7 @@ def crunch_products(
|
|
|
687
687
|
f'Unknown crunch name. Use one of: {", ".join(crunchers.keys())}'
|
|
688
688
|
)
|
|
689
689
|
|
|
690
|
-
cruncher_config:
|
|
690
|
+
cruncher_config: dict[str, Any] = {}
|
|
691
691
|
for config_param in cruncher.config_params:
|
|
692
692
|
config_param_value = kwargs.get(config_param)
|
|
693
693
|
if not config_param_value:
|
|
@@ -720,13 +720,13 @@ def eodag_api_init() -> None:
|
|
|
720
720
|
ext_col = StacCollection.ext_stac_collections.get(key)
|
|
721
721
|
if not ext_col:
|
|
722
722
|
continue
|
|
723
|
-
platform: Union[str,
|
|
723
|
+
platform: Union[str, list[str]] = ext_col.get("summaries", {}).get(
|
|
724
724
|
"platform"
|
|
725
725
|
)
|
|
726
|
-
constellation: Union[str,
|
|
726
|
+
constellation: Union[str, list[str]] = ext_col.get("summaries", {}).get(
|
|
727
727
|
"constellation"
|
|
728
728
|
)
|
|
729
|
-
processing_level: Union[str,
|
|
729
|
+
processing_level: Union[str, list[str]] = ext_col.get("summaries", {}).get(
|
|
730
730
|
"processing:level"
|
|
731
731
|
)
|
|
732
732
|
# Check if platform or constellation are lists and join them into a string if they are
|
eodag/rest/errors.py
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# See the License for the specific language governing permissions and
|
|
17
17
|
# limitations under the License.
|
|
18
18
|
import logging
|
|
19
|
-
from typing import
|
|
19
|
+
from typing import Union
|
|
20
20
|
|
|
21
21
|
from fastapi import FastAPI, Request
|
|
22
22
|
from fastapi.responses import ORJSONResponse
|
|
@@ -56,16 +56,16 @@ logger = logging.getLogger("eodag.rest.server")
|
|
|
56
56
|
class ResponseSearchError(Exception):
|
|
57
57
|
"""Represent a EODAG search error response"""
|
|
58
58
|
|
|
59
|
-
def __init__(self, errors:
|
|
59
|
+
def __init__(self, errors: list[tuple[str, Exception]]) -> None:
|
|
60
60
|
self._errors = errors
|
|
61
61
|
|
|
62
62
|
@property
|
|
63
|
-
def errors(self) ->
|
|
63
|
+
def errors(self) -> list[dict[str, Union[str, int]]]:
|
|
64
64
|
"""return errors as a list of dict"""
|
|
65
|
-
error_list:
|
|
65
|
+
error_list: list[dict[str, Union[str, int]]] = []
|
|
66
66
|
for name, exception in self._errors:
|
|
67
67
|
|
|
68
|
-
error_dict:
|
|
68
|
+
error_dict: dict[str, Union[str, int]] = {
|
|
69
69
|
"provider": name,
|
|
70
70
|
"error": exception.__class__.__name__,
|
|
71
71
|
}
|
eodag/rest/server.py
CHANGED
|
@@ -23,15 +23,7 @@ import re
|
|
|
23
23
|
from contextlib import asynccontextmanager
|
|
24
24
|
from importlib.metadata import version
|
|
25
25
|
from json import JSONDecodeError
|
|
26
|
-
from typing import
|
|
27
|
-
TYPE_CHECKING,
|
|
28
|
-
Any,
|
|
29
|
-
AsyncGenerator,
|
|
30
|
-
Awaitable,
|
|
31
|
-
Callable,
|
|
32
|
-
Dict,
|
|
33
|
-
Optional,
|
|
34
|
-
)
|
|
26
|
+
from typing import TYPE_CHECKING, Any, AsyncGenerator, Awaitable, Callable, Optional
|
|
35
27
|
|
|
36
28
|
from fastapi import APIRouter as FastAPIRouter
|
|
37
29
|
from fastapi import FastAPI, HTTPException, Request
|
|
@@ -131,7 +123,7 @@ stac_api_config = load_stac_api_config()
|
|
|
131
123
|
include_in_schema=False,
|
|
132
124
|
status_code=200,
|
|
133
125
|
)
|
|
134
|
-
async def liveness_probe(request: Request) ->
|
|
126
|
+
async def liveness_probe(request: Request) -> dict[str, bool]:
|
|
135
127
|
"Endpoint meant to be used as liveness probe by deployment platforms"
|
|
136
128
|
return {"success": True}
|
|
137
129
|
|
|
@@ -139,7 +131,7 @@ async def liveness_probe(request: Request) -> Dict[str, bool]:
|
|
|
139
131
|
@router.api_route(
|
|
140
132
|
methods=["GET", "HEAD"], path="/api", tags=["Capabilities"], include_in_schema=False
|
|
141
133
|
)
|
|
142
|
-
async def eodag_openapi(request: Request) ->
|
|
134
|
+
async def eodag_openapi(request: Request) -> dict[str, Any]:
|
|
143
135
|
"""Customized openapi"""
|
|
144
136
|
logger.debug("URL: /api")
|
|
145
137
|
if app.openapi_schema:
|