Repository: CS-SI/eodag
Pull request #1070 (2024-03-22 14:05:57)

feat: extend freetext search to all filters
* extend freetext search to all filter fields
* add support for +/- prefixes
* align with STAC advanced free-textsearch extension: https://github.com/stac-api-extensions/freetext-search
* simplify the function
* expose filters in function parameters

kwargs are kept for legacy support

Also, `rmtree` is not used any more to remove product types index before rebuilding it as it is [optional](https://whoosh.readthedocs.io/en/latest/indexing.html#clearing-the-index)


github-actions[bot]: ## Test Results
    4 files  ±0      4 suites  ±0   6m 2s :stopwatch: -1s
  507 tests ±0    504 :white_check_mark: ±0   3 :zzz: ±0  0 :x: ±0 
2 028 runs  ±0  1 942 :white_check_mark: ±0  86 :zzz: ±0  0 :x: ±0 

Results for commit 04505a00. ± Comparison against base commit 80b4fd00.

[test-results]:data:application/gzip;base64,H4sIAEqR/WUC/02MzQ6DIBAGX8Vw7mFZ+bMv01DQhFSlQTiZvnvBCvU48+3OTiY3jxu5d+zWkS252MCmoKPza8ZeYBZ5imXkICs9tmTModhfvdy7/DQxaTdnAU2MIfhwmpDW0kRAdVJt0oFhU7+mElVcmgdfk8Yvi4sZCDAOXAOg1AzxSdEKtNZKJmivNSoFMKh8Qj5ftsU4UggBAAA=

github-actions[bot]: ![badge](https://raw.githubusercontent.com/CS-SI/eodag/_xml_coverage_reports/data/refactor%2Fguess-product-types/./badge.svg)


## Code Coverage (Ubuntu)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                     11       0  100.00%
cli.py                                         300      47  84.33%   61, 647-686, 788-839, 843
config.py                                      313      27  91.37%   80-82, 91, 99, 103-105, 178, 190, 386-388, 452-455, 502-503, 512-513, 592, 661-666, 668
crunch.py                                        6       6  0.00%    18-24
api/__init__.py                                  1       0  100.00%
api/core.py                                    717      76  89.40%   86-95, 368, 579, 623-626, 664, 769, 773-778, 804, 874, 954, 1069-1074, 1160-1172, 1212, 1214, 1218, 1239-1241, 1245-1256, 1269-1275, 1365-1368, 1397-1417, 1465, 1471-1474, 1483, 1834, 1867-1873, 2138, 2142-2145, 2159-2161, 2196
api/search_result.py                            44       6  86.36%   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                        208      32  84.62%   48-55, 59-61, 165-172, 256-257, 347, 383, 444, 458-461, 474, 498-501, 544-550
api/product/metadata_mapping.py                648      87  86.57%   66-68, 129-131, 232, 264-265, 317-329, 331, 342, 346-362, 401-404, 441, 462-465, 479, 487-488, 561-562, 586-587, 593-596, 611-612, 776, 822, 879-880, 923-928, 1059, 1073-1093, 1113, 1118, 1228, 1250, 1264, 1277-1296, 1335, 1387, 1425-1429, 1448
api/product/drivers/__init__.py                  6       0  100.00%
api/product/drivers/base.py                      8       2  75.00%   23, 41
plugins/__init__.py                              1       0  100.00%
plugins/base.py                                 23       3  86.96%   25, 48, 55
plugins/manager.py                             127      14  88.98%   49-51, 95-100, 146, 185, 205, 231, 270-271
plugins/apis/__init__.py                         1       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/cds.py                            206      49  76.21%   72-80, 126-129, 176-188, 244, 309, 317-322, 335-342, 360-362, 383-385, 395-397, 411-412, 457, 460, 470, 487, 515, 517
plugins/apis/ecmwf.py                           99      15  84.85%   47-55, 156-158, 205-206, 232-234
plugins/apis/usgs.py                           168      36  78.57%   58-63, 124, 197, 231, 266-268, 273, 299-300, 305, 335-342, 351-356, 378-384, 386-392, 415
plugins/authentication/__init__.py               7       1  85.71%   31
plugins/authentication/aws_auth.py              20       2  90.00%   25-27
plugins/authentication/base.py                  19       2  89.47%   26, 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              88      17  80.68%   32-34, 159-160, 190-212, 238-243
plugins/authentication/oauth.py                 15       8  46.67%   25, 32-34, 38-41
plugins/authentication/openid_connect.py       103      64  37.86%   39-41, 138-150, 154-172, 180-222, 228-237, 246-286, 291-299, 304-305
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                 75       8  89.33%   35-37, 102, 127, 154-157
plugins/crunch/__init__.py                       1       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                     1       0  100.00%
plugins/download/aws.py                        491     165  66.40%   77-83, 272, 285, 352-355, 369-373, 419-421, 425, 458-459, 465-469, 502, 537, 541, 548, 578-586, 590, 628-636, 643-645, 686-760, 778-839, 850-855, 871-884, 913, 928-930, 933, 943-951, 959-972, 982-1001, 1008-1020, 1061, 1087, 1132-1134, 1354
plugins/download/base.py                       261      57  78.16%   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, 689, 711, 719
plugins/download/creodias_s3.py                 17       9  47.06%   44-58
plugins/download/http.py                       422      97  77.01%   81-88, 122, 171, 192-199, 209-222, 262-267, 318, 351, 378-380, 390-398, 420, 459-463, 520, 593-649, 663, 687-689, 719-720, 728, 731, 747, 771, 794-795, 802, 863-869, 924-925, 931, 941, 1007, 1025-1041
plugins/download/s3rest.py                     117      27  76.92%   55-58, 124, 165, 199, 229-236, 239-241, 245, 258-264, 272-273, 276-280, 303, 324-327
plugins/search/__init__.py                       1       0  100.00%
plugins/search/base.py                         127       9  92.91%   49-54, 108, 112, 275, 295, 378
plugins/search/build_search_result.py           56       6  89.29%   67, 112-113, 121, 132, 176
plugins/search/creodias_s3.py                   55       3  94.55%   56, 74, 108
plugins/search/csw.py                          107      83  22.43%   43-45, 57-58, 62-63, 74-122, 128-141, 149-181, 199-240
plugins/search/data_request_search.py          198      60  69.70%   52, 89-92, 108, 120, 139, 144, 149, 156, 169-172, 226-227, 231, 241-247, 252, 281, 291-302, 319, 321, 328-329, 331-332, 350-354, 387, 394, 405, 418, 424-436, 441
plugins/search/qssearch.py                     521      53  89.83%   87, 354-355, 449-455, 482-485, 558-559, 600, 618, 633, 686, 707, 710-711, 720, 731, 740, 763, 823-828, 832-833, 861, 932, 951-968, 1007, 1141-1142, 1163, 1205-1206, 1216-1222, 1263, 1277, 1297, 1385
plugins/search/static_stac_search.py            47       3  93.62%   39-40, 82
rest/__init__.py                                 1       0  100.00%
rest/core.py                                   169      10  94.08%   243, 514, 516, 519-521, 593, 600-604
rest/server.py                                 298      54  81.88%   80-81, 105, 128-129, 240-242, 258, 298-299, 311-327, 409-414, 444, 601-608, 639, 682-683, 771-773, 790-795, 825, 827, 831-832, 836-837
rest/stac.py                                   436      95  78.21%   59-61, 229-231, 273, 286-295, 314-320, 365, 402-404, 427, 462-463, 549-594, 639, 659-660, 840, 905-907, 1126, 1136-1148, 1161-1183, 1197-1242, 1401-1402
rest/types/__init__.py                           1       0  100.00%
rest/types/eodag_search.py                     185       9  95.14%   52-55, 231-235, 288, 291, 359
rest/types/stac_queryables.py                   30       2  93.33%   28, 114
rest/types/stac_search.py                      122      10  91.80%   48-51, 167, 182-184, 192, 196
rest/utils/__init__.py                         116      14  87.93%   53, 108-109, 128-130, 180, 190-204, 236
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                               76       6  92.11%   53, 87, 152, 172, 177, 185
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                                 14       0  100.00%
utils/__init__.py                              495      43  91.31%   83, 88, 109-111, 189-190, 199-226, 229, 243, 325-329, 405-409, 430-432, 514, 519, 529, 567-568, 964-967, 975-976, 1017-1018, 1098, 1182, 1200, 1373
utils/constraints.py                           123      42  65.85%   31, 84-93, 134, 139, 143, 154, 177-178, 189-197, 206, 220-236, 245-256
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/stac_reader.py                            91      28  69.23%   55-56, 63-86, 93-95, 99, 141, 155-158
TOTAL                                         8642    1545  82.12%
```

</details>


### Diff against develop

```
Filename           Stmts    Miss  Cover
---------------  -------  ------  --------
api/core.py           -4       0  -0.06%
types/whoosh.py      +14       0  +100.00%
TOTAL                +10       0  +0.02%
```


Results for commit: 04505a0027a422b12d62ddd74613aa2880098505


_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/refactor%2Fguess-product-types/./badge.svg)


## Code Coverage (Windows)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                     11       0  100.00%
cli.py                                         300      47  84.33%   61, 647-686, 788-839, 843
config.py                                      313      28  91.05%   80-82, 91, 99, 103-105, 178, 190, 386-388, 452-455, 502-503, 512-513, 592, 626, 661-666, 668
crunch.py                                        6       6  0.00%    18-24
api/__init__.py                                  1       0  100.00%
api/core.py                                    717      76  89.40%   86-95, 368, 579, 623-626, 664, 769, 773-778, 804, 874, 954, 1069-1074, 1160-1172, 1212, 1214, 1218, 1239-1241, 1245-1256, 1269-1275, 1365-1368, 1397-1417, 1465, 1471-1474, 1483, 1834, 1867-1873, 2138, 2142-2145, 2159-2161, 2196
api/search_result.py                            44       6  86.36%   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                        208      32  84.62%   48-55, 59-61, 165-172, 256-257, 347, 383, 444, 458-461, 474, 498-501, 544-550
api/product/metadata_mapping.py                648      88  86.42%   66-68, 129-131, 232, 264-265, 317-329, 331, 342, 346-362, 401-404, 441, 462-465, 479, 487-488, 561-562, 586-587, 593-596, 611-612, 776, 822, 879-880, 923-928, 1059, 1073-1093, 1113, 1118, 1228, 1250, 1264, 1277-1296, 1335, 1387, 1410, 1425-1429, 1448
api/product/drivers/__init__.py                  6       0  100.00%
api/product/drivers/base.py                      8       2  75.00%   23, 41
plugins/__init__.py                              1       0  100.00%
plugins/base.py                                 23       4  82.61%   25, 48, 55, 68
plugins/manager.py                             127      14  88.98%   49-51, 95-100, 146, 185, 205, 231, 270-271
plugins/apis/__init__.py                         1       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/cds.py                            206      56  72.82%   72-80, 126-129, 176-188, 244, 309, 317-322, 335-342, 360-362, 383-385, 395-397, 411-412, 457, 460, 470, 487, 507-522
plugins/apis/ecmwf.py                           99      15  84.85%   47-55, 156-158, 205-206, 232-234
plugins/apis/usgs.py                           168      36  78.57%   58-63, 124, 197, 231, 266-268, 273, 299-300, 305, 335-342, 351-356, 378-384, 386-392, 415
plugins/authentication/__init__.py               7       1  85.71%   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              88      17  80.68%   32-34, 159-160, 190-212, 238-243
plugins/authentication/oauth.py                 15       8  46.67%   25, 32-34, 38-41
plugins/authentication/openid_connect.py       103      64  37.86%   39-41, 138-150, 154-172, 180-222, 228-237, 246-286, 291-299, 304-305
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                 75       8  89.33%   35-37, 102, 127, 154-157
plugins/crunch/__init__.py                       1       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                     1       0  100.00%
plugins/download/aws.py                        491     165  66.40%   77-83, 272, 285, 352-355, 369-373, 419-421, 425, 458-459, 465-469, 502, 537, 541, 548, 578-586, 590, 628-636, 643-645, 686-760, 778-839, 850-855, 871-884, 913, 928-930, 933, 943-951, 959-972, 982-1001, 1008-1020, 1061, 1087, 1132-1134, 1354
plugins/download/base.py                       261      59  77.39%   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, 689, 711, 719
plugins/download/creodias_s3.py                 17       9  47.06%   44-58
plugins/download/http.py                       422      97  77.01%   81-88, 122, 171, 192-199, 209-222, 262-267, 318, 351, 378-380, 390-398, 420, 459-463, 520, 593-649, 663, 687-689, 719-720, 728, 731, 747, 771, 794-795, 802, 863-869, 924-925, 931, 941, 1007, 1025-1041
plugins/download/s3rest.py                     117      27  76.92%   55-58, 124, 165, 199, 229-236, 239-241, 245, 258-264, 272-273, 276-280, 303, 324-327
plugins/search/__init__.py                       1       0  100.00%
plugins/search/base.py                         127       9  92.91%   49-54, 108, 112, 275, 295, 378
plugins/search/build_search_result.py           56       6  89.29%   67, 112-113, 121, 132, 176
plugins/search/creodias_s3.py                   55       3  94.55%   56, 74, 108
plugins/search/csw.py                          107      83  22.43%   43-45, 57-58, 62-63, 74-122, 128-141, 149-181, 199-240
plugins/search/data_request_search.py          198      60  69.70%   52, 89-92, 108, 120, 139, 144, 149, 156, 169-172, 226-227, 231, 241-247, 252, 281, 291-302, 319, 321, 328-329, 331-332, 350-354, 387, 394, 405, 418, 424-436, 441
plugins/search/qssearch.py                     521      77  85.22%   87, 354-355, 449-455, 482-485, 558-559, 600, 618, 633, 686, 707, 710-711, 720, 731, 740, 763, 823-828, 832-833, 861, 932, 951-968, 1007, 1141-1142, 1163, 1205-1206, 1216-1222, 1263, 1277, 1297, 1345-1414
plugins/search/static_stac_search.py            47       3  93.62%   39-40, 82
rest/__init__.py                                 1       0  100.00%
rest/core.py                                   169      61  63.91%   140, 142, 144, 150-151, 168-176, 183-189, 235-264, 418-445, 463, 513-552, 593, 600-604
rest/server.py                                 298     298  0.00%    18-850
rest/stac.py                                   436     154  64.68%   59-61, 214, 229-231, 273, 286-295, 314-320, 365, 402-404, 427, 462-463, 549-594, 639, 647-648, 652-660, 782, 840, 905-907, 924-926, 934-936, 949-951, 965-982, 992-1013, 1023-1045, 1053-1070, 1093-1116, 1126, 1136-1148, 1161-1183, 1197-1242, 1395-1421
rest/types/__init__.py                           1       0  100.00%
rest/types/eodag_search.py                     185      18  90.27%   52-55, 231-235, 268-270, 288, 291, 297, 301, 359, 371-374
rest/types/stac_queryables.py                   30       6  80.00%   28, 53-58, 114
rest/types/stac_search.py                      122      12  90.16%   48-51, 167, 182-184, 192, 196, 240, 243
rest/utils/__init__.py                         116      31  73.28%   53, 79-85, 105, 108-109, 128-130, 147, 173-181, 188-209, 236
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                               76      11  85.53%   53, 87, 125, 152, 162-164, 172, 177, 185, 195
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                                 14       0  100.00%
utils/__init__.py                              495      43  91.31%   83, 88, 109-111, 189-190, 199-226, 229, 243, 325-329, 405-409, 430-432, 514, 519, 529, 567-568, 964-967, 975-976, 1017-1018, 1098, 1182, 1200, 1373
utils/constraints.py                           123      42  65.85%   31, 84-93, 134, 139, 143, 154, 177-178, 189-197, 206, 220-236, 245-256
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/stac_reader.py                            91      28  69.23%   55-56, 63-86, 93-95, 99, 141, 155-158
TOTAL                                         8642    2000  76.86%
```

</details>


### Diff against develop

```
Filename           Stmts    Miss  Cover
---------------  -------  ------  --------
api/core.py           -4       0  -0.06%
types/whoosh.py      +14       0  +100.00%
TOTAL                +10       0  +0.03%
```


Results for commit: 04505a0027a422b12d62ddd74613aa2880098505


_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/docs/notebooks/api_user_guide/4_search.ipynb b/docs/notebooks/api_user_guide/4_search.ipynb
index 412cd306..8b34b695 100644
--- a/docs/notebooks/api_user_guide/4_search.ipynb
+++ b/docs/notebooks/api_user_guide/4_search.ipynb
@@ -26,15 +26,22 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 2,
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-19 12:00:29,455 eodag.config                     [INFO    ] Loading user configuration from: /home/sylvain/.config/eodag/eodag.yml\n",
-      "2024-02-19 12:00:29,545 eodag.core                       [INFO    ] Locations configuration loaded from /home/sylvain/.config/eodag/locations.yml\n"
+      "2024-03-27 18:19:20,816 eodag.config                     [INFO    ] Loading user configuration from: /home/aubin/.config/eodag/eodag.yml\n",
+      "2024-03-27 18:19:20,830 eodag.core                       [INFO    ] usgs: provider needing auth for search has been pruned because no crendentials could be found\n",
+      "2024-03-27 18:19:20,831 eodag.core                       [INFO    ] aws_eos: provider needing auth for search has been pruned because no crendentials could be found\n",
+      "2024-03-27 18:19:20,832 eodag.core                       [INFO    ] meteoblue: provider needing auth for search has been pruned because no crendentials could be found\n",
+      "2024-03-27 18:19:20,832 eodag.core                       [INFO    ] hydroweb_next: provider needing auth for search has been pruned because no crendentials could be found\n",
+      "2024-03-27 18:19:20,833 eodag.core                       [INFO    ] wekeo: provider needing auth for search has been pruned because no crendentials could be found\n",
+      "2024-03-27 18:19:20,834 eodag.core                       [INFO    ] wekeo_cmems: provider needing auth for search has been pruned because no crendentials could be found\n",
+      "2024-03-27 18:19:20,835 eodag.core                       [INFO    ] creodias_s3: provider needing auth for search has been pruned because no crendentials could be found\n",
+      "2024-03-27 18:19:20,840 eodag.core                       [INFO    ] Locations configuration loaded from /home/aubin/.config/eodag/locations.yml\n"
      ]
     }
    ],
@@ -57,7 +64,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 4,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -139,22 +146,22 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 5,
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-06 16:11:46,094 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
-      "2024-02-06 16:11:46,097 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n"
+      "2024-03-27 18:19:44,780 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
+      "2024-03-27 18:19:44,881 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n"
      ]
     },
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-06 16:11:48,189 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
+      "2024-03-27 18:19:47,808 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
      ]
     }
    ],
@@ -164,14 +171,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 22,
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Got a hand on 20 products and an estimated total number of 48 products available.\n"
+      "Got a hand on 20 products and an estimated total number of 96 products available.\n"
      ]
     }
    ],
@@ -181,16 +188,16 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-06 16:11:48,220 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
-      "2024-02-06 16:11:48,224 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=10&page=2\n",
-      "2024-02-06 16:11:49,625 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
+      "2024-03-27 18:20:01,526 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
+      "2024-03-27 18:20:01,611 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=10&page=2\n",
+      "2024-03-27 18:20:02,461 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
      ]
     }
    ],
@@ -200,14 +207,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 24,
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Got a hand on 10 products and an estimated total number of 48 products available.\n"
+      "Got a hand on 10 products and an estimated total number of 96 products available.\n"
      ]
     }
    ],
@@ -242,7 +249,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 25,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -252,44 +259,53 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 26,
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-06 16:11:49,661 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
-      "2024-02-06 16:11:49,663 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
-      "2024-02-06 16:11:50,430 eodag.search.qssearch            [ERROR   ] Skipping error while searching for peps QueryStringSearch instance: \n",
+      "2024-03-26 23:11:38,857 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
+      "2024-03-26 23:11:38,859 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "2024-03-26 23:11:41,560 eodag.search.qssearch            [ERROR   ] Skipping error while searching for peps QueryStringSearch instance: \n",
       "Traceback (most recent call last):\n",
-      "  File \"/home/anesson/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py\", line 908, in _request\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py\", line 924, in _request\n",
       "    response.raise_for_status()\n",
-      "  File \"/home/anesson/.virtualenvs/eodag_docs/lib/python3.8/site-packages/requests/models.py\", line 1021, in raise_for_status\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/requests/models.py\", line 1021, in raise_for_status\n",
       "    raise HTTPError(http_error_msg, response=self)\n",
       "requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON%20((1.0000%2043.0000,%201.0000%2044.0000,%202.0000%2044.0000,%202.0000%2043.0000,%201.0000%2043.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
-      "2024-02-06 16:11:50,433 eodag.core                       [INFO    ] No result from provider 'peps' due to an error during search. Raise verbosity of log messages for details\n",
-      "2024-02-06 16:11:50,434 eodag.core                       [ERROR   ] Error while searching on provider peps (ignored):\n",
+      "2024-03-26 23:11:41,564 eodag.core                       [INFO    ] No result from provider 'peps' due to an error during search. Raise verbosity of log messages for details\n",
+      "2024-03-26 23:11:41,564 eodag.core                       [ERROR   ] Error while searching on provider peps (ignored):\n",
       "Traceback (most recent call last):\n",
-      "  File \"/home/anesson/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py\", line 908, in _request\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py\", line 924, in _request\n",
       "    response.raise_for_status()\n",
-      "  File \"/home/anesson/.virtualenvs/eodag_docs/lib/python3.8/site-packages/requests/models.py\", line 1021, in raise_for_status\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/requests/models.py\", line 1021, in raise_for_status\n",
       "    raise HTTPError(http_error_msg, response=self)\n",
       "requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON%20((1.0000%2043.0000,%201.0000%2044.0000,%202.0000%2044.0000,%202.0000%2043.0000,%201.0000%2043.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
       "\n",
       "During handling of the above exception, another exception occurred:\n",
       "\n",
       "Traceback (most recent call last):\n",
-      "  File \"/home/anesson/workspace/EODAG/dev/eodag/eodag/api/core.py\", line 1685, in _do_search\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/eodag/api/core.py\", line 1717, in _do_search\n",
       "    res, nb_res = search_plugin.query(count=count, auth=auth_plugin, **kwargs)\n",
-      "  File \"/home/anesson/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py\", line 541, in query\n",
+      "                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py\", line 545, in query\n",
       "    provider_results = self.do_search(items_per_page=items_per_page, **kwargs)\n",
-      "  File \"/home/anesson/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py\", line 650, in do_search\n",
+      "                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py\", line 658, in do_search\n",
       "    response = self._request(\n",
-      "  File \"/home/anesson/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py\", line 923, in _request\n",
+      "               ^^^^^^^^^^^^^^\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py\", line 939, in _request\n",
       "    raise RequestError(str(err))\n",
       "eodag.utils.exceptions.RequestError: 400 Client Error: Bad Request for url: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON%20((1.0000%2043.0000,%201.0000%2044.0000,%202.0000%2044.0000,%202.0000%2043.0000,%201.0000%2043.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
-      "2024-02-06 16:11:50,437 eodag.core                       [ERROR   ] No result could be obtained from any available provider\n"
+      "2024-03-26 23:11:41,566 eodag.core                       [ERROR   ] No result could be obtained from any available provider\n"
      ]
     }
    ],
@@ -299,7 +315,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 27,
    "metadata": {},
    "outputs": [
     {
@@ -324,23 +340,23 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 28,
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-06 16:11:50,460 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
-      "2024-02-06 16:11:50,465 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
-      "2024-02-06 16:11:51,058 eodag.search.qssearch            [ERROR   ] Skipping error while searching for peps QueryStringSearch instance: \n",
+      "2024-03-26 23:11:41,607 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
+      "2024-03-26 23:11:41,609 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
+      "2024-03-26 23:11:42,039 eodag.search.qssearch            [ERROR   ] Skipping error while searching for peps QueryStringSearch instance: \n",
       "Traceback (most recent call last):\n",
-      "  File \"/home/anesson/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py\", line 908, in _request\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py\", line 924, in _request\n",
       "    response.raise_for_status()\n",
-      "  File \"/home/anesson/.virtualenvs/eodag_docs/lib/python3.8/site-packages/requests/models.py\", line 1021, in raise_for_status\n",
+      "  File \"/home/aubin/cs/eodag/.venv/lib/python3.12/site-packages/requests/models.py\", line 1021, in raise_for_status\n",
       "    raise HTTPError(http_error_msg, response=self)\n",
       "requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON%20((1.0000%2043.0000,%201.0000%2044.0000,%202.0000%2044.0000,%202.0000%2043.0000,%201.0000%2043.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
-      "2024-02-06 16:11:51,059 eodag.core                       [INFO    ] No result from provider 'peps' due to an error during search.\n"
+      "2024-03-26 23:11:42,040 eodag.core                       [INFO    ] No result from provider 'peps' due to an error during search.\n"
      ]
     },
     {
@@ -350,17 +366,17 @@
      "traceback": [
       "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
       "\u001b[0;31mHTTPError\u001b[0m                                 Traceback (most recent call last)",
-      "File \u001b[0;32m~/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py:908\u001b[0m, in \u001b[0;36mQueryStringSearch._request\u001b[0;34m(self, url, info_message, exception_message)\u001b[0m\n\u001b[1;32m    905\u001b[0m         response \u001b[38;5;241m=\u001b[39m requests\u001b[38;5;241m.\u001b[39mget(\n\u001b[1;32m    906\u001b[0m             url, timeout\u001b[38;5;241m=\u001b[39mtimeout, headers\u001b[38;5;241m=\u001b[39mUSER_AGENT, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[1;32m    907\u001b[0m         )\n\u001b[0;32m--> 908\u001b[0m         \u001b[43mresponse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mraise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    909\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m requests\u001b[38;5;241m.\u001b[39mexceptions\u001b[38;5;241m.\u001b[39mTimeout \u001b[38;5;28;01mas\u001b[39;00m exc:\n",
-      "File \u001b[0;32m~/.virtualenvs/eodag_docs/lib/python3.8/site-packages/requests/models.py:1021\u001b[0m, in \u001b[0;36mResponse.raise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1020\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m http_error_msg:\n\u001b[0;32m-> 1021\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m HTTPError(http_error_msg, response\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m)\n",
+      "File \u001b[0;32m~/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py:924\u001b[0m, in \u001b[0;36mQueryStringSearch._request\u001b[0;34m(self, url, info_message, exception_message)\u001b[0m\n\u001b[1;32m    917\u001b[0m         response \u001b[38;5;241m=\u001b[39m requests\u001b[38;5;241m.\u001b[39mget(\n\u001b[1;32m    918\u001b[0m             url,\n\u001b[1;32m    919\u001b[0m             timeout\u001b[38;5;241m=\u001b[39mtimeout,\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    922\u001b[0m             \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[1;32m    923\u001b[0m         )\n\u001b[0;32m--> 924\u001b[0m         \u001b[43mresponse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mraise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    925\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m requests\u001b[38;5;241m.\u001b[39mexceptions\u001b[38;5;241m.\u001b[39mTimeout \u001b[38;5;28;01mas\u001b[39;00m exc:\n",
+      "File \u001b[0;32m~/cs/eodag/.venv/lib/python3.12/site-packages/requests/models.py:1021\u001b[0m, in \u001b[0;36mResponse.raise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1020\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m http_error_msg:\n\u001b[0;32m-> 1021\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m HTTPError(http_error_msg, response\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m)\n",
       "\u001b[0;31mHTTPError\u001b[0m: 400 Client Error: Bad Request for url: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON%20((1.0000%2043.0000,%201.0000%2044.0000,%202.0000%2044.0000,%202.0000%2043.0000,%201.0000%2043.0000))&productType=S2MSI1C&maxRecords=20&page=1",
       "\nDuring handling of the above exception, another exception occurred:\n",
       "\u001b[0;31mRequestError\u001b[0m                              Traceback (most recent call last)",
-      "Cell \u001b[0;32mIn [10], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m products_first_page, estimated_total_number \u001b[38;5;241m=\u001b[39m \u001b[43mdag\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msearch\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mbad_search_criteria\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mraise_errors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n",
-      "File \u001b[0;32m~/workspace/EODAG/dev/eodag/eodag/api/core.py:1056\u001b[0m, in \u001b[0;36mEODataAccessGateway.search\u001b[0;34m(self, page, items_per_page, raise_errors, start, end, geom, locations, provider, **kwargs)\u001b[0m\n\u001b[1;32m   1054\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i, search_plugin \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(search_plugins):\n\u001b[1;32m   1055\u001b[0m     search_plugin\u001b[38;5;241m.\u001b[39mclear()\n\u001b[0;32m-> 1056\u001b[0m     search_results, total_results \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_do_search\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1057\u001b[0m \u001b[43m        \u001b[49m\u001b[43msearch_plugin\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1058\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcount\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m   1059\u001b[0m \u001b[43m        \u001b[49m\u001b[43mraise_errors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mraise_errors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1060\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43msearch_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1061\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1062\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(search_results) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m i \u001b[38;5;241m<\u001b[39m \u001b[38;5;28mlen\u001b[39m(search_plugins) \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m   1063\u001b[0m         logger\u001b[38;5;241m.\u001b[39mwarning(\n\u001b[1;32m   1064\u001b[0m             \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNo result could be obtained from provider \u001b[39m\u001b[38;5;132;01m{\u001b[39;00msearch_plugin\u001b[38;5;241m.\u001b[39mprovider\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m   1065\u001b[0m             \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mwe will try to get the data from another provider\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m   1066\u001b[0m         )\n",
-      "File \u001b[0;32m~/workspace/EODAG/dev/eodag/eodag/api/core.py:1685\u001b[0m, in \u001b[0;36mEODataAccessGateway._do_search\u001b[0;34m(self, search_plugin, count, raise_errors, **kwargs)\u001b[0m\n\u001b[1;32m   1682\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m need_auth \u001b[38;5;129;01mand\u001b[39;00m auth_plugin \u001b[38;5;129;01mand\u001b[39;00m can_authenticate:\n\u001b[1;32m   1683\u001b[0m     search_plugin\u001b[38;5;241m.\u001b[39mauth \u001b[38;5;241m=\u001b[39m auth_plugin\u001b[38;5;241m.\u001b[39mauthenticate()\n\u001b[0;32m-> 1685\u001b[0m res, nb_res \u001b[38;5;241m=\u001b[39m \u001b[43msearch_plugin\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mquery\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcount\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcount\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mauth\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mauth_plugin\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1687\u001b[0m \u001b[38;5;66;03m# Only do the pagination computations when it makes sense. For example,\u001b[39;00m\n\u001b[1;32m   1688\u001b[0m \u001b[38;5;66;03m# for a search by id, we can reasonably guess that the provider will return\u001b[39;00m\n\u001b[1;32m   1689\u001b[0m \u001b[38;5;66;03m# At most 1 product, so we don't need such a thing as pagination\u001b[39;00m\n\u001b[1;32m   1690\u001b[0m page \u001b[38;5;241m=\u001b[39m kwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpage\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
-      "File \u001b[0;32m~/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py:541\u001b[0m, in \u001b[0;36mQueryStringSearch.query\u001b[0;34m(self, product_type, items_per_page, page, count, **kwargs)\u001b[0m\n\u001b[1;32m    538\u001b[0m     \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtotal_items_nb\n\u001b[1;32m    539\u001b[0m     \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mneed_count\n\u001b[0;32m--> 541\u001b[0m provider_results \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdo_search\u001b[49m\u001b[43m(\u001b[49m\u001b[43mitems_per_page\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mitems_per_page\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    542\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m count \u001b[38;5;129;01mand\u001b[39;00m total_items \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtotal_items_nb\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[1;32m    543\u001b[0m     total_items \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtotal_items_nb\n",
-      "File \u001b[0;32m~/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py:650\u001b[0m, in \u001b[0;36mQueryStringSearch.do_search\u001b[0;34m(self, items_per_page, **kwargs)\u001b[0m\n\u001b[1;32m    648\u001b[0m results: List[Any] \u001b[38;5;241m=\u001b[39m []\n\u001b[1;32m    649\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m search_url \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msearch_urls:\n\u001b[0;32m--> 650\u001b[0m     response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    651\u001b[0m \u001b[43m        \u001b[49m\u001b[43msearch_url\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    652\u001b[0m \u001b[43m        \u001b[49m\u001b[43minfo_message\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mSending search request: \u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mformat\u001b[49m\u001b[43m(\u001b[49m\u001b[43msearch_url\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    653\u001b[0m \u001b[43m        \u001b[49m\u001b[43mexception_message\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mSkipping error while searching for \u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m \u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m    654\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43minstance:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mformat\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mprovider\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;18;43m__class__\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;18;43m__name__\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    655\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    656\u001b[0m     next_page_url_key_path \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39mpagination\u001b[38;5;241m.\u001b[39mget(\n\u001b[1;32m    657\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnext_page_url_key_path\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m    658\u001b[0m     )\n\u001b[1;32m    659\u001b[0m     next_page_query_obj_key_path \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39mpagination\u001b[38;5;241m.\u001b[39mget(\n\u001b[1;32m    660\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnext_page_query_obj_key_path\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m    661\u001b[0m     )\n",
-      "File \u001b[0;32m~/workspace/EODAG/dev/eodag/eodag/plugins/search/qssearch.py:923\u001b[0m, in \u001b[0;36mQueryStringSearch._request\u001b[0;34m(self, url, info_message, exception_message)\u001b[0m\n\u001b[1;32m    915\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    916\u001b[0m         logger\u001b[38;5;241m.\u001b[39mexception(\n\u001b[1;32m    917\u001b[0m             \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSkipping error while requesting: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m (provider:\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m, plugin:\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m): \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m    918\u001b[0m             url,\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    921\u001b[0m             err_msg,\n\u001b[1;32m    922\u001b[0m         )\n\u001b[0;32m--> 923\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m RequestError(\u001b[38;5;28mstr\u001b[39m(err))\n\u001b[1;32m    924\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\n",
+      "Cell \u001b[0;32mIn[28], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m products_first_page, estimated_total_number \u001b[38;5;241m=\u001b[39m \u001b[43mdag\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msearch\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mbad_search_criteria\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mraise_errors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n",
+      "File \u001b[0;32m~/cs/eodag/.venv/lib/python3.12/site-packages/eodag/api/core.py:1089\u001b[0m, in \u001b[0;36mEODataAccessGateway.search\u001b[0;34m(self, page, items_per_page, raise_errors, start, end, geom, locations, provider, **kwargs)\u001b[0m\n\u001b[1;32m   1087\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i, search_plugin \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(search_plugins):\n\u001b[1;32m   1088\u001b[0m     search_plugin\u001b[38;5;241m.\u001b[39mclear()\n\u001b[0;32m-> 1089\u001b[0m     search_results, total_results \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_do_search\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1090\u001b[0m \u001b[43m        \u001b[49m\u001b[43msearch_plugin\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1091\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcount\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m   1092\u001b[0m \u001b[43m        \u001b[49m\u001b[43mraise_errors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mraise_errors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1093\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43msearch_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1094\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1095\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(search_results) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m i \u001b[38;5;241m<\u001b[39m \u001b[38;5;28mlen\u001b[39m(search_plugins) \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m   1096\u001b[0m         logger\u001b[38;5;241m.\u001b[39mwarning(\n\u001b[1;32m   1097\u001b[0m             \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNo result could be obtained from provider \u001b[39m\u001b[38;5;132;01m{\u001b[39;00msearch_plugin\u001b[38;5;241m.\u001b[39mprovider\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m   1098\u001b[0m             \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mwe will try to get the data from another provider\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m   1099\u001b[0m         )\n",
+      "File \u001b[0;32m~/cs/eodag/.venv/lib/python3.12/site-packages/eodag/api/core.py:1717\u001b[0m, in \u001b[0;36mEODataAccessGateway._do_search\u001b[0;34m(self, search_plugin, count, raise_errors, **kwargs)\u001b[0m\n\u001b[1;32m   1714\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m need_auth \u001b[38;5;129;01mand\u001b[39;00m auth_plugin \u001b[38;5;129;01mand\u001b[39;00m can_authenticate:\n\u001b[1;32m   1715\u001b[0m     search_plugin\u001b[38;5;241m.\u001b[39mauth \u001b[38;5;241m=\u001b[39m auth_plugin\u001b[38;5;241m.\u001b[39mauthenticate()\n\u001b[0;32m-> 1717\u001b[0m res, nb_res \u001b[38;5;241m=\u001b[39m \u001b[43msearch_plugin\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mquery\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcount\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcount\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mauth\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mauth_plugin\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1719\u001b[0m \u001b[38;5;66;03m# Only do the pagination computations when it makes sense. For example,\u001b[39;00m\n\u001b[1;32m   1720\u001b[0m \u001b[38;5;66;03m# for a search by id, we can reasonably guess that the provider will return\u001b[39;00m\n\u001b[1;32m   1721\u001b[0m \u001b[38;5;66;03m# At most 1 product, so we don't need such a thing as pagination\u001b[39;00m\n\u001b[1;32m   1722\u001b[0m page \u001b[38;5;241m=\u001b[39m kwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpage\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
+      "File \u001b[0;32m~/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py:545\u001b[0m, in \u001b[0;36mQueryStringSearch.query\u001b[0;34m(self, product_type, items_per_page, page, count, **kwargs)\u001b[0m\n\u001b[1;32m    542\u001b[0m     \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtotal_items_nb\n\u001b[1;32m    543\u001b[0m     \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mneed_count\n\u001b[0;32m--> 545\u001b[0m provider_results \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdo_search\u001b[49m\u001b[43m(\u001b[49m\u001b[43mitems_per_page\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mitems_per_page\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    546\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m count \u001b[38;5;129;01mand\u001b[39;00m total_items \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtotal_items_nb\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[1;32m    547\u001b[0m     total_items \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtotal_items_nb\n",
+      "File \u001b[0;32m~/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py:658\u001b[0m, in \u001b[0;36mQueryStringSearch.do_search\u001b[0;34m(self, items_per_page, **kwargs)\u001b[0m\n\u001b[1;32m    656\u001b[0m results: List[Any] \u001b[38;5;241m=\u001b[39m []\n\u001b[1;32m    657\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m search_url \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msearch_urls:\n\u001b[0;32m--> 658\u001b[0m     response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    659\u001b[0m \u001b[43m        \u001b[49m\u001b[43msearch_url\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    660\u001b[0m \u001b[43m        \u001b[49m\u001b[43minfo_message\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mSending search request: \u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mformat\u001b[49m\u001b[43m(\u001b[49m\u001b[43msearch_url\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    661\u001b[0m \u001b[43m        \u001b[49m\u001b[43mexception_message\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mSkipping error while searching for \u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m \u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m    662\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43minstance:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mformat\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mprovider\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;18;43m__class__\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;18;43m__name__\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    663\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    664\u001b[0m     next_page_url_key_path \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39mpagination\u001b[38;5;241m.\u001b[39mget(\n\u001b[1;32m    665\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnext_page_url_key_path\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m    666\u001b[0m     )\n\u001b[1;32m    667\u001b[0m     next_page_query_obj_key_path \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39mpagination\u001b[38;5;241m.\u001b[39mget(\n\u001b[1;32m    668\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnext_page_query_obj_key_path\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m    669\u001b[0m     )\n",
+      "File \u001b[0;32m~/cs/eodag/.venv/lib/python3.12/site-packages/eodag/plugins/search/qssearch.py:939\u001b[0m, in \u001b[0;36mQueryStringSearch._request\u001b[0;34m(self, url, info_message, exception_message)\u001b[0m\n\u001b[1;32m    931\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    932\u001b[0m         logger\u001b[38;5;241m.\u001b[39mexception(\n\u001b[1;32m    933\u001b[0m             \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSkipping error while requesting: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m (provider:\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m, plugin:\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m): \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m    934\u001b[0m             url,\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    937\u001b[0m             err_msg,\n\u001b[1;32m    938\u001b[0m         )\n\u001b[0;32m--> 939\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m RequestError(\u001b[38;5;28mstr\u001b[39m(err))\n\u001b[1;32m    940\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\n",
       "\u001b[0;31mRequestError\u001b[0m: 400 Client Error: Bad Request for url: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=malformed_start_date&completionDate=2021-03-31&geometry=POLYGON%20((1.0000%2043.0000,%201.0000%2044.0000,%202.0000%2044.0000,%202.0000%2043.0000,%201.0000%2043.0000))&productType=S2MSI1C&maxRecords=20&page=1"
      ]
     }
@@ -393,17 +409,17 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-06 16:12:45,983 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
-      "2024-02-06 16:12:45,987 eodag.core                       [INFO    ] Iterate search over multiple pages: page #1\n",
-      "2024-02-06 16:12:45,989 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=500&page=1\n",
-      "2024-02-06 16:12:50,782 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
+      "2024-03-26 22:50:32,835 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
+      "2024-03-26 22:50:32,836 eodag.core                       [INFO    ] Iterate search over multiple pages: page #1\n",
+      "2024-03-26 22:50:32,838 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=500&page=1\n",
+      "2024-03-26 22:50:37,157 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
      ]
     }
    ],
@@ -413,7 +429,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -438,7 +454,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -486,7 +502,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -518,7 +534,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -551,7 +567,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -580,7 +596,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -617,7 +633,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -640,7 +656,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -660,7 +676,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -684,7 +700,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -705,7 +721,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -733,7 +749,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -764,7 +780,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -954,7 +970,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -986,7 +1002,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1013,7 +1029,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1042,7 +1058,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1051,7 +1067,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1061,7 +1077,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1070,7 +1086,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1291,7 +1307,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1313,7 +1329,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1350,7 +1366,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1376,7 +1392,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 59,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1409,7 +1425,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 60,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1668,7 +1684,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 61,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1693,7 +1709,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 62,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1719,7 +1735,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 63,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -1744,7 +1760,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 64,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2017,7 +2033,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 65,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2046,7 +2062,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 66,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2093,7 +2109,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 67,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2144,7 +2160,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "#### Guess a product type"
+    "#### Extra query parameters"
    ]
   },
   {
@@ -2152,27 +2168,260 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "`eodag` has an internal product type catalog which stores a number of metadata for each product type (see [this page](../../getting_started_guide/product_types.rst) for more information). It is actually possible to search for products by using some of these metadata. In that case, `eodag` will query its own catalog and use **the product type that best matches the query** among the available product types (i.e. all product types offered by providers where the necessary credentials are provided). The supported kwargs are:\n",
+    "The search methods accept any additional query parameter passed as kwargs. Some of them may already be known to `eodag` and be converted in a correct way."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "<div class=\"alert alert-warning\">\n",
+    "\n",
+    "Warning\n",
+    "\n",
+    "This feature is intended for advanced users.\n",
     "\n",
+    "</div>"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Providers generally accept many more request parameters than the basic ones provided by `eodag` by default (geometry and time period). Many of these parameters are actually known to `eodag` and configured internally (see the [providers pre-configuration section](../../add_provider.rst#providers-pre-configuration)). They are just not exposed in the signature of the search methods, not to overload it, and also because these parameters are not necessarily share among all the providers.\n",
+    "\n",
+    "A common parameter used when searching for EO products is the percentage of cloud cover. *PEPS* for instance accepts a `cloudCover` parameter. `eodag` knows how to transform it in a way that is adapted to *PEPS*."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "2024-02-06 16:15:10,956 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
+      "2024-02-06 16:15:10,959 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?cloudCover=[0,10]&startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
+      "2024-02-06 16:15:12,893 eodag.core                       [INFO    ] Found 11 result(s) on provider 'peps'\n"
+     ]
+    }
+   ],
+   "source": [
+    "products, estimated_total_number = dag.search(\n",
+    "    cloudCover=10,  # cloud cover Less than 10\n",
+    "    **default_search_criteria\n",
+    ")"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It is possible to check that the search returned products than have a cloud cover less than 10%."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[0,\n",
+       " 0.332726867187601,\n",
+       " 3.4506936264591905,\n",
+       " 0,\n",
+       " 0,\n",
+       " 0,\n",
+       " 0,\n",
+       " 0,\n",
+       " 0,\n",
+       " 7.062549162254081,\n",
+       " 2.06458837230135]"
+      ]
+     },
+     "execution_count": 80,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[p.properties[\"cloudCover\"] for p in products]"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Having a closer look at the URL displayed in the logs above, it can be observed that `cloudCover=10` was actually converted by `eodag` to the query string `cloudCover=[0,10]`. This proves that `eodag` indeed knows about this parameter and how to adapt it for *PEPS*."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Query parameters unknown to `eodag` are also propagated until they are directly requested to the provider, albeit as is."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "2024-02-06 16:15:12,919 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
+      "2024-02-06 16:15:12,922 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?random_parameter=random_value&startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
+      "2024-02-06 16:15:15,274 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
+     ]
+    }
+   ],
+   "source": [
+    "products, estimated_total_number = dag.search(\n",
+    "    random_parameter=\"random_value\",\n",
+    "    **default_search_criteria\n",
+    ")"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The logs above show that the random kwarg passed to the [search()](../../api_reference/core.rst#eodag.api.core.EODataAccessGateway.search) method was indeed propagated to the request made to *PEPS*. It happens that *PEPS* accept unsupported parameters and still returned products, another provider might just have sent an error."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Guess a product type"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "`eodag` has an internal product type catalog which stores a number of metadata for each product type (see [this page](../../getting_started_guide/product_types.rst) for more information). It is actually possible to search for products by using some of these metadata. In that case, `eodag` will query its own catalog and use **the product type that best matches the query** among the available product types (i.e. all product types offered by providers where the necessary credentials are provided). The supported parameters are:\n",
+    "\n",
+    "* `free_text`: *search applied to all of the following fields*\n",
     "* `instrument` (e.g. *MSI*)\n",
     "* `platform` (e.g. *SENTINEL2*)\n",
     "* `platformSerialIdentifier` (e.g. *S2A*)\n",
     "* `processingLevel` (e.g. *L1*)\n",
     "* `sensorType` (e.g. *OPTICAL*)\n",
-    "* `keywords` (e.g. *SENTINEL2 L1C SAFE*), which is case insensitive and ignores `-` or `_` characters"
+    "* `keywords` (e.g. *SENTINEL2 L1C SAFE*), which is case insensitive and ignores `-` or `_` characters\n",
+    "* `abstract` (e.g. *\"Level-1C product is composed of 100x100 km2\"*), which is case insensitive\n",
+    "* `title` (e.g. *SENTINEL2 Level-1C*), which is case insensitive"
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "For example if we call the method with platform=\"SENTINEL1\", all the product types offering products from this platform will be returned."
+    "For example, if we call the method with \"Sentinel\", all the product having one off their searchable (described just above) field matching \"Sentinel\" (case insensitive) will be returned."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 68,
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['S5P_L2_CLOUD',\n",
+       " 'S5P_L2_NO2',\n",
+       " 'S5P_L2_CO',\n",
+       " 'S5P_L2_CH4',\n",
+       " 'S5P_L1B_RA_BD1',\n",
+       " 'S5P_L1B_RA_BD2',\n",
+       " 'S5P_L1B_RA_BD3',\n",
+       " 'S5P_L1B_RA_BD4',\n",
+       " 'S5P_L1B_RA_BD5',\n",
+       " 'S5P_L1B_RA_BD6',\n",
+       " 'S5P_L1B_RA_BD7',\n",
+       " 'S5P_L1B_RA_BD8',\n",
+       " 'S3_SRA',\n",
+       " 'S3_ERR',\n",
+       " 'S3_WAT',\n",
+       " 'S1_SAR_RAW',\n",
+       " 'S2_MSI_L2A',\n",
+       " 'S3_EFR',\n",
+       " 'S3_RAC',\n",
+       " 'S1_SAR_SLC',\n",
+       " 'S3_OLCI_L2LFR',\n",
+       " 'S3_OLCI_L2LRR',\n",
+       " 'S3_OLCI_L2WFR',\n",
+       " 'S3_OLCI_L2WRR',\n",
+       " 'S1_SAR_GRD',\n",
+       " 'S2_MSI_L1C',\n",
+       " 'S1_SAR_OCN',\n",
+       " 'S2_MSI_L2A_MAJA',\n",
+       " 'S2_MSI_L2B_MAJA_SNOW',\n",
+       " 'S5P_L2_HCHO',\n",
+       " 'S5P_L2_O3',\n",
+       " 'S5P_L2_O3_PR',\n",
+       " 'S5P_L2_O3_TCL',\n",
+       " 'S5P_L2_SO2',\n",
+       " 'L8_REFLECTANCE',\n",
+       " 'S5P_L2_AER_AI',\n",
+       " 'S5P_L2_AER_LH',\n",
+       " 'S5P_L2_NP_BD3',\n",
+       " 'S5P_L2_NP_BD6',\n",
+       " 'S5P_L2_NP_BD7',\n",
+       " 'S5P_L1B_IR_SIR',\n",
+       " 'S5P_L1B_IR_UVN',\n",
+       " 'S2_MSI_L2A_COG',\n",
+       " 'S2_MSI_L2B_MAJA_WATER',\n",
+       " 'S2_MSI_L3A_WASP',\n",
+       " 'S3_LAN',\n",
+       " 'S3_SLSTR_L1RBT',\n",
+       " 'S3_SLSTR_L2AOD',\n",
+       " 'S3_SLSTR_L2FRP',\n",
+       " 'S3_SLSTR_L2LST',\n",
+       " 'S3_SLSTR_L2WST',\n",
+       " 'S3_SRA_A',\n",
+       " 'S3_SRA_BS',\n",
+       " 'S3_SY_AOD',\n",
+       " 'S3_SY_SYN',\n",
+       " 'S3_SY_V10',\n",
+       " 'S3_SY_VG1',\n",
+       " 'S3_SY_VGP']"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# doing this\n",
+    "dag.guess_product_type(\"Sentinel\")\n",
+    "# is equivalent as doing that\n",
+    "dag.guess_product_type(free_text=\"Sentinel\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now, let say we want only the product types whith the platform being \"SENTINEL1\":"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2181,7 +2430,7 @@
        "['S1_SAR_GRD', 'S1_SAR_OCN', 'S1_SAR_RAW', 'S1_SAR_SLC']"
       ]
      },
-     "execution_count": 68,
+     "execution_count": 4,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2191,7 +2440,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2200,13 +2448,15 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 69,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "['LANDSAT_C2L1',\n",
+       "['L8_OLI_TIRS_C1L1',\n",
+       " 'L8_REFLECTANCE',\n",
+       " 'LANDSAT_C2L1',\n",
        " 'LANDSAT_C2L2',\n",
        " 'LANDSAT_C2L2ALB_BT',\n",
        " 'LANDSAT_C2L2ALB_SR',\n",
@@ -2214,13 +2464,10 @@
        " 'LANDSAT_C2L2ALB_TA',\n",
        " 'LANDSAT_C2L2_SR',\n",
        " 'LANDSAT_C2L2_ST',\n",
-       " 'LANDSAT_ETM_C2L1',\n",
-       " 'LANDSAT_ETM_C2L2',\n",
-       " 'LANDSAT_TM_C2L1',\n",
-       " 'LANDSAT_TM_C2L2']"
+       " 'L57_REFLECTANCE']"
       ]
      },
-     "execution_count": 69,
+     "execution_count": 5,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2230,7 +2477,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2239,7 +2485,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 70,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2254,19 +2500,13 @@
        " 'LANDSAT_C2L2ALB_TA',\n",
        " 'LANDSAT_C2L2_SR',\n",
        " 'LANDSAT_C2L2_ST',\n",
-       " 'LANDSAT_ETM_C1',\n",
-       " 'LANDSAT_ETM_C2L1',\n",
-       " 'LANDSAT_ETM_C2L2',\n",
-       " 'LANDSAT_TM_C1',\n",
-       " 'LANDSAT_TM_C2L1',\n",
-       " 'LANDSAT_TM_C2L2',\n",
        " 'S1_SAR_GRD',\n",
        " 'S1_SAR_OCN',\n",
        " 'S1_SAR_RAW',\n",
        " 'S1_SAR_SLC']"
       ]
      },
-     "execution_count": 70,
+     "execution_count": 6,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2276,7 +2516,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2285,7 +2524,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 71,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2299,17 +2538,13 @@
        " 'LANDSAT_C2L2ALB_TA',\n",
        " 'LANDSAT_C2L2_SR',\n",
        " 'LANDSAT_C2L2_ST',\n",
-       " 'LANDSAT_ETM_C2L1',\n",
-       " 'LANDSAT_ETM_C2L2',\n",
-       " 'LANDSAT_TM_C2L1',\n",
-       " 'LANDSAT_TM_C2L2',\n",
        " 'S1_SAR_GRD',\n",
        " 'S1_SAR_OCN',\n",
        " 'S1_SAR_RAW',\n",
        " 'S1_SAR_SLC']"
       ]
      },
-     "execution_count": 71,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2319,7 +2554,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2328,14 +2562,13 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 72,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "['CLMS_CORINE',\n",
-       " 'L57_REFLECTANCE',\n",
+       "['L57_REFLECTANCE',\n",
        " 'L8_OLI_TIRS_C1L1',\n",
        " 'L8_REFLECTANCE',\n",
        " 'LANDSAT_C2L1',\n",
@@ -2345,16 +2578,10 @@
        " 'LANDSAT_C2L2ALB_ST',\n",
        " 'LANDSAT_C2L2ALB_TA',\n",
        " 'LANDSAT_C2L2_SR',\n",
-       " 'LANDSAT_C2L2_ST',\n",
-       " 'LANDSAT_ETM_C1',\n",
-       " 'LANDSAT_ETM_C2L1',\n",
-       " 'LANDSAT_ETM_C2L2',\n",
-       " 'LANDSAT_TM_C1',\n",
-       " 'LANDSAT_TM_C2L1',\n",
-       " 'LANDSAT_TM_C2L2']"
+       " 'LANDSAT_C2L2_ST']"
       ]
      },
-     "execution_count": 72,
+     "execution_count": 8,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2364,7 +2591,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2373,7 +2599,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 73,
+   "execution_count": 2,
    "metadata": {},
    "outputs": [
     {
@@ -2385,7 +2611,6 @@
        " 'S1_SAR_SLC',\n",
        " 'S2_MSI_L1C',\n",
        " 'S2_MSI_L2A',\n",
-       " 'S2_MSI_L2AP',\n",
        " 'S2_MSI_L2A_COG',\n",
        " 'S2_MSI_L2A_MAJA',\n",
        " 'S2_MSI_L2B_MAJA_SNOW',\n",
@@ -2397,35 +2622,25 @@
        " 'S3_OLCI_L2LFR',\n",
        " 'S3_OLCI_L2LRR',\n",
        " 'S3_OLCI_L2WFR',\n",
-       " 'S3_OLCI_L2WFR_BC003',\n",
        " 'S3_OLCI_L2WRR',\n",
-       " 'S3_OLCI_L2WRR_BC003',\n",
-       " 'S3_OLCI_L4BALTIC',\n",
        " 'S3_RAC',\n",
        " 'S3_SLSTR_L1RBT',\n",
-       " 'S3_SLSTR_L1RBT_BC004',\n",
-       " 'S3_SLSTR_L2',\n",
        " 'S3_SLSTR_L2AOD',\n",
        " 'S3_SLSTR_L2FRP',\n",
        " 'S3_SLSTR_L2LST',\n",
        " 'S3_SLSTR_L2WST',\n",
-       " 'S3_SLSTR_L2WST_BC003',\n",
        " 'S3_SRA',\n",
-       " 'S3_SRA_1A_BC004',\n",
-       " 'S3_SRA_1B_BC004',\n",
        " 'S3_SRA_A',\n",
        " 'S3_SRA_BS',\n",
-       " 'S3_SRA_BS_BC004',\n",
        " 'S3_SY_AOD',\n",
        " 'S3_SY_SYN',\n",
        " 'S3_SY_V10',\n",
        " 'S3_SY_VG1',\n",
        " 'S3_SY_VGP',\n",
-       " 'S3_WAT',\n",
-       " 'S3_WAT_BC004']"
+       " 'S3_WAT']"
       ]
      },
-     "execution_count": 73,
+     "execution_count": 2,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2435,7 +2650,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2443,7 +2657,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2452,7 +2665,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2466,16 +2679,10 @@
        " 'LANDSAT_C2L2ALB_ST',\n",
        " 'LANDSAT_C2L2ALB_TA',\n",
        " 'LANDSAT_C2L2_SR',\n",
-       " 'LANDSAT_C2L2_ST',\n",
-       " 'LANDSAT_ETM_C1',\n",
-       " 'LANDSAT_ETM_C2L1',\n",
-       " 'LANDSAT_ETM_C2L2',\n",
-       " 'LANDSAT_TM_C1',\n",
-       " 'LANDSAT_TM_C2L1',\n",
-       " 'LANDSAT_TM_C2L2']"
+       " 'LANDSAT_C2L2_ST']"
       ]
      },
-     "execution_count": 4,
+     "execution_count": 11,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2485,7 +2692,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2496,12 +2702,12 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Per paramater guesses are joined using a `UNION` by default (`intersect=False`). This can also be changed to an intersection:"
+    "Per parameter, guesses are joined using a `UNION` by default (`intersect=False`). This can also be changed to an intersection:"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2510,7 +2716,7 @@
        "['LANDSAT_C2L1']"
       ]
      },
-     "execution_count": 3,
+     "execution_count": 12,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2520,41 +2726,6 @@
    ]
   },
   {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "[Whoosh query language](https://whoosh.readthedocs.io/en/latest/querylang.html#the-default-query-language) *free text search* can also be passed to the method, it will be used to search in `title`, `abstract` and `keywords` fields:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['ERA5_SL_MONTHLY',\n",
-       " 'ERA5_PL_MONTHLY',\n",
-       " 'ERA5_LAND_MONTHLY',\n",
-       " 'ERA5_SL',\n",
-       " 'ERA5_PL',\n",
-       " 'GLOFAS_SEASONAL_REFORECAST',\n",
-       " 'SEASONAL_MONTHLY_PL',\n",
-       " 'SEASONAL_MONTHLY_SL']"
-      ]
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "dag.guess_product_type(\"ECMWF AND MONTHLY\")"
-   ]
-  },
-  {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2563,7 +2734,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 75,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2578,7 +2749,7 @@
        " 'sensorType': 'OPTICAL'}"
       ]
      },
-     "execution_count": 75,
+     "execution_count": 15,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2597,7 +2768,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 76,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2606,7 +2777,7 @@
        "'S2_MSI_L1C'"
       ]
      },
-     "execution_count": 76,
+     "execution_count": 16,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2617,199 +2788,57 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 77,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-06 16:15:08,624 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
-      "2024-02-06 16:15:08,626 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
-      "2024-02-06 16:15:10,928 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
+      "2024-03-26 23:09:25,451 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
+      "2024-03-26 23:09:25,454 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n"
      ]
-    }
-   ],
-   "source": [
-    "products, estimated_total_number = dag.search(**guess_search_criteria)"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "`eodag` searches through its metadata catalog and checks which product type corresponds to the given parameters. There is a product type called `S2_MSI_L1C`, for the platform SENTINEL2 with the platformSerialIdentifiers S2A and S2B using the instrument MSI and the sensorType OPTICAL. Thus, all parameters of the product type `S2_MSI_L1C` are matching to the given search criteria and it is chosen to be internally used to search for products. If no product type is matching all the criteria, the one with the most matches is chosen, if several product types match all the given criteria, the first one is chosen."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 78,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'S2_MSI_L1C'"
-      ]
-     },
-     "execution_count": 78,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "products[0].product_type"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "#### Extra query parameters"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "The search methods accept any additional query parameter passed as kwargs. Some of them may already be known to `eodag` and be converted in a correct way."
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "<div class=\"alert alert-warning\">\n",
-    "\n",
-    "Warning\n",
-    "\n",
-    "This feature is intended for advanced users.\n",
-    "\n",
-    "</div>"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "Providers generally accept many more request parameters than the basic ones provided by `eodag` by default (geometry and time period). Many of these parameters are actually known to `eodag` and configured internally (see the [providers pre-configuration section](../../add_provider.rst#providers-pre-configuration)). They are just not exposed in the signature of the search methods, not to overload it, and also because these parameters are not necessarily share among all the providers.\n",
-    "\n",
-    "A common parameter used when searching for EO products is the percentage of cloud cover. *PEPS* for instance accepts a `cloudCover` parameter. `eodag` knows how to transform it in a way that is adapted to *PEPS*."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 79,
-   "metadata": {},
-   "outputs": [
+    },
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2024-02-06 16:15:10,956 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
-      "2024-02-06 16:15:10,959 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?cloudCover=[0,10]&startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
-      "2024-02-06 16:15:12,893 eodag.core                       [INFO    ] Found 11 result(s) on provider 'peps'\n"
+      "2024-03-26 23:09:27,017 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
      ]
     }
    ],
    "source": [
-    "products, estimated_total_number = dag.search(\n",
-    "    cloudCover=10,  # cloud cover Less than 10\n",
-    "    **default_search_criteria\n",
-    ")"
+    "products, estimated_total_number = dag.search(**guess_search_criteria)"
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "It is possible to check that the search returned products than have a cloud cover less than 10%."
+    "`eodag` searches through its metadata catalog and checks which product type corresponds to the given parameters. There is a product type called `S2_MSI_L1C`, for the platform SENTINEL2 with the platformSerialIdentifiers S2A and S2B using the instrument MSI and the sensorType OPTICAL. Thus, all parameters of the product type `S2_MSI_L1C` are matching to the given search criteria and it is chosen to be internally used to search for products. If no product type is matching all the criteria, the one with the most matches is chosen, if several product types match all the given criteria, the first one is chosen."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 80,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "[0,\n",
-       " 0.332726867187601,\n",
-       " 3.4506936264591905,\n",
-       " 0,\n",
-       " 0,\n",
-       " 0,\n",
-       " 0,\n",
-       " 0,\n",
-       " 0,\n",
-       " 7.062549162254081,\n",
-       " 2.06458837230135]"
+       "'S2_MSI_L1C'"
       ]
      },
-     "execution_count": 80,
+     "execution_count": 18,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "[p.properties[\"cloudCover\"] for p in products]"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "Having a closer look at the URL displayed in the logs above, it can be observed that `cloudCover=10` was actually converted by `eodag` to the query string `cloudCover=[0,10]`. This proves that `eodag` indeed knows about this parameter and how to adapt it for *PEPS*."
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "Query parameters unknown to `eodag` are also propagated until they are directly requested to the provider, albeit as is."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 81,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "2024-02-06 16:15:12,919 eodag.core                       [INFO    ] Searching product type 'S2_MSI_L1C' on provider: peps\n",
-      "2024-02-06 16:15:12,922 eodag.search.qssearch            [INFO    ] Sending search request: https://peps.cnes.fr/resto/api/collections/S2ST/search.json?random_parameter=random_value&startDate=2021-03-01&completionDate=2021-03-31&geometry=POLYGON ((1.0000 43.0000, 1.0000 44.0000, 2.0000 44.0000, 2.0000 43.0000, 1.0000 43.0000))&productType=S2MSI1C&maxRecords=20&page=1\n",
-      "2024-02-06 16:15:15,274 eodag.core                       [INFO    ] Found 48 result(s) on provider 'peps'\n"
-     ]
-    }
-   ],
-   "source": [
-    "products, estimated_total_number = dag.search(\n",
-    "    random_parameter=\"random_value\",\n",
-    "    **default_search_criteria\n",
-    ")"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "The logs above show that the random kwarg passed to the [search()](../../api_reference/core.rst#eodag.api.core.EODataAccessGateway.search) method was indeed propagated to the request made to *PEPS*. It happens that *PEPS* accept unsupported parameters and still returned products, another provider might just have sent an error."
+    "products[0].product_type"
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -2846,7 +2875,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2877,7 +2906,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2914,7 +2943,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -2996,7 +3025,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -3038,7 +3067,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -3069,7 +3098,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": null,
    "metadata": {},
    "outputs": [
     {
@@ -3098,13 +3127,6 @@
     "    api_product_type=None\n",
     ")"
    ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
   }
  ],
  "metadata": {
@@ -3123,7 +3145,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.12"
+   "version": "3.12.0"
   },
   "widgets": {
    "application/vnd.jupyter.widget-state+json": {
diff --git a/eodag/api/core.py b/eodag/api/core.py
index 4c994d0e..ea84e6fe 100644
--- a/eodag/api/core.py
+++ b/eodag/api/core.py
@@ -52,6 +52,7 @@ from eodag.plugins.manager import PluginManager
 from eodag.plugins.search.build_search_result import BuildPostSearchResult
 from eodag.types import model_fields_to_annotated
 from eodag.types.queryables import CommonQueryables
+from eodag.types.whoosh import EODAGQueryParser
 from eodag.utils import (
     DEFAULT_DOWNLOAD_TIMEOUT,
     DEFAULT_DOWNLOAD_WAIT,
@@ -235,7 +236,6 @@ class EODataAccessGateway:
             if "unsupported pickle protocol" in str(ve):
                 logger.debug("Need to recreate whoosh .index: '%s'", ve)
                 create_index = True
-                shutil.rmtree(index_dir)
             # Unexpected error
             else:
                 logger.error(
@@ -249,13 +249,14 @@ class EODataAccessGateway:
             if self._product_types_index is None:
                 logger.debug("Opening product types index in %s", index_dir)
                 self._product_types_index = open_dir(index_dir)
-            try:
-                self.guess_product_type(md5=self.product_types_config_md5)
-            except NoMatchingProductType:
-                create_index = True
-            finally:
-                if create_index:
-                    shutil.rmtree(index_dir)
+
+            with self._product_types_index.searcher() as searcher:
+                p = QueryParser("md5", self._product_types_index.schema, plugins=[])
+                query = p.parse(self.product_types_config_md5)
+                results = searcher.search(query, limit=1)
+
+                if not results:
+                    create_index = True
                     logger.debug(
                         "Out-of-date product types index removed from %s", index_dir
                     )
@@ -903,79 +904,83 @@ class EODataAccessGateway:
 
     def guess_product_type(
         self,
-        free_text_filter: Optional[str] = None,
+        free_text: Optional[str] = None,
         intersect: bool = False,
+        instrument: Optional[str] = None,
+        platform: Optional[str] = None,
+        platformSerialIdentifier: Optional[str] = None,
+        processingLevel: Optional[str] = None,
+        sensorType: Optional[str] = None,
+        keywords: Optional[str] = None,
+        abstract: Optional[str] = None,
+        title: Optional[str] = None,
         **kwargs: Any,
     ) -> List[str]:
-        """Find eodag product types ids that best match a set of search params
+        """
+        Find EODAG product type IDs that best match a set of search parameters.
 
         See https://whoosh.readthedocs.io/en/latest/querylang.html#the-default-query-language
-        for syntax.
+          for syntax.
 
-        :param free_text_filter: whoosh compatible free text search filter used to search
-                                 `title`, `abstract` and `keywords`
-        :type free_text_filter: Optional[str]
-        :param intersect: join results for each parameter using INTERSECT instead of UNION
+        :param free_text: Whoosh-compatible free text search filter used to search
+                        accross all the following parameters
+        :type free_text: Optional[str]
+        :param intersect: Join results for each parameter using INTERSECT instead of UNION.
         :type intersect: bool
-        :param kwargs: A set of search parameters as keywords arguments
-        :returns: The best match for the given parameters
-        :rtype: list[str]
+        :param instrument: Instrument parameter.
+        :type instrument: Optional[str]
+        :param platform: Platform parameter.
+        :type platform: Optional[str]
+        :param platformSerialIdentifier: Platform serial identifier parameter.
+        :type platformSerialIdentifier: Optional[str]
+        :param processingLevel: Processing level parameter.
+        :type processingLevel: Optional[str]
+        :param sensorType: Sensor type parameter.
+        :type sensorType: Optional[str]
+        :param keywords: Keywords parameter.
+        :type keywords: Optional[str]
+        :param abstract: Abstract parameter.
+        :type abstract: Optional[str]
+        :param title: Title parameter.
+        :type title: Optional[str]
+        :returns: The best match for the given parameters.
+        :rtype: List[str]
         :raises: :class:`~eodag.utils.exceptions.NoMatchingProductType`
         """
-        if kwargs.get("productType", None):
-            return [kwargs["productType"]]
-        free_text_search_params = (
-            ["title", "abstract", "keywords"] if free_text_filter else []
-        )
-        supported_params = {
-            param
-            for param in (
-                "instrument",
-                "platform",
-                "platformSerialIdentifier",
-                "processingLevel",
-                "sensorType",
-                "keywords",
-                "md5",
-                "abstract",
-                "title",
-            )
-            if kwargs.get(param, None) is not None
-        }
+        if productType := kwargs.get("productType"):
+            return [productType]
+
         if not self._product_types_index:
             raise EodagError("Missing product types index")
-        with self._product_types_index.searcher() as searcher:
-            results = None
-            # Using `upgrade_and_extend`, for each search key, do a guess and
-            # then upgrade the result (i.e. when merging results,
-            # if a hit appears in both results, its position is raised
-            # to the top). This way, the top most result will be the hit that best
-            # matches the given queries. Put another way, this best guess is the one
-            # that crosses the highest number of search params from the given queries
-
-            # Always use UNION to join free_text_search results
-            for search_key in free_text_search_params:
-                query = QueryParser(search_key, self._product_types_index.schema).parse(
-                    free_text_filter
-                )
-                if results is None:
-                    results = searcher.search(query, limit=None)
-                else:
-                    results.upgrade_and_extend(searcher.search(query, limit=None))
 
-            # join results from kwargs using UNION or INTERSECT
-            for search_key in supported_params:
-                query = QueryParser(search_key, self._product_types_index.schema).parse(
-                    kwargs[search_key]
-                )
-                if results is None:
-                    results = searcher.search(query, limit=None)
-                elif intersect:
-                    results.filter(searcher.search(query, limit=None))
-                else:
-                    results.upgrade_and_extend(searcher.search(query, limit=None))
+        filters = {
+            "instrument": instrument,
+            "platform": platform,
+            "platformSerialIdentifier": platformSerialIdentifier,
+            "processingLevel": processingLevel,
+            "sensorType": sensorType,
+            "keywords": keywords,
+            "abstract": abstract,
+            "title": title,
+        }
+        joint = " AND " if intersect else " OR "
+        filters_text = joint.join(
+            [f"{k}:({v})" for k, v in filters.items() if v is not None]
+        )
+
+        text = f"({free_text})" if free_text else ""
+        if free_text and filters_text:
+            text += joint
+        if filters_text:
+            text += f"({filters_text})"
+
+        with self._product_types_index.searcher() as searcher:
+            p = EODAGQueryParser(list(filters.keys()), self._product_types_index.schema)
+            query = p.parse(text)
+            results = searcher.search(query, limit=None)
 
             guesses: List[str] = [r["ID"] for r in results or []]
+
         if guesses:
             return guesses
         raise NoMatchingProductType()
diff --git a/eodag/resources/stac.yml b/eodag/resources/stac.yml
index bf9765e9..83b7109a 100644
--- a/eodag/resources/stac.yml
+++ b/eodag/resources/stac.yml
@@ -63,6 +63,7 @@ conformance:
     - https://api.stacspec.org/v1.0.0/ogcapi-features#sort
     - https://api.stacspec.org/v1.0.0/collections
     - https://api.stacspec.org/v1.0.0/collection-search#free-text
+    - https://api.stacspec.org/v1.0.0/collection-search#advanced-free-text
     - http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core
     - http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30
     - http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson
diff --git a/eodag/types/whoosh.py b/eodag/types/whoosh.py
new file mode 100644
index 00000000..c2c40566
--- /dev/null
+++ b/eodag/types/whoosh.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+# Copyright 2024, CS Systemes d'Information, https://www.csgroup.eu/
+#
+# This file is part of EODAG project
+#     https://www.github.com/CS-SI/EODAG
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from typing import List
+
+from whoosh.fields import Schema
+from whoosh.matching import NullMatcher
+from whoosh.qparser import OrGroup, QueryParser, plugins
+from whoosh.query.positional import Phrase
+from whoosh.query.qcore import QueryError
+
+
+class RobustPhrase(Phrase):
+    """
+    Matches documents containing a given phrase.
+    """
+
+    def matcher(self, searcher, context=None):
+        """
+        Override the default to not raise error on match exception but simply return not found
+        Needed to handle phrase search in whoosh.fields.IDLIST
+        """
+        try:
+            return super().matcher(searcher, context)
+        except QueryError:
+            return NullMatcher()
+
+
+class EODAGQueryParser(QueryParser):
+    """
+    A hand-written query parser built on modular plug-ins.
+
+    Override the default to include specific EODAG configuration
+    """
+
+    def __init__(
+        self,
+        filters: List[str],
+        schema: Schema,
+    ):
+        """
+        EODAG QueryParser initialization
+
+        :param filters: list of fieldnames to filter on
+        :type filters: List[str]
+        :param schema: Whoosh Schema
+        :type schma: :class:whoosh.fields.Schema
+        """
+        super().__init__(
+            None,
+            schema=schema,
+            plugins=[
+                plugins.SingleQuotePlugin(),
+                plugins.FieldsPlugin(),
+                plugins.WildcardPlugin(),
+                plugins.PhrasePlugin(),
+                plugins.GroupPlugin(),
+                plugins.OperatorsPlugin(),
+                plugins.BoostPlugin(),
+                plugins.EveryPlugin(),
+                plugins.RangePlugin(),
+                plugins.PlusMinusPlugin(),
+                plugins.MultifieldPlugin(filters, fieldboosts=None),
+            ],
+            phraseclass=RobustPhrase,
+            group=OrGroup,
+        )


Test patch:
diff --git a/tests/units/test_core.py b/tests/units/test_core.py
index 90551178..8eb1157c 100644
--- a/tests/units/test_core.py
+++ b/tests/units/test_core.py
@@ -497,14 +497,12 @@ class TestCore(TestCoreBase):
             ext_product_types_conf = json.load(f)
         self.dag.update_product_types_list(ext_product_types_conf)
 
-        # Free text search: match in the abstract
+        # Search any filter contains filter value
         filter = "ABSTRACTFOO"
         product_types_ids = self.dag.guess_product_type(filter)
         self.assertListEqual(product_types_ids, ["foo"])
-        filter = "(ABSTRACTFOO)"
-        product_types_ids = self.dag.guess_product_type(filter)
-        self.assertListEqual(product_types_ids, ["foo"])
-        filter = " FOO  THIS  IS "
+        # Search the exact phrase. Search is case insensitive
+        filter = '"THIS IS FOO. fooandbar"'
         product_types_ids = self.dag.guess_product_type(filter)
         self.assertListEqual(product_types_ids, ["foo"])
 
@@ -513,28 +511,52 @@ class TestCore(TestCoreBase):
         product_types_ids = self.dag.guess_product_type(filter)
         self.assertListEqual(product_types_ids, ["bar"])
 
-        # Free text search: match in the title
-        filter = "COLLECTION FOOBAR"
+        # Free text search: match the phrase in title
+        filter = '"FOOBAR COLLECTION"'
         product_types_ids = self.dag.guess_product_type(filter)
         self.assertListEqual(product_types_ids, ["foobar"])
 
-        # Free text search: multiple terms
-        filter = "(This is FOOBAR) OR (This is BAR)"
+        # Free text search: Using OR term match
+        filter = "FOOBAR,BAR"
+        product_types_ids = self.dag.guess_product_type(filter)
+        self.assertListEqual(sorted(product_types_ids), ["bar", "foobar"])
+
+        filter = "FOOBAR BAR"
+        product_types_ids = self.dag.guess_product_type(filter)
+        self.assertListEqual(sorted(product_types_ids), ["bar", "foobar"])
+
+        filter = "FOOBAR OR BAR"
         product_types_ids = self.dag.guess_product_type(filter)
         self.assertListEqual(sorted(product_types_ids), ["bar", "foobar"])
 
-        # Free text search: multiple terms joined with param search (UNION)
-        filter = "(This is FOOBAR) OR (This is BAR)"
+        # Free text search: using OR term match with additional filter UNION
+        filter = "FOOBAR OR BAR"
         product_types_ids = self.dag.guess_product_type(filter, title="FOO*")
         self.assertListEqual(sorted(product_types_ids), ["bar", "foo", "foobar"])
 
+        # Free text search: Using AND term match
+        filter = "suspendisse AND FOO"
+        product_types_ids = self.dag.guess_product_type(filter)
+        self.assertListEqual(sorted(product_types_ids), ["foo"])
+
+        # Free text search: Parentheses can be used to group terms
+        filter = "(FOOBAR OR BAR) AND titleFOOBAR"
+        product_types_ids = self.dag.guess_product_type(filter)
+        self.assertListEqual(sorted(product_types_ids), ["foobar"])
+
         # Free text search: multiple terms joined with param search (INTERSECT)
-        filter = "(This is FOOBAR) OR (This is BAR)"
+        filter = "FOOBAR OR BAR"
         product_types_ids = self.dag.guess_product_type(
             filter, intersect=True, title="titleFOO*"
         )
         self.assertListEqual(sorted(product_types_ids), ["foobar"])
 
+        # Free text search: Indicate included and excluded terms using +/-
+        # This will search for items that INCLUDES "abstractfoo" EXCLUDES "bar" OR CONTAIN "foo"
+        filter = "foo +abstractfoo -bar"
+        product_types_ids = self.dag.guess_product_type(filter)
+        self.assertListEqual(sorted(product_types_ids), ["foo"])
+
     def test_update_product_types_list(self):
         """Core api.update_product_types_list must update eodag product types list"""
         with open(os.path.join(TEST_RESOURCES_PATH, "ext_product_types.json")) as f: