eodag 3.4.3__tar.gz → 3.5.0__tar.gz
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-3.4.3 → eodag-3.5.0}/.github/workflows/deploy.yml +6 -0
- {eodag-3.4.3 → eodag-3.5.0}/CHANGES.rst +60 -0
- {eodag-3.4.3/eodag.egg-info → eodag-3.5.0}/PKG-INFO +3 -3
- {eodag-3.4.3 → eodag-3.5.0}/README.rst +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/Chart.yaml +2 -2
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/configure.rst +20 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/register.rst +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/docs/stac_rest.rst +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/core.py +75 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/metadata_mapping.py +31 -2
- {eodag-3.4.3 → eodag-3.5.0}/eodag/config.py +56 -10
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/keycloak.py +3 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/openid_connect.py +21 -3
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/token.py +14 -2
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/token_exchange.py +1 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/download/aws.py +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/manager.py +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/base.py +3 -2
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/build_search_result.py +10 -4
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/data_request_search.py +14 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/qssearch.py +8 -2
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/ext_product_types.json +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/providers.yml +4 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/core.py +3 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/errors.py +9 -4
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/server.py +3 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/stac.py +22 -1
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/__init__.py +3 -0
- eodag-3.5.0/eodag/utils/env.py +29 -0
- {eodag-3.4.3 → eodag-3.5.0/eodag.egg-info}/PKG-INFO +3 -3
- {eodag-3.4.3 → eodag-3.5.0}/eodag.egg-info/SOURCES.txt +1 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag.egg-info/requires.txt +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/pyproject.toml +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/setup.cfg +1 -1
- {eodag-3.4.3 → eodag-3.5.0}/.dockerignore +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.editorconfig +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.gitattributes +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/pull_request_template.md +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/workflows/changelog.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/workflows/fetch.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/workflows/github-pages.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/workflows/lint-pr-title.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/workflows/publish.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.github/workflows/test.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.gitignore +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/.pre-commit-config.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/BREAKING_CHANGES.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/CODE_OF_CONDUCT.md +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/CONTRIBUTING.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/LICENSE +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/MANIFEST.in +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/NOTICE +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/Chart.lock +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/README.md +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/NOTES.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/_helpers.tpl +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/configmap.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/deployment.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/extra-list.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/hpa.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/ingress.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/pv.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/pvc.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/secret.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/service.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/templates/serviceaccount.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/charts/eodag-server/values.yaml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docker/run-stac-server.sh +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docker/stac-browser.dockerfile +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docker/stac-server.dockerfile +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docker-compose.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/Makefile +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/custom.css +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/download_methods.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_advanced_calls_graph.svg +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_bycs.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_fetch_product_types.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_logo_160.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_logo_160r.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_main_calls_graph.svg +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_overview.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_stac_client.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/eodag_stac_server.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/favicon-32x32.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/params_mapping_extra.csv +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/params_mapping_offline_infos.json +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/params_mapping_opensearch.csv +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/product_types_information.csv +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/progress_1.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/progress_1_none.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/progress_2.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/progress_2_none.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/stac_browser_example.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/_static/stac_browser_example_600.png +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/add_product_type.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/add_provider.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/assets.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/call_graphs.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/core.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/eoproduct.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/exceptions.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/index.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/searchresult.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/types.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_reference/utils.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/api_user_guide.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/breaking_changes.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/changelog.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/cli_user_guide.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/conf.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/contribute.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/drivers.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/index.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/install.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/overview.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/product_storage_status.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/product_types.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/providers.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/getting_started_guide/side_projects.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/index.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/make.bat +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/1_overview.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/2_providers_products_available.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/3_configuration.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/4_search.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/5_queryables.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/6_serialize_deserialize.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/7_crunch.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/8_download.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/9_post_process.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/data/crunch_search_results.geojson +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/api_user_guide/data/download_search_results.geojson +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/intro_notebooks.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/auxdata/Gulf_of_Trieste_seamask_UTM33.cpg +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/auxdata/Gulf_of_Trieste_seamask_UTM33.dbf +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/auxdata/Gulf_of_Trieste_seamask_UTM33.prj +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/auxdata/Gulf_of_Trieste_seamask_UTM33.qix +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/auxdata/Gulf_of_Trieste_seamask_UTM33.qpj +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/auxdata/Gulf_of_Trieste_seamask_UTM33.shp +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/auxdata/Gulf_of_Trieste_seamask_UTM33.shx +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/auxdata/sentinel2_tiling_grid_centroids.zip +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_burnt_areas_snappy.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_cds.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_cop_dem.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_ecmwf.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_meteoblue.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_search_location_tile.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_ship_detection.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_stac_client.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/notebooks/tutos/tuto_wekeo.ipynb +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/params_mapping.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/plugins.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/plugins_reference/api.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/plugins_reference/auth.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/plugins_reference/crunch.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/plugins_reference/download.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/plugins_reference/search.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/stac.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/docs/tutos.rst +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/_assets.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/_product.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/drivers/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/drivers/base.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/drivers/generic.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/drivers/sentinel1.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/product/drivers/sentinel2.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/api/search_result.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/cli.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/crunch.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/apis/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/apis/base.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/apis/ecmwf.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/apis/usgs.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/aws_auth.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/base.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/generic.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/header.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/oauth.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/qsauth.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/authentication/sas_auth.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/base.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/crunch/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/crunch/base.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/crunch/filter_date.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/crunch/filter_latest_intersect.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/crunch/filter_latest_tpl_name.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/crunch/filter_overlap.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/crunch/filter_property.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/download/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/download/base.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/download/creodias_s3.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/download/http.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/download/s3rest.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/cop_marine.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/creodias_s3.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/csw.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/stac_list_assets.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/plugins/search/static_stac_search.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/py.typed +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/locations_conf_template.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/product_types.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/shp/ne_110m_admin_0_map_units.VERSION.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/shp/ne_110m_admin_0_map_units.cpg +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/shp/ne_110m_admin_0_map_units.dbf +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/shp/ne_110m_admin_0_map_units.prj +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/shp/ne_110m_admin_0_map_units.shp +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/shp/ne_110m_admin_0_map_units.shx +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/stac.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/stac_api.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/stac_provider.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/resources/user_conf_template.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/cache.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/config.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/constants.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/server.wsgi +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/templates/README +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/types/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/types/collections_search.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/types/eodag_search.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/types/queryables.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/types/stac_search.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/utils/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/utils/cql_evaluate.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/rest/utils/rfc3339.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/types/__init__.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/types/bbox.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/types/download_args.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/types/queryables.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/types/search_args.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/types/whoosh.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/exceptions.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/import_system.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/logging.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/notebook.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/repr.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/requests.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/rest.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/s3.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag/utils/stac_reader.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag.egg-info/dependency_links.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag.egg-info/entry_points.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/eodag.egg-info/top_level.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/get_pypi_latest_version.sh +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/pytest.ini +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/readthedocs.yml +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/requirements-dev.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/requirements-docs.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/requirements-tutorials.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/requirements.txt +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/setup.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/tox.ini +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/utils/params_mapping_to_csv.py +0 -0
- {eodag-3.4.3 → eodag-3.5.0}/utils/product_types_information_to_csv.py +0 -0
|
@@ -33,9 +33,12 @@ jobs:
|
|
|
33
33
|
source .venv/bin/activate
|
|
34
34
|
uv pip install python-semantic-release packaging
|
|
35
35
|
- name: Set Git config
|
|
36
|
+
env:
|
|
37
|
+
TOKEN: ${{ secrets.USER_TOKEN }}
|
|
36
38
|
run: |
|
|
37
39
|
git config user.name "github-actions[bot]"
|
|
38
40
|
git config user.email "'github-actions[bot]@users.noreply.github.com"
|
|
41
|
+
git remote set-url origin https://$TOKEN@github.com/${{ github.repository }}.git
|
|
39
42
|
- name: Git merge develop in master
|
|
40
43
|
run: |
|
|
41
44
|
git checkout master
|
|
@@ -62,9 +65,12 @@ jobs:
|
|
|
62
65
|
# Get history and tags for SCM versioning to work
|
|
63
66
|
fetch-depth: 0
|
|
64
67
|
- name: Set Git config
|
|
68
|
+
env:
|
|
69
|
+
TOKEN: ${{ secrets.USER_TOKEN }}
|
|
65
70
|
run: |
|
|
66
71
|
git config user.name "github-actions[bot]"
|
|
67
72
|
git config user.email "'github-actions[bot]@users.noreply.github.com"
|
|
73
|
+
git remote set-url origin https://$TOKEN@github.com/${{ github.repository }}.git
|
|
68
74
|
- name: Git merge master in develop
|
|
69
75
|
run: |
|
|
70
76
|
git checkout develop
|
|
@@ -3,6 +3,66 @@ Release history
|
|
|
3
3
|
===============
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
v3.5.0 (2025-06-20)
|
|
7
|
+
===================
|
|
8
|
+
|
|
9
|
+
Bug Fixes
|
|
10
|
+
---------
|
|
11
|
+
|
|
12
|
+
* **core**: Always validate PluginConfig before loading (`#1690`_, `59ac437`_)
|
|
13
|
+
|
|
14
|
+
* **core**: Skip provider empty conf on init (`#1687`_, `0a4104e`_)
|
|
15
|
+
|
|
16
|
+
* **plugins**: Raise errors when metadata discovery is not allowed (`#1534`_, `855ffa3`_)
|
|
17
|
+
|
|
18
|
+
Build System
|
|
19
|
+
------------
|
|
20
|
+
|
|
21
|
+
* Update usgs to 0.3.6 (`#1688`_, `e63cfb1`_)
|
|
22
|
+
|
|
23
|
+
Continuous Integration
|
|
24
|
+
----------------------
|
|
25
|
+
|
|
26
|
+
* Use personal access token for deploy github action (`#1693`_, `ff777d7`_)
|
|
27
|
+
|
|
28
|
+
Documentation
|
|
29
|
+
-------------
|
|
30
|
+
|
|
31
|
+
* Dead-links and out-of-date param fix (`#1692`_, `445a20e`_)
|
|
32
|
+
|
|
33
|
+
Features
|
|
34
|
+
--------
|
|
35
|
+
|
|
36
|
+
* **core**: Add env variable to whitelist providers (`#1672`_, `b93c4c8`_)
|
|
37
|
+
|
|
38
|
+
* **core**: Add strict product types mode (`#1677`_, `5077fa5`_)
|
|
39
|
+
|
|
40
|
+
* **plugins**: Auth token expiration margin (`#1665`_, `ef5fc18`_)
|
|
41
|
+
|
|
42
|
+
* **server**: Added bbox filter support for collections search (`#1671`_, `5717f0d`_)
|
|
43
|
+
|
|
44
|
+
.. _#1534: https://github.com/CS-SI/eodag/pull/1534
|
|
45
|
+
.. _#1665: https://github.com/CS-SI/eodag/pull/1665
|
|
46
|
+
.. _#1671: https://github.com/CS-SI/eodag/pull/1671
|
|
47
|
+
.. _#1672: https://github.com/CS-SI/eodag/pull/1672
|
|
48
|
+
.. _#1677: https://github.com/CS-SI/eodag/pull/1677
|
|
49
|
+
.. _#1687: https://github.com/CS-SI/eodag/pull/1687
|
|
50
|
+
.. _#1688: https://github.com/CS-SI/eodag/pull/1688
|
|
51
|
+
.. _#1690: https://github.com/CS-SI/eodag/pull/1690
|
|
52
|
+
.. _#1692: https://github.com/CS-SI/eodag/pull/1692
|
|
53
|
+
.. _#1693: https://github.com/CS-SI/eodag/pull/1693
|
|
54
|
+
.. _0a4104e: https://github.com/CS-SI/eodag/commit/0a4104e0518abc70e2133ca98472eea87d673a1c
|
|
55
|
+
.. _445a20e: https://github.com/CS-SI/eodag/commit/445a20e060730642e703615c73225c0df3cc84d0
|
|
56
|
+
.. _5077fa5: https://github.com/CS-SI/eodag/commit/5077fa591496811fb100c1e6b6a3e452cbdbe2a5
|
|
57
|
+
.. _5717f0d: https://github.com/CS-SI/eodag/commit/5717f0deddbf022f2c6d5207ade77de6afb0f9d5
|
|
58
|
+
.. _59ac437: https://github.com/CS-SI/eodag/commit/59ac437de01a8996d247b1f8239f332ed5dc5456
|
|
59
|
+
.. _855ffa3: https://github.com/CS-SI/eodag/commit/855ffa39fa9b914eb39cc20d6e5c2cbbc1b2097a
|
|
60
|
+
.. _b93c4c8: https://github.com/CS-SI/eodag/commit/b93c4c88f323af0eecb0950c90c6862ca9a7c3f4
|
|
61
|
+
.. _e63cfb1: https://github.com/CS-SI/eodag/commit/e63cfb19ca64a2ed65f500ae9678e117a2ea4cf8
|
|
62
|
+
.. _ef5fc18: https://github.com/CS-SI/eodag/commit/ef5fc188e515759c9227584b25805db75f537833
|
|
63
|
+
.. _ff777d7: https://github.com/CS-SI/eodag/commit/ff777d7a1e33f612c5227dba4fecfcec55ff18fc
|
|
64
|
+
|
|
65
|
+
|
|
6
66
|
v3.4.3 (2025-06-12)
|
|
7
67
|
===================
|
|
8
68
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eodag
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.0
|
|
4
4
|
Summary: Earth Observation Data Access Gateway
|
|
5
5
|
Home-page: https://github.com/CS-SI/eodag
|
|
6
6
|
Author: CS GROUP - France
|
|
@@ -64,7 +64,7 @@ Requires-Dist: OWSLib>=0.27.1; extra == "csw"
|
|
|
64
64
|
Provides-Extra: ecmwf
|
|
65
65
|
Requires-Dist: ecmwf-api-client; extra == "ecmwf"
|
|
66
66
|
Provides-Extra: usgs
|
|
67
|
-
Requires-Dist: usgs>=0.3.
|
|
67
|
+
Requires-Dist: usgs>=0.3.6; extra == "usgs"
|
|
68
68
|
Provides-Extra: server
|
|
69
69
|
Requires-Dist: fastapi>=0.93.0; extra == "server"
|
|
70
70
|
Requires-Dist: pygeofilter; extra == "server"
|
|
@@ -317,7 +317,7 @@ An eodag instance can be exposed through a STAC compliant REST api from the comm
|
|
|
317
317
|
|
|
318
318
|
.. code-block:: bash
|
|
319
319
|
|
|
320
|
-
docker run -p 5000:5000 --rm csspace/eodag-server:3.
|
|
320
|
+
docker run -p 5000:5000 --rm csspace/eodag-server:3.5.0
|
|
321
321
|
|
|
322
322
|
You can also browse over your STAC API server using `STAC Browser <https://github.com/radiantearth/stac-browser>`_.
|
|
323
323
|
Simply run:
|
|
@@ -187,7 +187,7 @@ An eodag instance can be exposed through a STAC compliant REST api from the comm
|
|
|
187
187
|
|
|
188
188
|
.. code-block:: bash
|
|
189
189
|
|
|
190
|
-
docker run -p 5000:5000 --rm csspace/eodag-server:3.
|
|
190
|
+
docker run -p 5000:5000 --rm csspace/eodag-server:3.5.0
|
|
191
191
|
|
|
192
192
|
You can also browse over your STAC API server using `STAC Browser <https://github.com/radiantearth/stac-browser>`_.
|
|
193
193
|
Simply run:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
apiVersion: v2
|
|
2
|
-
appVersion: 3.
|
|
2
|
+
appVersion: 3.5.0
|
|
3
3
|
dependencies:
|
|
4
4
|
- name: common
|
|
5
5
|
repository: oci://registry-1.docker.io/bitnamicharts
|
|
@@ -15,4 +15,4 @@ name: eodag-server
|
|
|
15
15
|
sources:
|
|
16
16
|
- https://github.com/CS-SI/eodag
|
|
17
17
|
type: application
|
|
18
|
-
version: 3.
|
|
18
|
+
version: 3.5.0
|
|
@@ -157,6 +157,26 @@ Some EODAG core settings can be overriden using environment variables:
|
|
|
157
157
|
<https://eodag.readthedocs.io/en/stable/notebooks/api_user_guide/2_providers_products_available.html#Product-types-discovery>`_
|
|
158
158
|
in place of https://cs-si.github.io/eodag/eodag/resources/ext_product_types.json.
|
|
159
159
|
If the file is not readable, only user-modified providers will be fetched.
|
|
160
|
+
* ``EODAG_PROVIDERS_WHITELIST`` to restrict EODAG to only use a specific list of providers.
|
|
161
|
+
|
|
162
|
+
If this environment variable is set (as a comma-separated list of provider names), EODAG will only load and use the specified providers.
|
|
163
|
+
All other providers will be ignored, regardless of their presence in configuration files.
|
|
164
|
+
|
|
165
|
+
This is useful for restricting EODAG to a subset of providers, for example in controlled or production environments.
|
|
166
|
+
* ``EODAG_STRICT_PRODUCT_TYPES`` to control how product types are listed.
|
|
167
|
+
|
|
168
|
+
If this environment variable is set to a truthy value (such as ``1``, ``true``, ``yes``, or ``on``), EODAG will only list product types that are present in the main product types configuration file.
|
|
169
|
+
Product types defined only in provider configurations (but not in the main product types configuration) will be ignored.
|
|
170
|
+
If not set, EODAG will also include product types defined only in provider configurations, with minimal metadata.
|
|
171
|
+
|
|
172
|
+
This is useful if you want to strictly control which product types are available, for example to ensure consistency across environments.
|
|
173
|
+
|
|
174
|
+
Example usage:
|
|
175
|
+
|
|
176
|
+
.. code-block:: bash
|
|
177
|
+
|
|
178
|
+
export EODAG_PROVIDERS_WHITELIST=peps,creodias,theia
|
|
179
|
+
export EODAG_STRICT_PRODUCT_TYPES=true
|
|
160
180
|
|
|
161
181
|
CLI configuration
|
|
162
182
|
^^^^^^^^^^^^^^^^^
|
|
@@ -150,7 +150,7 @@ No authentication needed.
|
|
|
150
150
|
|
|
151
151
|
``ecmwf``
|
|
152
152
|
^^^^^^^^^
|
|
153
|
-
Create an account `here <https://
|
|
153
|
+
Create an account `here <https://www.ecmwf.int/user/login>`__.
|
|
154
154
|
|
|
155
155
|
Then use *email* as ``username`` and *key* as ``password`` from `here <https://api.ecmwf.int/v1/key/>`__ in eodag credentials.
|
|
156
156
|
EODAG can be used to request for public datasets as for operational archive. Please note that for public datasets you
|
|
@@ -115,7 +115,7 @@ available on `https://hub.docker.com/r/csspace/eodag-server <https://hub.docker.
|
|
|
115
115
|
|
|
116
116
|
.. code-block:: bash
|
|
117
117
|
|
|
118
|
-
$ docker run -p 5000:5000 --rm csspace/eodag-server:3.
|
|
118
|
+
$ docker run -p 5000:5000 --rm csspace/eodag-server:3.5.0
|
|
119
119
|
|
|
120
120
|
Example
|
|
121
121
|
-------
|
|
@@ -36,6 +36,7 @@ from whoosh.index import exists_in, open_dir
|
|
|
36
36
|
from whoosh.qparser import QueryParser
|
|
37
37
|
|
|
38
38
|
from eodag.api.product.metadata_mapping import (
|
|
39
|
+
NOT_AVAILABLE,
|
|
39
40
|
ONLINE_STATUS,
|
|
40
41
|
mtd_cfg_as_conversion_and_querypath,
|
|
41
42
|
)
|
|
@@ -79,6 +80,7 @@ from eodag.utils import (
|
|
|
79
80
|
string_to_jsonpath,
|
|
80
81
|
uri_to_path,
|
|
81
82
|
)
|
|
83
|
+
from eodag.utils.env import is_env_var_true
|
|
82
84
|
from eodag.utils.exceptions import (
|
|
83
85
|
AuthenticationError,
|
|
84
86
|
EodagError,
|
|
@@ -175,12 +177,19 @@ class EODataAccessGateway:
|
|
|
175
177
|
share_credentials(self.providers_config)
|
|
176
178
|
|
|
177
179
|
# init updated providers conf
|
|
180
|
+
strict_mode = is_env_var_true("EODAG_STRICT_PRODUCT_TYPES")
|
|
181
|
+
available_product_types = set(self.product_types_config.source.keys())
|
|
182
|
+
|
|
178
183
|
for provider in self.providers_config.keys():
|
|
179
184
|
provider_config_init(
|
|
180
185
|
self.providers_config[provider],
|
|
181
186
|
load_stac_provider_config(),
|
|
182
187
|
)
|
|
183
188
|
|
|
189
|
+
self._sync_provider_product_types(
|
|
190
|
+
provider, available_product_types, strict_mode
|
|
191
|
+
)
|
|
192
|
+
|
|
184
193
|
# re-build _plugins_manager using up-to-date providers_config
|
|
185
194
|
self._plugins_manager.rebuild(self.providers_config)
|
|
186
195
|
|
|
@@ -226,6 +235,61 @@ class EODataAccessGateway:
|
|
|
226
235
|
)
|
|
227
236
|
self.set_locations_conf(locations_conf_path)
|
|
228
237
|
|
|
238
|
+
def _sync_provider_product_types(
|
|
239
|
+
self,
|
|
240
|
+
provider: str,
|
|
241
|
+
available_product_types: set[str],
|
|
242
|
+
strict_mode: bool,
|
|
243
|
+
) -> None:
|
|
244
|
+
"""
|
|
245
|
+
Synchronize product types for a provider based on strict or permissive mode.
|
|
246
|
+
|
|
247
|
+
In strict mode, removes product types not in available_product_types.
|
|
248
|
+
In permissive mode, adds empty product type configs for missing types.
|
|
249
|
+
|
|
250
|
+
:param provider: The provider name whose product types should be synchronized.
|
|
251
|
+
:param available_product_types: The set of available product type IDs.
|
|
252
|
+
:param strict_mode: If True, remove unknown product types; if False, add empty configs for them.
|
|
253
|
+
:returns: None
|
|
254
|
+
"""
|
|
255
|
+
provider_products = self.providers_config[provider].products
|
|
256
|
+
products_to_remove: list[str] = []
|
|
257
|
+
products_to_add: list[str] = []
|
|
258
|
+
|
|
259
|
+
for product_id in provider_products:
|
|
260
|
+
if product_id == GENERIC_PRODUCT_TYPE:
|
|
261
|
+
continue
|
|
262
|
+
|
|
263
|
+
if product_id not in available_product_types:
|
|
264
|
+
if strict_mode:
|
|
265
|
+
products_to_remove.append(product_id)
|
|
266
|
+
continue
|
|
267
|
+
|
|
268
|
+
empty_product = {
|
|
269
|
+
"title": product_id,
|
|
270
|
+
"abstract": NOT_AVAILABLE,
|
|
271
|
+
}
|
|
272
|
+
self.product_types_config.source[
|
|
273
|
+
product_id
|
|
274
|
+
] = empty_product # will update available_product_types
|
|
275
|
+
products_to_add.append(product_id)
|
|
276
|
+
|
|
277
|
+
if products_to_add:
|
|
278
|
+
logger.debug(
|
|
279
|
+
"Product types permissive mode, %s added (provider %s)",
|
|
280
|
+
", ".join(products_to_add),
|
|
281
|
+
provider,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
if products_to_remove:
|
|
285
|
+
logger.debug(
|
|
286
|
+
"Product types strict mode, ignoring %s (provider %s)",
|
|
287
|
+
", ".join(products_to_remove),
|
|
288
|
+
provider,
|
|
289
|
+
)
|
|
290
|
+
for id in products_to_remove:
|
|
291
|
+
del self.providers_config[provider].products[id]
|
|
292
|
+
|
|
229
293
|
def get_version(self) -> str:
|
|
230
294
|
"""Get eodag package version"""
|
|
231
295
|
return version("eodag")
|
|
@@ -608,11 +672,14 @@ class EODataAccessGateway:
|
|
|
608
672
|
for product_type_id in p.products: # type: ignore
|
|
609
673
|
if product_type_id == GENERIC_PRODUCT_TYPE:
|
|
610
674
|
continue
|
|
675
|
+
|
|
611
676
|
config = self.product_types_config[product_type_id]
|
|
612
677
|
config["_id"] = product_type_id
|
|
678
|
+
|
|
613
679
|
if "alias" in config:
|
|
614
680
|
product_type_id = config["alias"]
|
|
615
681
|
product_type = {"ID": product_type_id, **config}
|
|
682
|
+
|
|
616
683
|
if product_type not in product_types:
|
|
617
684
|
product_types.append(product_type)
|
|
618
685
|
|
|
@@ -620,11 +687,18 @@ class EODataAccessGateway:
|
|
|
620
687
|
return sorted(product_types, key=itemgetter("ID"))
|
|
621
688
|
|
|
622
689
|
def fetch_product_types_list(self, provider: Optional[str] = None) -> None:
|
|
623
|
-
"""Fetch product types list and update if needed
|
|
690
|
+
"""Fetch product types list and update if needed.
|
|
691
|
+
|
|
692
|
+
If strict mode is enabled (by setting the ``EODAG_STRICT_PRODUCT_TYPES`` environment variable
|
|
693
|
+
to a truthy value), this method will not fetch or update product types and will return immediately.
|
|
624
694
|
|
|
625
695
|
:param provider: The name of a provider or provider-group for which product types
|
|
626
696
|
list should be updated. Defaults to all providers (None value).
|
|
627
697
|
"""
|
|
698
|
+
strict_mode = is_env_var_true("EODAG_STRICT_PRODUCT_TYPES")
|
|
699
|
+
if strict_mode:
|
|
700
|
+
return
|
|
701
|
+
|
|
628
702
|
providers_to_fetch = list(self.providers_config.keys())
|
|
629
703
|
# check if some providers are grouped under a group name which is not a provider name
|
|
630
704
|
if provider is not None and provider not in self.providers_config:
|
|
@@ -54,6 +54,7 @@ from eodag.utils import (
|
|
|
54
54
|
string_to_jsonpath,
|
|
55
55
|
update_nested_dict,
|
|
56
56
|
)
|
|
57
|
+
from eodag.utils.exceptions import ValidationError
|
|
57
58
|
|
|
58
59
|
if TYPE_CHECKING:
|
|
59
60
|
from shapely.geometry.base import BaseGeometry
|
|
@@ -1286,7 +1287,10 @@ def mtd_cfg_as_conversion_and_querypath(
|
|
|
1286
1287
|
|
|
1287
1288
|
|
|
1288
1289
|
def format_query_params(
|
|
1289
|
-
product_type: str,
|
|
1290
|
+
product_type: str,
|
|
1291
|
+
config: PluginConfig,
|
|
1292
|
+
query_dict: dict[str, Any],
|
|
1293
|
+
error_context: str = "",
|
|
1290
1294
|
) -> dict[str, Any]:
|
|
1291
1295
|
"""format the search parameters to query parameters"""
|
|
1292
1296
|
if "raise_errors" in query_dict.keys():
|
|
@@ -1299,10 +1303,26 @@ def format_query_params(
|
|
|
1299
1303
|
**config.products.get(product_type, {}).get("metadata_mapping", {}),
|
|
1300
1304
|
)
|
|
1301
1305
|
|
|
1306
|
+
# Raise error if non-queryables parameters are used and raise_mtd_discovery_error configured
|
|
1307
|
+
if (
|
|
1308
|
+
raise_mtd_discovery_error := config.products.get(product_type, {})
|
|
1309
|
+
.get("discover_metadata", {})
|
|
1310
|
+
.get("raise_mtd_discovery_error")
|
|
1311
|
+
) is None:
|
|
1312
|
+
raise_mtd_discovery_error = getattr(config, "discover_metadata", {}).get(
|
|
1313
|
+
"raise_mtd_discovery_error", False
|
|
1314
|
+
)
|
|
1315
|
+
|
|
1302
1316
|
query_params: dict[str, Any] = {}
|
|
1303
1317
|
# Get all the search parameters that are recognised as queryables by the
|
|
1304
1318
|
# provider (they appear in the queryables dictionary)
|
|
1305
|
-
queryables = _get_queryables(
|
|
1319
|
+
queryables = _get_queryables(
|
|
1320
|
+
query_dict,
|
|
1321
|
+
config,
|
|
1322
|
+
product_type_metadata_mapping,
|
|
1323
|
+
raise_mtd_discovery_error,
|
|
1324
|
+
error_context,
|
|
1325
|
+
)
|
|
1306
1326
|
|
|
1307
1327
|
for eodag_search_key, provider_search_key in queryables.items():
|
|
1308
1328
|
user_input = query_dict[eodag_search_key]
|
|
@@ -1438,6 +1458,8 @@ def _get_queryables(
|
|
|
1438
1458
|
search_params: dict[str, Any],
|
|
1439
1459
|
config: PluginConfig,
|
|
1440
1460
|
metadata_mapping: dict[str, Any],
|
|
1461
|
+
raise_mtd_discovery_error: bool,
|
|
1462
|
+
error_context: str,
|
|
1441
1463
|
) -> dict[str, Any]:
|
|
1442
1464
|
"""Retrieve the metadata mappings that are query-able"""
|
|
1443
1465
|
logger.debug("Retrieving queryable metadata from metadata_mapping")
|
|
@@ -1445,6 +1467,13 @@ def _get_queryables(
|
|
|
1445
1467
|
for eodag_search_key, user_input in search_params.items():
|
|
1446
1468
|
if user_input is not None:
|
|
1447
1469
|
md_mapping = metadata_mapping.get(eodag_search_key, (None, NOT_MAPPED))
|
|
1470
|
+
# raise an error when a query param not allowed by the provider is found
|
|
1471
|
+
if not isinstance(md_mapping, list) and raise_mtd_discovery_error:
|
|
1472
|
+
raise ValidationError(
|
|
1473
|
+
"Search parameters which are not queryable are disallowed for this product type on this provider: "
|
|
1474
|
+
f"please remove '{eodag_search_key}' from your search parameters. {error_context}",
|
|
1475
|
+
{eodag_search_key},
|
|
1476
|
+
)
|
|
1448
1477
|
_, md_value = md_mapping
|
|
1449
1478
|
# query param from defined metadata_mapping
|
|
1450
1479
|
if md_mapping is not None and isinstance(md_mapping, list):
|
|
@@ -194,12 +194,24 @@ class ProviderConfig(yaml.YAMLObject):
|
|
|
194
194
|
},
|
|
195
195
|
)
|
|
196
196
|
for key in PLUGINS_TOPICS_KEYS:
|
|
197
|
-
current_value: Optional[
|
|
197
|
+
current_value: Optional[PluginConfig] = getattr(self, key, None)
|
|
198
198
|
mapping_value = mapping.get(key, {})
|
|
199
199
|
if current_value is not None:
|
|
200
200
|
current_value.update(mapping_value)
|
|
201
201
|
elif mapping_value:
|
|
202
|
-
|
|
202
|
+
try:
|
|
203
|
+
setattr(self, key, PluginConfig.from_mapping(mapping_value))
|
|
204
|
+
except ValidationError as e:
|
|
205
|
+
logger.warning(
|
|
206
|
+
(
|
|
207
|
+
"Could not add %s Plugin config to %s configuration: %s. "
|
|
208
|
+
"Try updating existing %s Plugin configs instead."
|
|
209
|
+
),
|
|
210
|
+
key,
|
|
211
|
+
self.name,
|
|
212
|
+
str(e),
|
|
213
|
+
", ".join([k for k in PLUGINS_TOPICS_KEYS if hasattr(self, k)]),
|
|
214
|
+
)
|
|
203
215
|
|
|
204
216
|
|
|
205
217
|
class PluginConfig(yaml.YAMLObject):
|
|
@@ -256,9 +268,11 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
256
268
|
#: Metadata regex pattern used for discovery in search result properties
|
|
257
269
|
metadata_pattern: str
|
|
258
270
|
#: Configuration/template that will be used to query for a discovered parameter
|
|
259
|
-
search_param: str
|
|
271
|
+
search_param: str | dict[str, Any]
|
|
260
272
|
#: Path to the metadata in search result
|
|
261
273
|
metadata_path: str
|
|
274
|
+
#: Whether an error must be raised when using a search parameter which is not queryable or not
|
|
275
|
+
raise_mtd_discovery_error: bool
|
|
262
276
|
|
|
263
277
|
class DiscoverProductTypes(TypedDict, total=False):
|
|
264
278
|
"""Configuration for product types discovery"""
|
|
@@ -628,6 +642,10 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
628
642
|
#: :class:`~eodag.plugins.authentication.token_exchange.OIDCTokenExchangeAuth`
|
|
629
643
|
#: Identifies the issuer of the `subject_token`
|
|
630
644
|
subject_issuer: str
|
|
645
|
+
#: :class:`~eodag.plugins.authentication.token.TokenAuth`
|
|
646
|
+
#: :class:`~eodag.plugins.authentication.openid_connect.OIDCRefreshTokenBase`
|
|
647
|
+
#: Safety buffer to prevent token rejection from unexpected expiry between validity check and request.
|
|
648
|
+
token_expiration_margin: int
|
|
631
649
|
#: :class:`~eodag.plugins.authentication.token_exchange.OIDCTokenExchangeAuth`
|
|
632
650
|
#: Audience that the token ID is intended for. :attr:`~eodag.config.PluginConfig.client_id` of the Relying Party
|
|
633
651
|
audience: str
|
|
@@ -648,6 +666,7 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
648
666
|
@classmethod
|
|
649
667
|
def from_mapping(cls, mapping: dict[str, Any]) -> PluginConfig:
|
|
650
668
|
"""Build a :class:`~eodag.config.PluginConfig` from a mapping"""
|
|
669
|
+
cls.validate(tuple(mapping.keys()))
|
|
651
670
|
c = cls()
|
|
652
671
|
c.__dict__.update(mapping)
|
|
653
672
|
return c
|
|
@@ -657,7 +676,7 @@ class PluginConfig(yaml.YAMLObject):
|
|
|
657
676
|
"""Validate a :class:`~eodag.config.PluginConfig`"""
|
|
658
677
|
if "type" not in config_keys:
|
|
659
678
|
raise ValidationError(
|
|
660
|
-
"A Plugin config must specify the Plugin it configures"
|
|
679
|
+
"A Plugin config must specify the type of Plugin it configures"
|
|
661
680
|
)
|
|
662
681
|
|
|
663
682
|
def update(self, mapping: Optional[dict[Any, Any]]) -> None:
|
|
@@ -689,6 +708,8 @@ def load_default_config() -> dict[str, ProviderConfig]:
|
|
|
689
708
|
def load_config(config_path: str) -> dict[str, ProviderConfig]:
|
|
690
709
|
"""Load the providers configuration into a dictionary from a given file
|
|
691
710
|
|
|
711
|
+
If EODAG_PROVIDERS_WHITELIST is set, only load listed providers.
|
|
712
|
+
|
|
692
713
|
:param config_path: The path to the provider config file
|
|
693
714
|
:returns: The default provider's configuration
|
|
694
715
|
"""
|
|
@@ -701,10 +722,23 @@ def load_config(config_path: str) -> dict[str, ProviderConfig]:
|
|
|
701
722
|
except yaml.parser.ParserError as e:
|
|
702
723
|
logger.error("Unable to load configuration")
|
|
703
724
|
raise e
|
|
725
|
+
|
|
704
726
|
stac_provider_config = load_stac_provider_config()
|
|
727
|
+
|
|
728
|
+
whitelist_env = os.getenv("EODAG_PROVIDERS_WHITELIST")
|
|
729
|
+
whitelist = None
|
|
730
|
+
if whitelist_env:
|
|
731
|
+
whitelist = {provider for provider in whitelist_env.split(",")}
|
|
732
|
+
logger.info("Using providers whitelist: %s", ", ".join(whitelist))
|
|
733
|
+
|
|
705
734
|
for provider_config in providers_configs:
|
|
735
|
+
if provider_config is None or (
|
|
736
|
+
whitelist and provider_config.name not in whitelist
|
|
737
|
+
):
|
|
738
|
+
continue
|
|
706
739
|
provider_config_init(provider_config, stac_provider_config)
|
|
707
740
|
config[provider_config.name] = provider_config
|
|
741
|
+
|
|
708
742
|
return config
|
|
709
743
|
|
|
710
744
|
|
|
@@ -803,7 +837,9 @@ def provider_config_init(
|
|
|
803
837
|
pass
|
|
804
838
|
|
|
805
839
|
|
|
806
|
-
def override_config_from_file(
|
|
840
|
+
def override_config_from_file(
|
|
841
|
+
config: dict[str, ProviderConfig], file_path: str
|
|
842
|
+
) -> None:
|
|
807
843
|
"""Override a configuration with the values in a file
|
|
808
844
|
|
|
809
845
|
:param config: An eodag providers configuration dictionary
|
|
@@ -818,10 +854,11 @@ def override_config_from_file(config: dict[str, Any], file_path: str) -> None:
|
|
|
818
854
|
except yaml.parser.ParserError as e:
|
|
819
855
|
logger.error("Unable to load user configuration file")
|
|
820
856
|
raise e
|
|
857
|
+
|
|
821
858
|
override_config_from_mapping(config, config_in_file)
|
|
822
859
|
|
|
823
860
|
|
|
824
|
-
def override_config_from_env(config: dict[str,
|
|
861
|
+
def override_config_from_env(config: dict[str, ProviderConfig]) -> None:
|
|
825
862
|
"""Override a configuration with environment variables values
|
|
826
863
|
|
|
827
864
|
:param config: An eodag providers configuration dictionary
|
|
@@ -892,16 +929,25 @@ def override_config_from_env(config: dict[str, Any]) -> None:
|
|
|
892
929
|
|
|
893
930
|
|
|
894
931
|
def override_config_from_mapping(
|
|
895
|
-
config: dict[str,
|
|
932
|
+
config: dict[str, ProviderConfig], mapping: dict[str, Any]
|
|
896
933
|
) -> None:
|
|
897
|
-
"""Override a configuration with the values in a mapping
|
|
934
|
+
"""Override a configuration with the values in a mapping.
|
|
935
|
+
|
|
936
|
+
If the environment variable ``EODAG_PROVIDERS_WHITELIST`` is set (as a comma-separated list of provider names),
|
|
937
|
+
only the listed providers will be used from the mapping. All other providers in the mapping will be ignored.
|
|
898
938
|
|
|
899
939
|
:param config: An eodag providers configuration dictionary
|
|
900
940
|
:param mapping: The mapping containing the values to be overriden
|
|
901
941
|
"""
|
|
942
|
+
whitelist_env = os.getenv("EODAG_PROVIDERS_WHITELIST")
|
|
943
|
+
whitelist = None
|
|
944
|
+
if whitelist_env:
|
|
945
|
+
whitelist = {provider for provider in whitelist_env.split(",")}
|
|
946
|
+
|
|
902
947
|
for provider, new_conf in mapping.items():
|
|
903
948
|
# check if metada-mapping as already been built as jsonpath in providers_config
|
|
904
|
-
|
|
949
|
+
# or provider not in whitelist
|
|
950
|
+
if not isinstance(new_conf, dict) or (whitelist and provider not in whitelist):
|
|
905
951
|
continue
|
|
906
952
|
new_conf_search = new_conf.get("search", {}) or {}
|
|
907
953
|
new_conf_api = new_conf.get("api", {}) or {}
|
|
@@ -930,7 +976,7 @@ def override_config_from_mapping(
|
|
|
930
976
|
)
|
|
931
977
|
|
|
932
978
|
# try overriding conf
|
|
933
|
-
old_conf: Optional[
|
|
979
|
+
old_conf: Optional[ProviderConfig] = config.get(provider)
|
|
934
980
|
if old_conf is not None:
|
|
935
981
|
old_conf.update(new_conf)
|
|
936
982
|
else:
|
|
@@ -60,8 +60,10 @@ class KeycloakOIDCPasswordAuth(OIDCRefreshTokenBase):
|
|
|
60
60
|
The allowed audiences that have to be present in the user token.
|
|
61
61
|
* :attr:`~eodag.config.PluginConfig.auth_error_code` (``int``): which error code is
|
|
62
62
|
returned in case of an authentication error
|
|
63
|
-
* :attr:`~eodag.config.PluginConfig.ssl_verify` (``bool``):
|
|
63
|
+
* :attr:`~eodag.config.PluginConfig.ssl_verify` (``bool``): If the SSL certificates
|
|
64
64
|
should be verified in the token request; default: ``True``
|
|
65
|
+
* :attr:`~eodag.config.PluginConfig.token_expiration_margin` (``int``): The margin of time (in seconds)
|
|
66
|
+
before a token is considered expired. Default: 60 seconds
|
|
65
67
|
|
|
66
68
|
Using :class:`~eodag.plugins.download.http.HTTPDownload` a download link
|
|
67
69
|
``http://example.com?foo=bar`` will become
|
|
@@ -30,7 +30,14 @@ from lxml import etree
|
|
|
30
30
|
from requests.auth import AuthBase
|
|
31
31
|
|
|
32
32
|
from eodag.plugins.authentication import Authentication
|
|
33
|
-
from eodag.utils import
|
|
33
|
+
from eodag.utils import (
|
|
34
|
+
DEFAULT_TOKEN_EXPIRATION_MARGIN,
|
|
35
|
+
HTTP_REQ_TIMEOUT,
|
|
36
|
+
USER_AGENT,
|
|
37
|
+
parse_qs,
|
|
38
|
+
repeatfunc,
|
|
39
|
+
urlparse,
|
|
40
|
+
)
|
|
34
41
|
from eodag.utils.exceptions import (
|
|
35
42
|
AuthenticationError,
|
|
36
43
|
MisconfiguredError,
|
|
@@ -117,13 +124,22 @@ class OIDCRefreshTokenBase(Authentication):
|
|
|
117
124
|
|
|
118
125
|
def _get_access_token(self) -> str:
|
|
119
126
|
now = datetime.now(timezone.utc)
|
|
120
|
-
|
|
127
|
+
expiration_margin = timedelta(
|
|
128
|
+
seconds=getattr(
|
|
129
|
+
self.config, "token_expiration_margin", DEFAULT_TOKEN_EXPIRATION_MARGIN
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
if self.access_token and self.access_token_expiration - now > expiration_margin:
|
|
121
134
|
logger.debug(
|
|
122
135
|
f"Existing access_token is still valid until {self.access_token_expiration.isoformat()}."
|
|
123
136
|
)
|
|
124
137
|
return self.access_token
|
|
125
138
|
|
|
126
|
-
elif
|
|
139
|
+
elif (
|
|
140
|
+
self.refresh_token
|
|
141
|
+
and self.refresh_token_expiration - now > expiration_margin
|
|
142
|
+
):
|
|
127
143
|
response = self._get_token_with_refresh_token()
|
|
128
144
|
logger.debug(
|
|
129
145
|
"access_token expired, fetching new access_token using refresh_token"
|
|
@@ -268,6 +284,8 @@ class OIDCAuthorizationCodeFlowAuth(OIDCRefreshTokenBase):
|
|
|
268
284
|
Refers to the name of the query param to be used in the query request
|
|
269
285
|
* :attr:`~eodag.config.PluginConfig.refresh_token_key` (``str``): The key pointing to
|
|
270
286
|
the refresh_token in the json response to the POST request to the token server
|
|
287
|
+
* :attr:`~eodag.config.PluginConfig.token_expiration_margin` (``int``): The margin of time (in seconds)
|
|
288
|
+
before a token is considered expired. Default: 60 seconds.
|
|
271
289
|
|
|
272
290
|
"""
|
|
273
291
|
|
|
@@ -31,6 +31,7 @@ from urllib3 import Retry
|
|
|
31
31
|
|
|
32
32
|
from eodag.plugins.authentication.base import Authentication
|
|
33
33
|
from eodag.utils import (
|
|
34
|
+
DEFAULT_TOKEN_EXPIRATION_MARGIN,
|
|
34
35
|
HTTP_REQ_TIMEOUT,
|
|
35
36
|
REQ_RETRY_BACKOFF_FACTOR,
|
|
36
37
|
REQ_RETRY_STATUS_FORCELIST,
|
|
@@ -90,6 +91,8 @@ class TokenAuth(Authentication):
|
|
|
90
91
|
* :attr:`~eodag.config.PluginConfig.retry_status_forcelist` (``list[int]``): :class:`urllib3.util.Retry`
|
|
91
92
|
``status_forcelist`` parameter, list of integer HTTP status codes that we should force a retry on; default:
|
|
92
93
|
``[401, 429, 500, 502, 503, 504]``
|
|
94
|
+
* :attr:`~eodag.config.PluginConfig.token_expiration_margin` (``int``): The margin of time (in seconds) before
|
|
95
|
+
a token is considered expired. Default: 60 seconds.
|
|
93
96
|
"""
|
|
94
97
|
|
|
95
98
|
def __init__(self, provider: str, config: PluginConfig) -> None:
|
|
@@ -152,9 +155,18 @@ class TokenAuth(Authentication):
|
|
|
152
155
|
|
|
153
156
|
# Use a thread lock to avoid several threads requesting the token at the same time
|
|
154
157
|
with self.auth_lock:
|
|
155
|
-
|
|
158
|
+
expiration_margin = timedelta(
|
|
159
|
+
seconds=getattr(
|
|
160
|
+
self.config,
|
|
161
|
+
"token_expiration_margin",
|
|
162
|
+
DEFAULT_TOKEN_EXPIRATION_MARGIN,
|
|
163
|
+
)
|
|
164
|
+
)
|
|
156
165
|
self.validate_config_credentials()
|
|
157
|
-
if
|
|
166
|
+
if (
|
|
167
|
+
self.token
|
|
168
|
+
and self.token_expiration - datetime.now() > expiration_margin
|
|
169
|
+
):
|
|
158
170
|
logger.debug("using existing access token")
|
|
159
171
|
return RequestsTokenAuth(
|
|
160
172
|
self.token, "header", headers=getattr(self.config, "headers", {})
|