Skip to content

fix(search): allow any value for keywords not required by form#2148

Open
dalpasso wants to merge 2 commits intodevelopfrom
fix-request-validation-of-CMIP6_CLIMATE_PROJECTIONS
Open

fix(search): allow any value for keywords not required by form#2148
dalpasso wants to merge 2 commits intodevelopfrom
fix-request-validation-of-CMIP6_CLIMATE_PROJECTIONS

Conversation

@dalpasso
Copy link
Copy Markdown
Collaborator

@dalpasso dalpasso commented Apr 14, 2026

This PR is fixing how the available values are calculated from the constraints file.

If no constraint is matching a given parameter, then look at the form file:

  • if the keyword is required by the form file then raise an exception, cause no constrain is matching the given parameters:
  • if the keyword is not required by form, then any value is accepted for it.

In the latter case, there may be no constraint at all containing that keyword because any value is anyway accepted.

import os
from eodag import EODataAccessGateway
from eodag.utils.logging import setup_logging

setup_logging(3)
dag = EODataAccessGateway()

# must fail because not constraint is matching the given params and all keywords are required by form
params = {
    "provider": "cop_cds",
    "collection": "CMIP6_CLIMATE_PROJECTIONS",
    "experiment": "ssp2_4_5",
    "level": ["1"], # level not allowed
    "model": "access_cm2",
    "month": ["01"],
    "temporal_resolution": "monthly",
    "variable": "near_surface_air_temperature",
    "year": ["2023"],
}
dag.search(**params)

# must succeed
params = {
    "provider": "cop_cds",
    "collection": "CMIP6_CLIMATE_PROJECTIONS",
    "experiment": "ssp2_4_5",
    "model": "access_cm2",
    "month": ["01"],
    "temporal_resolution": "monthly",
    "variable": "near_surface_air_temperature",
    "year": ["2023"],
}
dag.search(**params)

# must succeed: `pressure_level` and `model_level` are not required by form: any value is accepted
# note: the constraint file doesn't contain any constraint matching *all* these parameters,
# but this is fine cause any value is accepted
params = {
    "provider": "cop_ads",
    "collection": "CAMS_GAC_FORECAST",
    "variable": ["ammonium_aerosol_mass_mixing_ratio"],
    "pressure_level": ["1"],
    "model_level": ["1"],
    "date": "2025-12-11/2025-12-11",
    "time": ["00:00"],
    "leadtime_hour": ["0"],
    "type": ["forecast"],
    "data_format": "grib",
    "area": [42, 10, 40, 12],
}
dag.search(**params)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 14, 2026

Test Results

    4 files  ±0      4 suites  ±0   4m 46s ⏱️ +6s
  786 tests ±0    786 ✅ ±0  0 💤 ±0  0 ❌ ±0 
3 186 runs  ±0  3 184 ✅ ±0  2 💤 ±0  0 ❌ ±0 

Results for commit b243936. ± Comparison against base commit 33ad4a7.

♻️ This comment has been updated with latest results.

@eodag-bot
Copy link
Copy Markdown
Collaborator

eodag-bot commented Apr 14, 2026

badge

Code Coverage (Ubuntu)

