Repository: CS-SI/eodag
Pull request #1199 (2024-06-11 08:02:21)

fix(server): single asset download with ignore_assets plugin setting
Check if the user set `asset` in download `kwargs` so the `download_link` is not automatically used if the provider has `ignore_assets` attribute set to True in its configuration.

github-actions[bot]: ## Test Results
    4 files  ±0      4 suites  ±0   5m 30s :stopwatch: +5s
  542 tests ±0    539 :white_check_mark: ±0   3 :zzz: ±0  0 :x: ±0 
2 168 runs  ±0  2 070 :white_check_mark: ±0  98 :zzz: ±0  0 :x: ±0 

Results for commit c3aaeba2. ± Comparison against base commit 2c37db30.

[test-results]:data:application/gzip;base64,H4sIAHwFaGYC/02MSw7CIBBAr9KwdgEDVPAyzUghIbbF8FkZ7y5oi93NezPzXsT5xSZyG8RlIKn43GEuEbMPW0XOaRV1ldtSCjhoSsWYprj+q4d/tp8uHPqlip6YbIwh7iaWrTWBjWqnown0Srv6NXW/OTW/fE6asK4+VyCGI9o7gnJSKASJlikHTivL6jiPlAkDzAB5fwDLXxVeCAEAAA==

github-actions[bot]: ![badge](https://raw.githubusercontent.com/CS-SI/eodag/_xml_coverage_reports/data/eumetsat-zip-single-asset/./badge.svg)


## Code Coverage (Ubuntu)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                     10       0  100.00%
cli.py                                         302      51  83.11%   60, 644-690, 792-843, 847
config.py                                      349      27  92.26%   81-83, 92, 100, 104-106, 183, 195, 452-454, 518-521, 568-569, 578-579, 658, 727-732, 734
crunch.py                                        5       5  0.00%    20-24
api/__init__.py                                  0       0  100.00%
api/core.py                                    760      84  88.95%   89-98, 372, 597, 641-644, 682, 719, 792, 796-801, 827, 923, 1000, 1113, 1203-1215, 1255, 1257, 1261, 1284, 1288-1299, 1312-1318, 1408-1411, 1440-1460, 1517, 1534-1537, 1549-1552, 1569-1576, 1941, 1974-1980, 2245, 2249-2252, 2266-2268, 2303
api/search_result.py                            50       6  88.00%   33-35, 70, 79, 86, 100
api/product/__init__.py                          5       0  100.00%
api/product/_assets.py                          44       5  88.64%   27-29, 79, 129
api/product/_product.py                        203      32  84.24%   56-63, 67-69, 173-180, 264-265, 347, 376, 437, 451-454, 467, 491-494, 537-543
api/product/metadata_mapping.py                678      83  87.76%   67-69, 131-133, 234, 266-267, 313-314, 324-336, 338, 349, 355-367, 412-413, 450, 471-474, 497, 505-506, 582-583, 607-608, 614-617, 632-633, 782, 828, 1002-1007, 1138, 1152-1172, 1192, 1197, 1307, 1329, 1343, 1356-1375, 1414, 1466, 1504-1508, 1527
api/product/drivers/__init__.py                  5       0  100.00%
api/product/drivers/base.py                      8       2  75.00%   23, 41
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 23       3  86.96%   25, 48, 55
plugins/manager.py                             133      15  88.72%   49-51, 105-110, 156, 197, 219, 223, 248, 287-288
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           99      15  84.85%   46-54, 150-152, 199-200, 226-228
plugins/apis/usgs.py                           175      36  79.43%   60-65, 132, 205, 239, 274-276, 281, 307-308, 313, 343-350, 361-366, 388-394, 396-402, 425
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py              20       2  90.00%   25-27
plugins/authentication/base.py                  19       3  84.21%   26, 34, 47
plugins/authentication/generic.py               16       3  81.25%   28, 40, 50
plugins/authentication/header.py                17       1  94.12%   27
plugins/authentication/keycloak.py              49       6  87.76%   33-35, 132, 156-161
plugins/authentication/oauth.py                 15       8  46.67%   25, 32-34, 38-41
plugins/authentication/openid_connect.py       186      19  89.78%   41-43, 121, 135-160, 168, 322-325, 349
plugins/authentication/qsauth.py                36       2  94.44%   32, 83
plugins/authentication/sas_auth.py              49       2  95.92%   32, 76
plugins/authentication/token.py                 90      17  81.11%   35-37, 79, 107, 109, 131-143, 198-201
plugins/authentication/token_exchange.py        35      19  45.71%   74-80, 92-120
plugins/crunch/__init__.py                       0       0  100.00%
plugins/crunch/base.py                          10       2  80.00%   25, 38
plugins/crunch/filter_date.py                   62      15  75.81%   30, 53-58, 72, 81, 90, 93, 105-107, 116-118, 125
plugins/crunch/filter_latest_intersect.py       50      10  80.00%   32-34, 51-52, 71, 80-83, 85, 92-95
plugins/crunch/filter_latest_tpl_name.py        33       2  93.94%   28, 86
plugins/crunch/filter_overlap.py                68      17  75.00%   28-30, 33, 82-85, 91, 99, 110-126
plugins/crunch/filter_property.py               33       8  75.76%   29, 60-65, 68-69, 85-89
plugins/download/__init__.py                     0       0  100.00%
plugins/download/aws.py                        492     165  66.46%   77-83, 272, 285, 352-355, 369-373, 419-421, 425, 459-460, 466-470, 503, 538, 542, 549, 579-587, 591, 629-637, 644-646, 687-761, 779-840, 851-856, 872-885, 914, 929-931, 934, 944-952, 960-973, 983-1002, 1009-1021, 1062, 1088, 1133-1135, 1355
plugins/download/base.py                       260      57  78.08%   58-64, 145, 180, 319-320, 340-346, 377-381, 387-388, 432, 435-449, 461, 465, 538-542, 572-573, 581-598, 605-613, 615-619, 666, 688, 710, 718
plugins/download/creodias_s3.py                 17       9  47.06%   44-58
plugins/download/http.py                       529     132  75.05%   85-91, 124, 203-213, 215-216, 251-254, 318-321, 323-324, 331-336, 354-369, 386-388, 400, 448, 455-461, 479, 493, 507, 515-517, 533-538, 549, 567, 609-613, 635, 675, 720, 734-740, 776-840, 858, 891-900, 926-927, 954-959, 965, 981, 998-999, 1026-1027, 1034, 1096-1102, 1157-1158, 1164, 1174, 1240, 1244, 1258-1274
plugins/download/s3rest.py                     118      27  77.12%   55-58, 121, 162, 197, 227-234, 237-239, 243, 256-262, 270-271, 274-278, 301, 322-325
plugins/search/__init__.py                      26       3  88.46%   27-31
plugins/search/base.py                         133      13  90.23%   48-53, 104, 108, 121, 271, 291, 350-351, 371, 380
plugins/search/build_search_result.py          183      24  86.89%   62, 97, 141-142, 148, 159, 295-298, 327, 384-401, 463, 466, 476, 493, 521, 523
plugins/search/creodias_s3.py                   55       3  94.55%   56, 74, 108
plugins/search/csw.py                          108      83  23.15%   44-46, 58-59, 63-64, 72-120, 126-139, 147-179, 197-238
plugins/search/data_request_search.py          198      65  67.17%   53, 90-93, 109, 121, 125-126, 137, 142, 147, 154, 167-170, 224-225, 229, 239-245, 250, 276-279, 287-298, 315, 317, 324-325, 327-328, 346-350, 383, 390, 401, 414, 420-432, 437
plugins/search/qssearch.py                     646      69  89.32%   102, 386, 390-396, 404-405, 512-518, 568, 584, 594, 621, 623, 666-669, 744-745, 788, 807, 822, 880, 901, 904-905, 914, 925, 934, 957, 1021-1026, 1030-1031, 1061, 1135, 1184, 1258-1262, 1328-1329, 1350, 1378-1390, 1397, 1429-1431, 1441-1447, 1491, 1506, 1526, 1629-1639
plugins/search/static_stac_search.py            48       3  93.75%   35-36, 78
rest/__init__.py                                 4       2  50.00%   21-22
rest/core.py                                   207      17  91.79%   66-72, 261, 345, 605, 607, 610-612, 684, 691-696
rest/server.py                                 299      53  82.27%   80-81, 107, 130-131, 244-246, 302-303, 315-331, 423-428, 460, 627-634, 667, 711-712, 803-805, 822-827, 858, 860, 864-865, 869-870
rest/stac.py                                   474      91  80.80%   63-65, 327, 349, 421, 458-460, 483, 518-519, 605-644, 681-686, 770-774, 808, 828-829, 972, 1037-1039, 1258, 1268-1280, 1293-1315, 1329-1374, 1533-1534
rest/types/__init__.py                           0       0  100.00%
rest/types/eodag_search.py                     184       9  95.11%   52-55, 235-239, 292, 295, 363
rest/types/stac_queryables.py                   38       2  94.74%   34, 140
rest/types/stac_search.py                      121      10  91.74%   48-51, 167, 182-184, 192, 196
rest/utils/__init__.py                          95      13  86.32%   51, 108-109, 128-130, 182, 192-206
rest/utils/cql_evaluate.py                      48       5  89.58%   69, 76, 90, 97, 105
rest/utils/rfc3339.py                           31       3  90.32%   78, 90, 92
types/__init__.py                              110      11  90.00%   53, 70, 129-132, 199, 214-218, 245, 258
types/bbox.py                                   43      19  55.81%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                           9       0  100.00%
types/queryables.py                             81       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 104
types/whoosh.py                                 15       0  100.00%
utils/__init__.py                              501      41  91.82%   84, 89, 110-112, 193-194, 203-230, 233, 247, 329-333, 409-413, 434-436, 518, 533, 571-572, 968-971, 979-980, 1021-1022, 1102, 1204, 1380
utils/constraints.py                           119      37  68.91%   94-103, 144, 149, 153, 164, 190-192, 202, 216-232, 241-252
utils/exceptions.py                             37       2  94.59%   23, 93
utils/import_system.py                          30      20  33.33%   27, 67-81, 93-103
utils/logging.py                                29       1  96.55%   123
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/requests.py                               55      11  80.00%   69, 96, 98, 100, 102, 104, 123, 128-130, 138
utils/rest.py                                   27       1  96.30%   49
utils/stac_reader.py                            91      28  69.23%   55-56, 63-86, 93-95, 99, 141, 155-158
TOTAL                                         9222    1571  82.96%
```

</details>


### Diff against develop

```
Filename      Stmts    Miss  Cover
----------  -------  ------  --------
TOTAL             0       0  +100.00%
```


Results for commit: c3aaeba28f548a25ae18f2f98e1ae1d6014c21c2


_Minimum allowed coverage is `70%`_


:recycle: This comment has been updated with latest results


<!-- Sticky Pull Request Commentartifacts/unit-test-results-python3.12-ubuntu-latest/coverage.xml -->
github-actions[bot]: ![badge](https://raw.githubusercontent.com/CS-SI/eodag/_xml_coverage_reports_win/data/eumetsat-zip-single-asset/./badge.svg)


## Code Coverage (Windows)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                     10       0  100.00%
cli.py                                         302      51  83.11%   60, 644-690, 792-843, 847
config.py                                      349      28  91.98%   81-83, 92, 100, 104-106, 183, 195, 452-454, 518-521, 568-569, 578-579, 658, 692, 727-732, 734
crunch.py                                        5       5  0.00%    20-24
api/__init__.py                                  0       0  100.00%
api/core.py                                    760      84  88.95%   89-98, 372, 597, 641-644, 682, 719, 792, 796-801, 827, 923, 1000, 1113, 1203-1215, 1255, 1257, 1261, 1284, 1288-1299, 1312-1318, 1408-1411, 1440-1460, 1517, 1534-1537, 1549-1552, 1569-1576, 1941, 1974-1980, 2245, 2249-2252, 2266-2268, 2303
api/search_result.py                            50       6  88.00%   33-35, 70, 79, 86, 100
api/product/__init__.py                          5       0  100.00%
api/product/_assets.py                          44       5  88.64%   27-29, 79, 129
api/product/_product.py                        203      32  84.24%   56-63, 67-69, 173-180, 264-265, 347, 376, 437, 451-454, 467, 491-494, 537-543
api/product/metadata_mapping.py                678      83  87.76%   67-69, 131-133, 234, 266-267, 313-314, 324-336, 338, 349, 355-367, 412-413, 450, 471-474, 497, 505-506, 582-583, 607-608, 614-617, 632-633, 782, 828, 1002-1007, 1138, 1152-1172, 1192, 1197, 1307, 1329, 1343, 1356-1375, 1414, 1466, 1504-1508, 1527
api/product/drivers/__init__.py                  5       0  100.00%
api/product/drivers/base.py                      8       2  75.00%   23, 41
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 23       4  82.61%   25, 48, 55, 68
plugins/manager.py                             133      15  88.72%   49-51, 105-110, 156, 197, 219, 223, 248, 287-288
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           99      15  84.85%   46-54, 150-152, 199-200, 226-228
plugins/apis/usgs.py                           175      36  79.43%   60-65, 132, 205, 239, 274-276, 281, 307-308, 313, 343-350, 361-366, 388-394, 396-402, 425
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py              20       2  90.00%   25-27
plugins/authentication/base.py                  19       3  84.21%   26, 34, 47
plugins/authentication/generic.py               16       3  81.25%   28, 40, 50
plugins/authentication/header.py                17       1  94.12%   27
plugins/authentication/keycloak.py              49       6  87.76%   33-35, 132, 156-161
plugins/authentication/oauth.py                 15       8  46.67%   25, 32-34, 38-41
plugins/authentication/openid_connect.py       186      19  89.78%   41-43, 121, 135-160, 168, 322-325, 349
plugins/authentication/qsauth.py                36       2  94.44%   32, 83
plugins/authentication/sas_auth.py              49       2  95.92%   32, 76
plugins/authentication/token.py                 90      17  81.11%   35-37, 79, 107, 109, 131-143, 198-201
plugins/authentication/token_exchange.py        35      19  45.71%   74-80, 92-120
plugins/crunch/__init__.py                       0       0  100.00%
plugins/crunch/base.py                          10       2  80.00%   25, 38
plugins/crunch/filter_date.py                   62      15  75.81%   30, 53-58, 72, 81, 90, 93, 105-107, 116-118, 125
plugins/crunch/filter_latest_intersect.py       50      35  30.00%   32-34, 48-53, 69-114
plugins/crunch/filter_latest_tpl_name.py        33       2  93.94%   28, 86
plugins/crunch/filter_overlap.py                68      17  75.00%   28-30, 33, 82-85, 91, 99, 110-126
plugins/crunch/filter_property.py               33       8  75.76%   29, 60-65, 68-69, 85-89
plugins/download/__init__.py                     0       0  100.00%
plugins/download/aws.py                        492     165  66.46%   77-83, 272, 285, 352-355, 369-373, 419-421, 425, 459-460, 466-470, 503, 538, 542, 549, 579-587, 591, 629-637, 644-646, 687-761, 779-840, 851-856, 872-885, 914, 929-931, 934, 944-952, 960-973, 983-1002, 1009-1021, 1062, 1088, 1133-1135, 1355
plugins/download/base.py                       260      59  77.31%   58-64, 145, 180, 250-252, 319-320, 340-346, 377-381, 387-388, 432, 435-449, 461, 465, 538-542, 572-573, 581-598, 605-613, 615-619, 666, 688, 710, 718
plugins/download/creodias_s3.py                 17       9  47.06%   44-58
plugins/download/http.py                       529     132  75.05%   85-91, 124, 203-213, 215-216, 251-254, 318-321, 323-324, 331-336, 354-369, 386-388, 400, 448, 455-461, 479, 493, 507, 515-517, 533-538, 549, 567, 609-613, 635, 675, 720, 734-740, 776-840, 858, 891-900, 926-927, 954-959, 965, 981, 998-999, 1026-1027, 1034, 1096-1102, 1157-1158, 1164, 1174, 1240, 1244, 1258-1274
plugins/download/s3rest.py                     118      27  77.12%   55-58, 121, 162, 197, 227-234, 237-239, 243, 256-262, 270-271, 274-278, 301, 322-325
plugins/search/__init__.py                      26       3  88.46%   27-31
plugins/search/base.py                         133      18  86.47%   48-53, 104, 108, 121, 271, 291, 350-351, 371, 374-382, 384
plugins/search/build_search_result.py          183      31  83.06%   62, 97, 141-142, 148, 159, 295-298, 327, 384-401, 463, 466, 476, 493, 513-528
plugins/search/creodias_s3.py                   55       3  94.55%   56, 74, 108
plugins/search/csw.py                          108      83  23.15%   44-46, 58-59, 63-64, 72-120, 126-139, 147-179, 197-238
plugins/search/data_request_search.py          198      65  67.17%   53, 90-93, 109, 121, 125-126, 137, 142, 147, 154, 167-170, 224-225, 229, 239-245, 250, 276-279, 287-298, 315, 317, 324-325, 327-328, 346-350, 383, 390, 401, 414, 420-432, 437
plugins/search/qssearch.py                     646      97  84.98%   102, 386, 390-396, 404-405, 512-518, 568, 571, 584, 594, 613-628, 666-669, 744-745, 788, 807, 822, 880, 901, 904-905, 914, 925, 934, 957, 1021-1026, 1030-1031, 1061, 1135, 1184, 1258-1262, 1328-1329, 1350, 1378-1390, 1397, 1429-1431, 1441-1447, 1491, 1506, 1526, 1588-1659
plugins/search/static_stac_search.py            48       3  93.75%   35-36, 78
rest/__init__.py                                 4       2  50.00%   21-22
rest/core.py                                   207      96  53.62%   66-72, 153, 155, 157, 163-164, 185-193, 199-205, 252-306, 319-355, 505-536, 554, 604-643, 684, 691-696
rest/server.py                                 299     299  0.00%    18-883
rest/stac.py                                   474     150  68.35%   63-65, 262, 327, 349, 421, 458-460, 483, 518-519, 605-644, 681-686, 770-774, 808, 816-817, 821-829, 914, 972, 1037-1039, 1056-1058, 1066-1068, 1081-1083, 1097-1114, 1124-1145, 1155-1177, 1185-1202, 1225-1248, 1258, 1268-1280, 1293-1315, 1329-1374, 1527-1553
rest/types/__init__.py                           0       0  100.00%
rest/types/eodag_search.py                     184      18  90.22%   52-55, 235-239, 272-274, 292, 295, 301, 305, 363, 375-378
rest/types/stac_queryables.py                   38       8  78.95%   34, 63-68, 77-78, 140
rest/types/stac_search.py                      121      12  90.08%   48-51, 167, 182-184, 192, 196, 240, 243
rest/utils/__init__.py                          95      31  67.37%   51, 79-85, 105, 108-109, 128-130, 143, 150, 175-183, 190-211
rest/utils/cql_evaluate.py                      48       5  89.58%   69, 76, 90, 97, 105
rest/utils/rfc3339.py                           31       5  83.87%   73-74, 78, 90, 92
types/__init__.py                              110      36  67.27%   53, 66-70, 81-93, 120-122, 129-132, 172, 199, 209-221, 226, 245, 250, 258, 268
types/bbox.py                                   43      19  55.81%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                           9       0  100.00%
types/queryables.py                             81       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 104
types/whoosh.py                                 15       0  100.00%
utils/__init__.py                              501      41  91.82%   84, 89, 110-112, 193-194, 203-230, 233, 247, 329-333, 409-413, 434-436, 518, 533, 571-572, 968-971, 979-980, 1021-1022, 1102, 1204, 1380
utils/constraints.py                           119      37  68.91%   94-103, 144, 149, 153, 164, 190-192, 202, 216-232, 241-252
utils/exceptions.py                             37       2  94.59%   23, 93
utils/import_system.py                          30      20  33.33%   27, 67-81, 93-103
utils/logging.py                                29       1  96.55%   123
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/requests.py                               55      11  80.00%   69, 96, 98, 100, 102, 104, 123, 128-130, 138
utils/rest.py                                   27       1  96.30%   49
utils/stac_reader.py                            91      28  69.23%   55-56, 63-86, 93-95, 99, 141, 155-158
TOTAL                                         9222    2086  77.38%
```

</details>


### Diff against develop

```
Filename      Stmts    Miss  Cover
----------  -------  ------  --------
TOTAL             0       0  +100.00%
```


Results for commit: c3aaeba28f548a25ae18f2f98e1ae1d6014c21c2


_Minimum allowed coverage is `70%`_


:recycle: This comment has been updated with latest results


<!-- Sticky Pull Request Commentartifacts/unit-test-results-python3.12-windows-latest/coverage.xml -->

Patch:
diff --git a/eodag/api/core.py b/eodag/api/core.py
index a2974508..36f31222 100644
--- a/eodag/api/core.py
+++ b/eodag/api/core.py
@@ -2308,6 +2308,10 @@ class EODataAccessGateway:
         providers_queryables: Dict[str, Dict[str, Annotated[Any, FieldInfo]]] = {}
 
         for plugin in self._plugins_manager.get_search_plugins(product_type, provider):
+            if getattr(plugin.config, "need_auth", False) and (
+                auth := self._plugins_manager.get_auth_plugin(plugin.provider)
+            ):
+                plugin.auth = auth.authenticate()
             providers_queryables[plugin.provider] = plugin.list_queryables(
                 filters=kwargs, product_type=product_type
             )
diff --git a/eodag/plugins/download/http.py b/eodag/plugins/download/http.py
index cdc3fba5..e36c5d3a 100644
--- a/eodag/plugins/download/http.py
+++ b/eodag/plugins/download/http.py
@@ -777,7 +777,10 @@ class HTTPDownload(Download):
             raise MisconfiguredError(f"Incompatible auth plugin: {type(auth)}")
 
         # download assets if exist instead of remote_location
-        if len(product.assets) > 0 and not getattr(self.config, "ignore_assets", False):
+        if len(product.assets) > 0 and (
+            not getattr(self.config, "ignore_assets", False)
+            or kwargs.get("asset") is not None
+        ):
             try:
                 assets_values = product.assets.get_values(kwargs.get("asset", None))
                 chunks_tuples = self._stream_download_assets(
diff --git a/eodag/resources/stac.yml b/eodag/resources/stac.yml
index d8895072..18e9ad86 100644
--- a/eodag/resources/stac.yml
+++ b/eodag/resources/stac.yml
@@ -165,7 +165,7 @@ items:
 item:
   stac_version: "{stac_version}"
   stac_extensions:
-  id: '$.product.properties.title'
+  id: '$.product.properties.id'
   bbox:
     - '{item[geometry].bounds[0]}'
     - '{item[geometry].bounds[1]}'
diff --git a/eodag/rest/core.py b/eodag/rest/core.py
index fd33b583..dfca29ad 100644
--- a/eodag/rest/core.py
+++ b/eodag/rest/core.py
@@ -54,7 +54,13 @@ from eodag.rest.utils import (
     get_next_link,
 )
 from eodag.rest.utils.rfc3339 import rfc3339_str_to_datetime
-from eodag.utils import _deprecated, deepcopy, dict_items_recursive_apply, urlencode
+from eodag.utils import (
+    _deprecated,
+    deepcopy,
+    dict_items_recursive_apply,
+    obj_md5sum,
+    urlencode,
+)
 from eodag.utils.exceptions import (
     MisconfiguredError,
     NoMatchingProductType,
@@ -691,6 +697,49 @@ def eodag_api_init() -> None:
     eodag_api.fetch_product_types_list()
     StacCollection.fetch_external_stac_collections(eodag_api)
 
+    # update eodag product_types config form external stac collections
+    for p, p_f in eodag_api.product_types_config.source.items():
+        for key in (p, p_f.get("alias")):
+            if key is None:
+                continue
+            ext_col = StacCollection.ext_stac_collections.get(key)
+            if not ext_col:
+                continue
+            platform: Union[str, List[str]] = ext_col.get("summaries", {}).get(
+                "platform"
+            )
+            constellation: Union[str, List[str]] = ext_col.get("summaries", {}).get(
+                "constellation"
+            )
+            # Check if platform or constellation are lists and join them into a string if they are
+            if isinstance(platform, list):
+                platform = ",".join(platform)
+            if isinstance(constellation, list):
+                constellation = ",".join(constellation)
+
+            update_fields = {
+                "title": ext_col.get("title"),
+                "abstract": ext_col["description"],
+                "keywords": ext_col.get("keywords"),
+                "instrument": ",".join(
+                    ext_col.get("summaries", {}).get("instruments", [])
+                ),
+                "platform": constellation,
+                "platformSerialIdentifier": platform,
+                "processingLevel": ext_col.get("summaries", {}).get("processing:level"),
+                "license": ext_col["license"],
+                "missionStartDate": ext_col["extent"]["temporal"]["interval"][0][0],
+                "missionEndDate": ext_col["extent"]["temporal"]["interval"][-1][1],
+            }
+            clean = {k: v for k, v in update_fields.items() if v}
+            p_f.update(clean)
+
+    eodag_api.product_types_config_md5 = obj_md5sum(
+        eodag_api.product_types_config.source
+    )
+
+    eodag_api.build_index()
+
     # pre-build search plugins
     for provider in eodag_api.available_providers():
         next(eodag_api._plugins_manager.get_search_plugins(provider=provider))
diff --git a/eodag/rest/stac.py b/eodag/rest/stac.py
index 1764ccd9..e0b6ab9e 100644
--- a/eodag/rest/stac.py
+++ b/eodag/rest/stac.py
@@ -201,11 +201,11 @@ class StacCommon:
 
     def get_provider_dict(self, provider: str) -> Dict[str, Any]:
         """Generate STAC provider dict"""
-        provider_config = [
+        provider_config = next(
             p
             for p in self.eodag_api.providers_config.values()
             if provider in [p.name, getattr(p, "group", None)]
-        ][0]
+        )
         return {
             "name": getattr(provider_config, "group", provider_config.name),
             "description": getattr(provider_config, "description", None),
@@ -310,7 +310,7 @@ class StacItem(StacCommon):
 
             # parse download link
             downloadlink_href = (
-                f"{catalog['url']}/items/{product.properties['title']}/download"
+                f"{catalog['url']}/items/{product.properties['id']}/download"
             )
             _dc_qs = product.properties.get("_dc_qs", None)
             url_parts = urlparse(downloadlink_href)
@@ -321,7 +321,8 @@ class StacItem(StacCommon):
                 else f"{url_parts.netloc}{url_parts.path}"
             )
             # add provider to query-args
-            query_dict.update(provider=[product.provider])
+            p_config = self.eodag_api.providers_config[product.provider]
+            query_dict.update(provider=[getattr(p_config, "group", p_config.name)])
             # add datacube query-string to query-args
             if _dc_qs:
                 query_dict.update(_dc_qs=_dc_qs)
@@ -625,7 +626,7 @@ class StacItem(StacCommon):
             item_model,
             {
                 "product": product_dict,
-                "providers": self.get_provider_dict(product.provider),
+                "providers": [self.get_provider_dict(product.provider)],
             },
         )
         # parse f-strings
@@ -735,12 +736,18 @@ class StacCollection(StacCommon):
         """
         providers = self.__list_product_type_providers(product_type)
 
+        providers_dict: Dict[str, Dict[str, Any]] = {}
+        for provider in providers:
+            p_dict = self.get_provider_dict(provider)
+            providers_dict.setdefault(p_dict["name"], p_dict)
+        providers_list = list(providers_dict.values())
+
         # parse jsonpath
         product_type_collection = jsonpath_parse_dict_items(
             collection_model,
             {
                 "product_type": product_type,
-                "providers": [self.get_provider_dict(p) for p in providers],
+                "providers": providers_list,
             },
         )
         # override EODAG's collection with the external collection


Test patch:
diff --git a/tests/units/test_core.py b/tests/units/test_core.py
index 99b3c03c..829572a6 100644
--- a/tests/units/test_core.py
+++ b/tests/units/test_core.py
@@ -1289,6 +1289,10 @@ class TestCore(TestCoreBase):
         # run a 2nd time: check that it does not raise an error
         self.dag.update_providers_config(new_config)
 
+    @mock.patch(
+        "eodag.plugins.manager.PluginManager.get_auth_plugin",
+        autospec=True,
+    )
     @mock.patch(
         "eodag.api.core.EODataAccessGateway.fetch_product_types_list", autospec=True
     )
@@ -1304,6 +1308,7 @@ class TestCore(TestCoreBase):
         mock_stacsearch_discover_queryables: Mock,
         mock_qssearch_discover_queryables: Mock,
         mock_fetch_product_types_list: Mock,
+        mock_auth_plugin: Mock,
     ) -> None:
         """list_queryables must return queryables list adapted to provider and product-type"""
         mock_stacsearch_discover_queryables.return_value = {}
diff --git a/tests/units/test_http_server.py b/tests/units/test_http_server.py
index abd85023..229fe763 100644
--- a/tests/units/test_http_server.py
+++ b/tests/units/test_http_server.py
@@ -1392,9 +1392,7 @@ class RequestTestCase(unittest.TestCase):
 
         self.assertEqual(400, response.status_code)
 
-    @mock.patch(
-        "eodag.plugins.authentication.token.requests.Session.post", autospec=True
-    )
+    @mock.patch("eodag.plugins.manager.PluginManager.get_auth_plugin", autospec=True)
     def test_product_type_queryables(self, mock_requests_session_post):
         """Request to /collections/{collection_id}/queryables should return a valid response."""
 
diff --git a/tests/units/test_stac_core.py b/tests/units/test_stac_core.py
index 90c921a4..0e1d00a1 100644
--- a/tests/units/test_stac_core.py
+++ b/tests/units/test_stac_core.py
@@ -244,9 +244,7 @@ class TestStacCore(unittest.TestCase):
             "downloadLink", "thumbnail" in response["features"][0]["assets"].keys()
         )
         # check that assets from the provider response search are reformatted in the response
-        product_id = self.earth_search_resp_search_json["features"][0]["properties"][
-            "s2:product_uri"
-        ].replace(".SAFE", "")
+        product_id = self.earth_search_resp_search_json["features"][0]["id"]
         for k in self.earth_search_resp_search_json["features"][0]["assets"]:
             self.assertIn(k, response["features"][0]["assets"].keys())
             if k == "thumbnail":