Skip to content

feat(core): STAC summaries in Collections#2052

Merged
sbrunato merged 12 commits intov5.x.xfrom
collections-stac-formatting
Mar 24, 2026
Merged

feat(core): STAC summaries in Collections#2052
sbrunato merged 12 commits intov5.x.xfrom
collections-stac-formatting

Conversation

@anesson-cs
Copy link
Copy Markdown
Collaborator

@anesson-cs anesson-cs commented Feb 16, 2026

Linked to this PR and fix this issue.

eodag collection model now inherits Collection model from library stac_pydantic to be fully STAC-compliant. Some fields are adapted to eodag to deal with cases where values are not provided in the input, especially when fields are mandatory. Field keywords is adapted for typing reason.

model_dump() and model_dump_json() methods are overwritten to get unset values and display 'stac_extensions' property if wanted. As it takes too long to set stac_extensions for a big amount of collections, a parameter display_extensions has been created to display it with these methods when needed.

The wrap validator has been updated to handle errors of an element in a dictionary or list field as these fields are now accepted in the model.

Some validators have been created to deal with field summaries, which is a dictionary whose key-value pairs are checked in the model. Pairs set directly in model fields have priority over the ones set in field summaries.

proprietary is replaced by other for collection metadata license which still had this value in some collections.

The default value of collection metadata instruments is now set to None as it is not mandatory.

@anesson-cs anesson-cs self-assigned this Feb 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 16, 2026

Test Results

    4 files  ± 0      4 suites  ±0   4m 32s ⏱️ + 1m 12s
  708 tests +11    706 ✅ +10   2 💤 +1  0 ❌ ±0 
2 874 runs  +44  2 864 ✅ +40  10 💤 +4  0 ❌ ±0 

Results for commit 14ca62c. ± Comparison against base commit b2df124.

This pull request removes 1 and adds 12 tests. Note that renamed tests count towards both.
eodag.api.collection ‑ eodag.api.collection.Collection.get_collection_mtd_from_alias
eodag.api.collection ‑ eodag.api.collection.Collection.get_collection_alias_from_field
eodag.api.collection ‑ eodag.api.collection.Collection.get_collection_field_from_alias
tests.units.test_collection.TestCollection ‑ test_collection_dump
tests.units.test_collection.TestCollection ‑ test_collection_dump_json
tests.units.test_collection.TestCollection ‑ test_collection_stac_fields
tests.units.test_collection.TestCollection ‑ test_collection_static_fields
tests.units.test_collection.TestCollection ‑ test_collection_strings_for_list_fields
tests.units.test_collection.TestCollection ‑ test_collection_summaries
tests.units.test_collection.TestCollection ‑ test_collection_summaries_fields
tests.units.test_collection.TestCollection ‑ test_collection_wrong_links
…
This pull request skips 1 test.
tests.units.test_core.TestCoreSearch ‑ test_guess_collection_has_no_limit

♻️ This comment has been updated with latest results.

@anesson-cs anesson-cs marked this pull request as draft February 16, 2026 16:39
@eodag-bot
Copy link
Copy Markdown
Collaborator

eodag-bot commented Feb 18, 2026

badge

Code Coverage (Ubuntu)

Details
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         251      11  95.62%   104-115, 377, 644
config.py                                      305      24  92.13%   70-72, 75, 78, 81, 85, 89, 93-95, 583-585, 707-709, 728, 736, 766-771, 773
crunch.py                                        2       0  100.00%
api/__init__.py                                  0       0  100.00%
api/collection.py                              276      11  96.01%   194, 199, 311, 408, 426, 558, 561, 653, 656, 674, 677
api/core.py                                    793      57  92.81%   266, 552, 600, 643, 683, 703, 744-749, 774, 895-914, 928, 934, 1087, 1092, 1191, 1230-1231, 1327-1328, 1354, 1385-1386, 1412, 1425, 1486-1487, 1504, 1518-1519, 1593-1598, 1610-1613, 1725, 2112, 2238, 2326-2327
api/provider.py                                381      35  90.81%   186, 190-191, 316-337, 405, 521, 525-526, 531-534, 545, 621-631, 821-822, 870, 877, 908-911, 947-948, 956-957
api/search_result.py                           181      19  89.50%   111, 123, 133, 154, 203, 220, 320, 375-378, 448, 453-454, 488, 502, 525-526, 532
api/product/__init__.py                         18       2  88.89%   57, 59
api/product/_assets.py                          52       4  92.31%   97, 191, 194-198
api/product/_product.py                        248      20  91.94%   189, 305-306, 324-325, 434, 463, 470, 577, 597, 620-623, 632-635, 689, 755, 767
api/product/metadata_mapping.py                791      53  93.30%   125-127, 220-225, 249, 307-308, 396, 417, 469-470, 507, 528-531, 554, 566-567, 608, 631, 661-666, 731-736, 748, 756, 988, 1163, 1172-1176, 1193-1198, 1331, 1354, 1363, 1385, 1390, 1442, 1514, 1535, 1561, 1575, 1600, 1646, 1715, 1790
api/product/drivers/__init__.py                 11       0  100.00%
api/product/drivers/base.py                     29       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       7  72.00%   48, 55, 68-72
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                          101       8  92.08%   178-180, 228-229, 255-257
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/generic.py               16       3  81.25%   50, 55, 65
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              46       7  84.78%   153-156, 177-182
plugins/authentication/openid_connect.py       232      28  87.93%   91-92, 104-122, 169, 175-203, 211, 350-353, 379, 420
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                128       9  92.97%   180, 217, 288-289, 339-343
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                   59       0  100.00%
plugins/crunch/filter_latest_intersect.py       54       6  88.89%   92-93, 100-101, 103-107
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                     0       0  100.00%
plugins/download/aws.py                        401      76  81.05%   270, 304, 353-356, 386-387, 395-399, 479-482, 522-524, 528, 559-560, 566-570, 601, 666-674, 738-833, 845-850, 888, 914, 959-961, 1013
plugins/download/base.py                       280      35  87.50%   133, 162, 309-310, 368-369, 411, 415-426, 440, 517-521, 551, 586-587, 612-621, 680, 701, 723, 731, 765
plugins/download/http.py                       564      77  86.35%   233, 275-278, 340-343, 346, 353-358, 389-391, 408, 423, 483, 518, 532, 546, 556-560, 576-581, 592, 611, 648-651, 672, 682, 689, 854, 886, 916-925, 961, 986-987, 1006-1011, 1020, 1035-1037, 1041, 1044, 1059-1060, 1144, 1196, 1238-1239, 1251, 1261, 1311-1312, 1342, 1362, 1403-1405, 1459-1460
plugins/search/__init__.py                      25       0  100.00%
plugins/search/base.py                         196      18  90.82%   109, 113, 137-143, 200-203, 296, 317, 442, 492, 525-528, 537
plugins/search/build_search_result.py          504      83  83.53%   259-260, 296, 300, 320, 550-561, 576-578, 701, 725, 727, 794, 802-806, 827, 837, 863, 908, 932, 960, 978-993, 1043, 1068, 1071, 1075, 1084, 1090, 1128-1149, 1190, 1217-1218, 1227-1236, 1300, 1315, 1321, 1340-1349, 1470-1471, 1515, 1524-1526, 1583, 1631-1641
plugins/search/cop_marine.py                   273      59  78.39%   57, 65-67, 77-78, 83, 88-89, 105, 107, 110, 176-177, 220, 236, 242, 246, 250, 261, 272-273, 281, 313-316, 322, 332, 345, 349, 353, 357, 361-365, 371-374, 377-394, 411-414, 467-471, 476, 488, 502-503
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/qssearch.py                     823      94  88.58%   415-416, 533-534, 557-558, 570-574, 786-792, 850, 946, 953, 1024, 1045, 1048-1049, 1067, 1076-1077, 1104, 1176, 1185, 1190-1207, 1216, 1231, 1240-1243, 1253, 1275, 1364, 1387, 1460-1461, 1467, 1557, 1664-1668, 1734, 1737, 1741-1742, 1763-1766, 1778, 1800-1812, 1820, 1855-1857, 1880-1886, 1893, 1947, 1970, 1975-1976, 1991, 1997, 2007, 2097, 2101, 2112, 2136, 2149, 2157-2167, 2205-2209
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                              167      43  74.25%   58, 62, 71-75, 86-98, 126-128, 135-140, 216, 219, 257, 267-283, 288, 290, 312, 317, 325, 335
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                            112       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/stac_extensions.py                       114       1  99.12%   282
types/stac_metadata.py                         118      16  86.44%   94, 115-116, 149, 179-193, 202-209
utils/__init__.py                              608      43  92.93%   71, 206, 237-238, 247-273, 276, 291, 371-375, 450-454, 534, 574-575, 604, 982-985, 1036, 1055-1056, 1085, 1103-1104, 1216, 1304, 1468, 1557, 1572, 1581, 1593, 1783
utils/cache.py                                  22       0  100.00%
utils/dates.py                                 113       4  96.46%   171, 329-331
utils/env.py                                     3       0  100.00%
utils/exceptions.py                             47       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                                28       1  96.43%   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                                    240      12  95.00%   200-203, 245, 263, 489, 537-538, 585, 660, 686
utils/stac_reader.py                           113      44  61.06%   63-85, 95-97, 101, 138, 154-159, 206-216, 226-256
TOTAL                                        10240    1245  87.84%

Diff against develop

Filename             Stmts    Miss  Cover
-----------------  -------  ------  -------
api/collection.py     +126      +3  +1.34%
api/core.py             +6       0  +0.05%
TOTAL                 +132      +3  +0.13%

Results for commit: 14ca62c

Minimum allowed coverage is 70%

♻️ This comment has been updated with latest results

@eodag-bot
Copy link
Copy Markdown
Collaborator

eodag-bot commented Feb 19, 2026

badge

Code Coverage (Windows)

Details
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         251      11  95.62%   104-115, 377, 644
config.py                                      305      24  92.13%   70-72, 75, 78, 81, 85, 89, 93-95, 583-585, 707-709, 728, 736, 766-771, 773
crunch.py                                        2       0  100.00%
api/__init__.py                                  0       0  100.00%
api/collection.py                              276      11  96.01%   194, 199, 311, 408, 426, 558, 561, 653, 656, 674, 677
api/core.py                                    793      57  92.81%   266, 552, 600, 643, 683, 703, 744-749, 774, 895-914, 928, 934, 1087, 1092, 1191, 1230-1231, 1327-1328, 1354, 1385-1386, 1412, 1425, 1486-1487, 1504, 1518-1519, 1593-1598, 1610-1613, 1725, 2112, 2238, 2326-2327
api/provider.py                                381      35  90.81%   186, 190-191, 316-337, 405, 521, 525-526, 531-534, 545, 621-631, 821-822, 870, 877, 908-911, 947-948, 956-957
api/search_result.py                           181      19  89.50%   111, 123, 133, 154, 203, 220, 320, 375-378, 448, 453-454, 488, 502, 525-526, 532
api/product/__init__.py                         18       2  88.89%   57, 59
api/product/_assets.py                          52       4  92.31%   97, 191, 194-198
api/product/_product.py                        248      20  91.94%   189, 305-306, 324-325, 434, 463, 470, 577, 597, 620-623, 632-635, 689, 755, 767
api/product/metadata_mapping.py                791      53  93.30%   125-127, 220-225, 249, 307-308, 396, 417, 469-470, 507, 528-531, 554, 566-567, 608, 631, 661-666, 731-736, 748, 756, 988, 1163, 1172-1176, 1193-1198, 1331, 1354, 1363, 1385, 1390, 1442, 1514, 1535, 1561, 1575, 1600, 1646, 1715, 1790
api/product/drivers/__init__.py                 11       0  100.00%
api/product/drivers/base.py                     29       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       7  72.00%   48, 55, 68-72
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                          101       8  92.08%   178-180, 228-229, 255-257
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/generic.py               16       3  81.25%   50, 55, 65
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              46       7  84.78%   153-156, 177-182
plugins/authentication/openid_connect.py       232      28  87.93%   91-92, 104-122, 169, 175-203, 211, 350-353, 379, 420
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                128       9  92.97%   180, 217, 288-289, 339-343
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                   59       0  100.00%
plugins/crunch/filter_latest_intersect.py       54       6  88.89%   92-93, 100-101, 103-107
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                     0       0  100.00%
plugins/download/aws.py                        401      76  81.05%   270, 304, 353-356, 386-387, 395-399, 479-482, 522-524, 528, 559-560, 566-570, 601, 666-674, 738-833, 845-850, 888, 914, 959-961, 1013
plugins/download/base.py                       280      37  86.79%   133, 162, 229-231, 309-310, 368-369, 411, 415-426, 440, 517-521, 551, 586-587, 612-621, 680, 701, 723, 731, 765
plugins/download/http.py                       564      77  86.35%   233, 275-278, 340-343, 346, 353-358, 389-391, 408, 423, 483, 518, 532, 546, 556-560, 576-581, 592, 611, 648-651, 672, 682, 689, 854, 886, 916-925, 961, 986-987, 1006-1011, 1020, 1035-1037, 1041, 1044, 1059-1060, 1144, 1196, 1238-1239, 1251, 1261, 1311-1312, 1342, 1362, 1403-1405, 1459-1460
plugins/search/__init__.py                      25       0  100.00%
plugins/search/base.py                         196      18  90.82%   109, 113, 137-143, 200-203, 296, 317, 442, 492, 525-528, 537
plugins/search/build_search_result.py          504      83  83.53%   259-260, 296, 300, 320, 550-561, 576-578, 701, 725, 727, 794, 802-806, 827, 837, 863, 908, 932, 960, 978-993, 1043, 1068, 1071, 1075, 1084, 1090, 1128-1149, 1190, 1217-1218, 1227-1236, 1300, 1315, 1321, 1340-1349, 1470-1471, 1515, 1524-1526, 1583, 1631-1641
plugins/search/cop_marine.py                   273      59  78.39%   57, 65-67, 77-78, 83, 88-89, 105, 107, 110, 176-177, 220, 236, 242, 246, 250, 261, 272-273, 281, 313-316, 322, 332, 345, 349, 353, 357, 361-365, 371-374, 377-394, 411-414, 467-471, 476, 488, 502-503
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/qssearch.py                     823      94  88.58%   415-416, 533-534, 557-558, 570-574, 786-792, 850, 946, 953, 1024, 1045, 1048-1049, 1067, 1076-1077, 1104, 1176, 1185, 1190-1207, 1216, 1231, 1240-1243, 1253, 1275, 1364, 1387, 1460-1461, 1467, 1557, 1664-1668, 1734, 1737, 1741-1742, 1763-1766, 1778, 1800-1812, 1820, 1855-1857, 1880-1886, 1893, 1947, 1970, 1975-1976, 1991, 1997, 2007, 2097, 2101, 2112, 2136, 2149, 2157-2167, 2205-2209
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                              167      43  74.25%   58, 62, 71-75, 86-98, 126-128, 135-140, 216, 219, 257, 267-283, 288, 290, 312, 317, 325, 335
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                            112       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/stac_extensions.py                       114       1  99.12%   282
types/stac_metadata.py                         118      16  86.44%   94, 115-116, 149, 179-193, 202-209
utils/__init__.py                              608      43  92.93%   71, 206, 237-238, 247-273, 276, 291, 371-375, 450-454, 534, 574-575, 604, 982-985, 1036, 1055-1056, 1085, 1103-1104, 1216, 1304, 1468, 1557, 1572, 1581, 1593, 1783
utils/cache.py                                  22       0  100.00%
utils/dates.py                                 113       4  96.46%   171, 329-331
utils/env.py                                     3       0  100.00%
utils/exceptions.py                             47       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                                28       1  96.43%   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                                    240      12  95.00%   200-203, 245, 263, 489, 537-538, 585, 660, 686
utils/stac_reader.py                           113      44  61.06%   63-85, 95-97, 101, 138, 154-159, 206-216, 226-256
TOTAL                                        10240    1247  87.82%

Diff against develop

Filename             Stmts    Miss  Cover
-----------------  -------  ------  -------
api/collection.py     +126      +3  +1.34%
api/core.py             +6       0  +0.05%
TOTAL                 +132      +3  +0.13%

Results for commit: 14ca62c

Minimum allowed coverage is 70%

♻️ This comment has been updated with latest results

@anesson-cs anesson-cs force-pushed the collections-stac-formatting branch from 01a09cf to 716b848 Compare February 19, 2026 09:57
@anesson-cs anesson-cs marked this pull request as ready for review February 19, 2026 10:02
@anesson-cs anesson-cs requested a review from sbrunato February 19, 2026 10:03
@anesson-cs anesson-cs force-pushed the collections-stac-formatting branch from 716b848 to fc87c45 Compare February 19, 2026 13:19
Comment thread eodag/api/core.py
@sbrunato sbrunato marked this pull request as draft March 18, 2026 13:54
eodag collection model now inherits 'Collection model from 'stac_pydantic'

'model_dump()' and 'model_dump_json()' methods are overwritten to get unset values and display 'stac_extensions' property if wanted

new validators have been created

the wrap validator has been updated to handle errors of an element in a dictionary or list field

replace 'proprietary' by 'other' for collection metadata 'license'

the default value of collection metadata 'instruments' is now set to None
when a sub-field do not pass validation, it is replaced by its default value
it converts string values of fields whose type is list in the model to list of strings
collection 'CLMS_HRVPP_ST' has already a link in file 'collections.yml'
@anesson-cs anesson-cs force-pushed the collections-stac-formatting branch from fc87c45 to 14ca62c Compare March 19, 2026 15:56
@anesson-cs anesson-cs marked this pull request as ready for review March 19, 2026 16:03
@anesson-cs anesson-cs requested a review from sbrunato March 20, 2026 08:32
@sbrunato sbrunato changed the base branch from develop to v5.x.x March 24, 2026 14:50
@sbrunato sbrunato changed the title feat: complete collections STAC formatting feat(core): STAC summaries in Collections Mar 24, 2026
@sbrunato sbrunato merged commit 64c8983 into v5.x.x Mar 24, 2026
13 checks passed
@sbrunato sbrunato deleted the collections-stac-formatting branch March 24, 2026 14:53
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.

4 participants