Details
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         252      11  95.63%   105-116, 378, 645
config.py                                      306      24  92.16%   70-72, 75, 78, 81, 85, 89, 93-95, 587-589, 711-713, 732, 740, 770-775, 777
crunch.py                                        2       0  100.00%
api/__init__.py                                  0       0  100.00%
api/collection.py                              151       8  94.70%   177, 213, 216, 323, 362, 365, 383, 386
api/core.py                                    774      57  92.64%   263, 549, 597, 640, 680, 700, 741-746, 771, 855-874, 888, 894, 1047, 1052, 1151, 1190-1191, 1287-1288, 1314, 1345-1346, 1372, 1385, 1446-1447, 1478-1479, 1553-1558, 1570-1573, 1685, 1910, 2067, 2178, 2266-2267
api/provider.py                                382      40  89.53%   186, 190-191, 316-337, 405, 521, 525-526, 531-534, 545, 621-631, 821-822, 870, 877, 891, 914-917, 951-958, 962-963
api/search_result.py                           138      12  91.30%   111, 123, 133, 154, 208, 266, 278, 413, 468-471
api/product/__init__.py                          7       0  100.00%
api/product/_assets.py                          56       4  92.86%   101, 195, 206-210
api/product/_product.py                        311      24  92.28%   200, 356, 382-385, 422, 441-442, 551, 580, 587, 626, 738, 781-784, 793-796, 850, 916, 928, 995
api/product/metadata_mapping.py                867      62  92.85%   125-127, 222-227, 251, 310-311, 349-350, 391, 412, 475-476, 513, 534-537, 560, 572-573, 614, 637, 662-665, 667-672, 737-742, 751, 757, 773, 781, 1012, 1165, 1187, 1196-1200, 1217-1222, 1355, 1378, 1387, 1409, 1414, 1466, 1538, 1559, 1585, 1599, 1624, 1670, 1739, 1814, 1848, 1879
api/product/drivers/__init__.py                 11       0  100.00%
api/product/drivers/base.py                     32       0  100.00%
api/product/drivers/generic.py                  11       0  100.00%
api/product/drivers/sentinel1.py                33       0  100.00%
api/product/drivers/sentinel2.py                33       0  100.00%
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 25       2  92.00%   48, 55
plugins/manager.py                             173      16  90.75%   102-107, 179, 201, 219-220, 232, 271-272, 372-375, 387-388
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           95       8  91.58%   163-165, 213-214, 240-242
plugins/apis/usgs.py                           182      25  86.26%   157, 263, 297, 339-341, 346, 374-375, 380, 410-417, 428-433, 455-461
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py             124      35  71.77%   52-54, 69-70, 142-149, 177-203, 226, 258-262, 279, 303, 319-320
plugins/authentication/base.py                  22       4  81.82%   45, 58, 81, 95
plugins/authentication/eoiam.py                 98       1  98.98%   170
plugins/authentication/generic.py               16       3  81.25%   50, 55, 65
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              46       4  91.30%   154, 177-182
plugins/authentication/openid_connect.py       235      19  91.91%   98-99, 107-125, 172, 180, 194, 214, 353-356, 382, 423
plugins/authentication/qsauth.py                34       1  97.06%   91
plugins/authentication/sas_auth.py              57       3  94.74%   68, 89, 135
plugins/authentication/token.py                141       9  93.62%   192, 229, 309-310, 358-362
plugins/authentication/token_exchange.py        36      14  61.11%   75, 93-121
plugins/crunch/__init__.py                       6       0  100.00%
plugins/crunch/base.py                          12       0  100.00%
plugins/crunch/filter_date.py                   47       0  100.00%
plugins/crunch/filter_latest_intersect.py       52       6  88.46%   87-88, 95-96, 98-102
plugins/crunch/filter_latest_tpl_name.py        35       0  100.00%
plugins/crunch/filter_overlap.py                66      10  84.85%   118-121, 137-163
plugins/crunch/filter_property.py               30       0  100.00%
plugins/download/__init__.py                     4       0  100.00%
plugins/download/aws.py                        402      76  81.09%   271, 305, 354-357, 387-388, 396-400, 480-483, 523-525, 529, 560-561, 567-571, 602, 667-675, 739-834, 846-851, 889, 915, 960-962, 1014
plugins/download/base.py                       288      24  91.67%   135, 165, 371-372, 416, 450, 527-531, 561, 596-597, 622-631, 690, 711, 733, 741
plugins/download/http.py                       575      74  87.13%   235, 277-280, 342-345, 348, 355-360, 391-393, 410, 425, 486, 521, 535, 549, 559-563, 579-584, 595, 614, 651-654, 675, 685, 692, 748, 857, 889, 921-930, 966, 1011-1016, 1025, 1040-1042, 1046, 1049, 1064-1065, 1075, 1150, 1202, 1244-1245, 1257, 1267, 1323-1324, 1354, 1392, 1472-1473
plugins/search/__init__.py                      25       0  100.00%
plugins/search/base.py                         197      18  90.86%   109, 113, 137-143, 218-221, 296, 317, 443, 493, 526-529, 538
plugins/search/build_search_result.py          526      95  81.94%   138-139, 175, 179, 199, 258, 425-436, 446-448, 515-516, 565, 577-579, 603, 605, 670, 678-682, 702, 712, 738, 787, 812, 834, 851-861, 866-887, 938, 963, 966, 970, 979, 985, 1023-1044, 1085, 1112-1113, 1122-1131, 1221, 1236, 1242, 1261-1270, 1391-1392, 1436, 1445-1447, 1504, 1552-1562
plugins/search/cop_ghsl.py                     407      85  79.12%   73-74, 109-110, 174, 176, 218, 249-252, 298, 314, 317, 353, 357-362, 377, 399, 420, 454, 470, 505, 520, 534-535, 549-551, 558, 562-564, 567-570, 588-648, 659-674
plugins/search/cop_marine.py                   295      68  76.95%   56, 64-66, 76-77, 82, 104, 106, 109, 175-176, 194, 212, 218, 222, 235, 244-245, 253, 288-291, 297, 307, 320, 328, 334-338, 344-347, 353-406, 422-425, 475, 487, 531-532
plugins/search/creodias_s3.py                   29       1  96.55%   59
plugins/search/csw.py                          112      87  22.32%   99-100, 104-105, 113-170, 176-189, 197-229, 247-288
plugins/search/eumetsat_ds.py                   25       0  100.00%
plugins/search/geodes.py                        64       0  100.00%
plugins/search/qssearch.py                     868      99  88.59%   382, 427-428, 545-546, 569-570, 582-586, 817-823, 881, 947, 977, 984, 1055, 1076, 1079-1080, 1098, 1107-1108, 1135, 1207, 1216, 1221-1238, 1247, 1262, 1271, 1284, 1307, 1316, 1406, 1429, 1444, 1517-1518, 1520-1522, 1524-1525, 1612, 1619, 1727-1731, 1802, 1805, 1809-1810, 1831-1834, 1846, 1868-1880, 1888, 1923-1925, 1948-1954, 1961, 2015, 2038, 2043-2044, 2059, 2065, 2079, 2180, 2184, 2195, 2219, 2232, 2240-2250
plugins/search/stac_list_assets.py              25      10  60.00%   44-51, 75-85
plugins/search/static_stac_search.py            84      18  78.57%   99-127, 166-169, 182, 224
resources/__init__.py                            0       0  100.00%
resources/shp/__init__.py                        0       0  100.00%
types/__init__.py                              180      43  76.11%   58, 71-75, 86-98, 126-128, 135-140, 155, 165, 247, 285, 295-311, 316, 318, 340, 345, 353, 363
types/bbox.py                                   39      19  51.28%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                          10       0  100.00%
types/queryables.py                            113       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/stac_extensions.py                       153       4  97.39%   455-461, 642
types/stac_metadata.py                         155      22  85.81%   98, 120, 153, 186-188, 202-216, 225-232, 259-262
utils/__init__.py                              636      48  92.45%   60, 199, 230-231, 240-266, 269, 284, 364-368, 443-447, 527, 567-568, 597, 975-978, 1029, 1048-1049, 1078, 1096-1097, 1254, 1256, 1264, 1268, 1274, 1276, 1278, 1284, 1286, 1384, 1548, 1613, 1788
utils/cache.py                                  22       0  100.00%
utils/dates.py                                 187       1  99.47%   174
utils/deserialize.py                            73      10  86.30%   53, 55, 103, 108-109, 145, 159, 181-182, 188
utils/env.py                                     3       0  100.00%
utils/exceptions.py                             58       0  100.00%
utils/free_text_search.py                       65       2  96.92%   83, 91
utils/import_system.py                          28      19  32.14%   64-78, 89-99
utils/logging.py                                31       1  96.77%   41
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/repr.py                                   38       0  100.00%
utils/requests.py                               55      29  47.27%   51-52, 64, 85-96, 107-124, 128
utils/s3.py                                    254      12  95.28%   200-203, 245, 263, 489, 536-537, 605, 680, 706
utils/stac_reader.py                           113      44  61.06%   63-85, 95-97, 101, 138, 154-159, 206-216, 226-256
utils/streamresponse.py                         82       7  91.46%   24-26, 63, 124, 133, 145
TOTAL                                        11270    1360  87.93%

Diff against develop

Filename                                 Stmts    Miss  Cover
-------------------------------------  -------  ------  -------
plugins/search/build_search_result.py       +7      +6  -0.91%
TOTAL                                       +7      +6  -0.05%

Results for commit: b243936

Minimum allowed coverage is 70%

♻️ This comment has been updated with latest results

@eodag-bot
Copy link
Copy Markdown
Collaborator

eodag-bot commented Apr 14, 2026

badge

Code Coverage (Windows)

Details
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         252      11  95.63%   105-116, 378, 645
config.py                                      306      24  92.16%   70-72, 75, 78, 81, 85, 89, 93-95, 587-589, 711-713, 732, 740, 770-775, 777
crunch.py                                        2       0  100.00%
api/__init__.py                                  0       0  100.00%
api/collection.py                              151       8  94.70%   177, 213, 216, 323, 362, 365, 383, 386
api/core.py                                    774      57  92.64%   263, 549, 597, 640, 680, 700, 741-746, 771, 855-874, 888, 894, 1047, 1052, 1151, 1190-1191, 1287-1288, 1314, 1345-1346, 1372, 1385, 1446-1447, 1478-1479, 1553-1558, 1570-1573, 1685, 1910, 2067, 2178, 2266-2267
api/provider.py                                382      40  89.53%   186, 190-191, 316-337, 405, 521, 525-526, 531-534, 545, 621-631, 821-822, 870, 877, 891, 914-917, 951-958, 962-963
api/search_result.py                           138      12  91.30%   111, 123, 133, 154, 208, 266, 278, 413, 468-471
api/product/__init__.py                          7       0  100.00%
api/product/_assets.py                          56       4  92.86%   101, 195, 206-210
api/product/_product.py                        311      24  92.28%   200, 356, 382-385, 422, 441-442, 551, 580, 587, 626, 738, 781-784, 793-796, 850, 916, 928, 995
api/product/metadata_mapping.py                867      62  92.85%   125-127, 222-227, 251, 310-311, 349-350, 391, 412, 475-476, 513, 534-537, 560, 572-573, 614, 637, 662-665, 667-672, 737-742, 751, 757, 773, 781, 1012, 1165, 1187, 1196-1200, 1217-1222, 1355, 1378, 1387, 1409, 1414, 1466, 1538, 1559, 1585, 1599, 1624, 1670, 1739, 1814, 1848, 1879
api/product/drivers/__init__.py                 11       0  100.00%
api/product/drivers/base.py                     32       0  100.00%
api/product/drivers/generic.py                  11       0  100.00%
api/product/drivers/sentinel1.py                33       0  100.00%
api/product/drivers/sentinel2.py                33       0  100.00%
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 25       2  92.00%   48, 55
plugins/manager.py                             173      16  90.75%   102-107, 179, 201, 219-220, 232, 271-272, 372-375, 387-388
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           95       8  91.58%   163-165, 213-214, 240-242
plugins/apis/usgs.py                           182      25  86.26%   157, 263, 297, 339-341, 346, 374-375, 380, 410-417, 428-433, 455-461
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py             124      35  71.77%   52-54, 69-70, 142-149, 177-203, 226, 258-262, 279, 303, 319-320
plugins/authentication/base.py                  22       4  81.82%   45, 58, 81, 95
plugins/authentication/eoiam.py                 98       1  98.98%   170
plugins/authentication/generic.py               16       3  81.25%   50, 55, 65
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              46       4  91.30%   154, 177-182
plugins/authentication/openid_connect.py       235      19  91.91%   98-99, 107-125, 172, 180, 194, 214, 353-356, 382, 423
plugins/authentication/qsauth.py                34       1  97.06%   91
plugins/authentication/sas_auth.py              57       3  94.74%   68, 89, 135
plugins/authentication/token.py                141       9  93.62%   192, 229, 309-310, 358-362
plugins/authentication/token_exchange.py        36      14  61.11%   75, 93-121
plugins/crunch/__init__.py                       6       0  100.00%
plugins/crunch/base.py                          12       0  100.00%
plugins/crunch/filter_date.py                   47       0  100.00%
plugins/crunch/filter_latest_intersect.py       52       6  88.46%   87-88, 95-96, 98-102
plugins/crunch/filter_latest_tpl_name.py        35       0  100.00%
plugins/crunch/filter_overlap.py                66      10  84.85%   118-121, 137-163
plugins/crunch/filter_property.py               30       0  100.00%
plugins/download/__init__.py                     4       0  100.00%
plugins/download/aws.py                        402      76  81.09%   271, 305, 354-357, 387-388, 396-400, 480-483, 523-525, 529, 560-561, 567-571, 602, 667-675, 739-834, 846-851, 889, 915, 960-962, 1014
plugins/download/base.py                       288      26  90.97%   135, 165, 232-234, 371-372, 416, 450, 527-531, 561, 596-597, 622-631, 690, 711, 733, 741
plugins/download/http.py                       575      74  87.13%   235, 277-280, 342-345, 348, 355-360, 391-393, 410, 425, 486, 521, 535, 549, 559-563, 579-584, 595, 614, 651-654, 675, 685, 692, 748, 857, 889, 921-930, 966, 1011-1016, 1025, 1040-1042, 1046, 1049, 1064-1065, 1075, 1150, 1202, 1244-1245, 1257, 1267, 1323-1324, 1354, 1392, 1472-1473
plugins/search/__init__.py                      25       0  100.00%
plugins/search/base.py                         197      18  90.86%   109, 113, 137-143, 218-221, 296, 317, 443, 493, 526-529, 538
plugins/search/build_search_result.py          526      95  81.94%   138-139, 175, 179, 199, 258, 425-436, 446-448, 515-516, 565, 577-579, 603, 605, 670, 678-682, 702, 712, 738, 787, 812, 834, 851-861, 866-887, 938, 963, 966, 970, 979, 985, 1023-1044, 1085, 1112-1113, 1122-1131, 1221, 1236, 1242, 1261-1270, 1391-1392, 1436, 1445-1447, 1504, 1552-1562
plugins/search/cop_ghsl.py                     407      85  79.12%   73-74, 109-110, 174, 176, 218, 249-252, 298, 314, 317, 353, 357-362, 377, 399, 420, 454, 470, 505, 520, 534-535, 549-551, 558, 562-564, 567-570, 588-648, 659-674
plugins/search/cop_marine.py                   295      68  76.95%   56, 64-66, 76-77, 82, 104, 106, 109, 175-176, 194, 212, 218, 222, 235, 244-245, 253, 288-291, 297, 307, 320, 328, 334-338, 344-347, 353-406, 422-425, 475, 487, 531-532
plugins/search/creodias_s3.py                   29       1  96.55%   59
plugins/search/csw.py                          112      87  22.32%   99-100, 104-105, 113-170, 176-189, 197-229, 247-288
plugins/search/eumetsat_ds.py                   25       0  100.00%
plugins/search/geodes.py                        64       0  100.00%
plugins/search/qssearch.py                     868      99  88.59%   382, 427-428, 545-546, 569-570, 582-586, 817-823, 881, 947, 977, 984, 1055, 1076, 1079-1080, 1098, 1107-1108, 1135, 1207, 1216, 1221-1238, 1247, 1262, 1271, 1284, 1307, 1316, 1406, 1429, 1444, 1517-1518, 1520-1522, 1524-1525, 1612, 1619, 1727-1731, 1802, 1805, 1809-1810, 1831-1834, 1846, 1868-1880, 1888, 1923-1925, 1948-1954, 1961, 2015, 2038, 2043-2044, 2059, 2065, 2079, 2180, 2184, 2195, 2219, 2232, 2240-2250
plugins/search/stac_list_assets.py              25      10  60.00%   44-51, 75-85
plugins/search/static_stac_search.py            84      18  78.57%   99-127, 166-169, 182, 224
resources/__init__.py                            0       0  100.00%
resources/shp/__init__.py                        0       0  100.00%
types/__init__.py                              180      43  76.11%   58, 71-75, 86-98, 126-128, 135-140, 155, 165, 247, 285, 295-311, 316, 318, 340, 345, 353, 363
types/bbox.py                                   39      19  51.28%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                          10       0  100.00%
types/queryables.py                            113       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/stac_extensions.py                       153       4  97.39%   455-461, 642
types/stac_metadata.py                         155      22  85.81%   98, 120, 153, 186-188, 202-216, 225-232, 259-262
utils/__init__.py                              636      48  92.45%   60, 199, 230-231, 240-266, 269, 284, 364-368, 443-447, 527, 567-568, 597, 975-978, 1029, 1048-1049, 1078, 1096-1097, 1254, 1256, 1264, 1268, 1274, 1276, 1278, 1284, 1286, 1384, 1548, 1613, 1788
utils/cache.py                                  22       0  100.00%
utils/dates.py                                 187       1  99.47%   174
utils/deserialize.py                            73      10  86.30%   53, 55, 103, 108-109, 145, 159, 181-182, 188
utils/env.py                                     3       0  100.00%
utils/exceptions.py                             58       0  100.00%
utils/free_text_search.py                       65       2  96.92%   83, 91
utils/import_system.py                          28      19  32.14%   64-78, 89-99
utils/logging.py                                31       1  96.77%   41
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/repr.py                                   38       0  100.00%
utils/requests.py                               55      29  47.27%   51-52, 64, 85-96, 107-124, 128
utils/s3.py                                    254      12  95.28%   200-203, 245, 263, 489, 536-537, 605, 680, 706
utils/stac_reader.py                           113      44  61.06%   63-85, 95-97, 101, 138, 154-159, 206-216, 226-256
utils/streamresponse.py                         82       7  91.46%   24-26, 63, 124, 133, 145
TOTAL                                        11270    1362  87.91%

Diff against develop

Filename                                 Stmts    Miss  Cover
-------------------------------------  -------  ------  -------
plugins/search/build_search_result.py       +7      +6  -0.91%
TOTAL                                       +7      +6  -0.05%

Results for commit: b243936

Minimum allowed coverage is 70%

♻️ This comment has been updated with latest results

@dalpasso dalpasso marked this pull request as ready for review April 14, 2026 13:07
@dalpasso dalpasso requested a review from jlahovnik April 14, 2026 13:07
@dalpasso dalpasso self-assigned this Apr 14, 2026
dalpasso added 2 commits May 6, 2026 10:54
More precisely: allow any value if the keyword not required by form and the list of allowed values is empty.
@jlahovnik jlahovnik force-pushed the fix-request-validation-of-CMIP6_CLIMATE_PROJECTIONS branch from 4018d34 to b243936 Compare May 6, 2026 08:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants