stac-fastapi-opensearch 6.4.0__tar.gz → 6.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (16) hide show
  1. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/PKG-INFO +32 -10
  2. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/README.md +31 -9
  3. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/setup.py +2 -2
  4. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi/opensearch/app.py +74 -9
  5. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi/opensearch/database_logic.py +173 -19
  6. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi/opensearch/version.py +1 -1
  7. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi_opensearch.egg-info/PKG-INFO +32 -10
  8. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi_opensearch.egg-info/requires.txt +2 -2
  9. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/setup.cfg +0 -0
  10. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi/opensearch/__init__.py +0 -0
  11. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi/opensearch/config.py +0 -0
  12. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi_opensearch.egg-info/SOURCES.txt +0 -0
  13. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi_opensearch.egg-info/dependency_links.txt +0 -0
  14. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi_opensearch.egg-info/entry_points.txt +0 -0
  15. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi_opensearch.egg-info/not-zip-safe +0 -0
  16. {stac_fastapi_opensearch-6.4.0 → stac_fastapi_opensearch-6.5.1}/stac_fastapi_opensearch.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stac_fastapi_opensearch
3
- Version: 6.4.0
3
+ Version: 6.5.1
4
4
  Summary: Opensearch stac-fastapi backend.
5
5
  Home-page: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
6
6
  License: MIT
@@ -87,13 +87,13 @@ This project is built on the following technologies: STAC, stac-fastapi, FastAPI
87
87
  ## Table of Contents
88
88
 
89
89
  - [stac-fastapi-elasticsearch-opensearch](#stac-fastapi-elasticsearch-opensearch)
90
- - [Sponsors \& Supporters](#sponsors--supporters)
90
+ - [Sponsors & Supporters](#sponsors--supporters)
91
91
  - [Project Introduction - What is SFEOS?](#project-introduction---what-is-sfeos)
92
92
  - [Common Deployment Patterns](#common-deployment-patterns)
93
93
  - [Technologies](#technologies)
94
94
  - [Table of Contents](#table-of-contents)
95
95
  - [Collection Search Extensions](#collection-search-extensions)
96
- - [Documentation \& Resources](#documentation--resources)
96
+ - [Documentation & Resources](#documentation--resources)
97
97
  - [Package Structure](#package-structure)
98
98
  - [Examples](#examples)
99
99
  - [Performance](#performance)
@@ -136,7 +136,11 @@ This project is built on the following technologies: STAC, stac-fastapi, FastAPI
136
136
 
137
137
  ## Collection Search Extensions
138
138
 
139
- SFEOS implements extended capabilities for the `/collections` endpoint, allowing for more powerful collection discovery:
139
+ SFEOS provides enhanced collection search capabilities through two primary routes:
140
+ - **GET/POST `/collections`**: The standard STAC endpoint with extended query parameters
141
+ - **GET/POST `/collections-search`**: A custom endpoint that supports the same parameters, created to avoid conflicts with the STAC Transactions extension if enabled (which uses POST `/collections` for collection creation)
142
+
143
+ These endpoints support advanced collection discovery features including:
140
144
 
141
145
  - **Sorting**: Sort collections by sortable fields using the `sortby` parameter
142
146
  - Example: `/collections?sortby=+id` (ascending sort by ID)
@@ -152,9 +156,26 @@ SFEOS implements extended capabilities for the `/collections` endpoint, allowing
152
156
  - Searches across multiple text fields including title, description, and keywords
153
157
  - Supports partial word matching and relevance-based sorting
154
158
 
159
+ - **Structured Filtering**: Filter collections using CQL2 expressions
160
+ - JSON format: `/collections?filter={"op":"=","args":[{"property":"id"},"sentinel-2"]}&filter-lang=cql2-json`
161
+ - Text format: `/collections?filter=id='sentinel-2'&filter-lang=cql2-text` (note: string values must be quoted)
162
+ - Advanced text format: `/collections?filter=id LIKE '%sentinel%'&filter-lang=cql2-text` (supports LIKE, BETWEEN, etc.)
163
+ - Supports both CQL2 JSON and CQL2 text formats with various operators
164
+ - Enables precise filtering on any collection property
165
+
166
+ - **Datetime Filtering**: Filter collections by their temporal extent using the `datetime` parameter
167
+ - Example: `/collections?datetime=2020-01-01T00:00:00Z/2020-12-31T23:59:59Z` (finds collections with temporal extents that overlap this range)
168
+ - Example: `/collections?datetime=2020-06-15T12:00:00Z` (finds collections whose temporal extent includes this specific time)
169
+ - Example: `/collections?datetime=2020-01-01T00:00:00Z/..` (finds collections with temporal extents that extend to or beyond January 1, 2020)
170
+ - Example: `/collections?datetime=../2020-12-31T23:59:59Z` (finds collections with temporal extents that begin on or before December 31, 2020)
171
+ - Collections are matched if their temporal extent overlaps with the provided datetime parameter
172
+ - This allows for efficient discovery of collections based on time periods
173
+
155
174
  These extensions make it easier to build user interfaces that display and navigate through collections efficiently.
156
175
 
157
- > **Configuration**: Collection search extensions can be disabled by setting the `ENABLE_COLLECTIONS_SEARCH` environment variable to `false`. By default, these extensions are enabled.
176
+ > **Configuration**: Collection search extensions (sorting, field selection, free text search, structured filtering, and datetime filtering) for the `/collections` endpoint can be disabled by setting the `ENABLE_COLLECTIONS_SEARCH` environment variable to `false`. By default, these extensions are enabled.
177
+ >
178
+ > **Configuration**: The custom `/collections-search` endpoint can be enabled by setting the `ENABLE_COLLECTIONS_SEARCH_ROUTE` environment variable to `true`. By default, this endpoint is **disabled**.
158
179
 
159
180
  > **Note**: Sorting is only available on fields that are indexed for sorting in Elasticsearch/OpenSearch. With the default mappings, you can sort on:
160
181
  > - `id` (keyword field)
@@ -165,6 +186,7 @@ These extensions make it easier to build user interfaces that display and naviga
165
186
  >
166
187
  > **Important**: Adding keyword fields to make text fields sortable can significantly increase the index size, especially for large text fields. Consider the storage implications when deciding which fields to make sortable.
167
188
 
189
+
168
190
  ## Package Structure
169
191
 
170
192
  This project is organized into several packages, each with a specific purpose:
@@ -177,7 +199,7 @@ This project is organized into several packages, each with a specific purpose:
177
199
  - Shared logic and utilities that improve code reuse between backends
178
200
 
179
201
  - **stac_fastapi_elasticsearch**: Complete implementation of the STAC API using Elasticsearch as the backend database. This package depends on both `stac_fastapi_core` and `sfeos_helpers`.
180
- -
202
+
181
203
  - **stac_fastapi_opensearch**: Complete implementation of the STAC API using OpenSearch as the backend database. This package depends on both `stac_fastapi_core` and `sfeos_helpers`.
182
204
 
183
205
  ## Examples
@@ -295,12 +317,13 @@ You can customize additional settings in your `.env` file:
295
317
  | `ENABLE_DIRECT_RESPONSE` | Enable direct response for maximum performance (disables all FastAPI dependencies, including authentication, custom status codes, and validation) | `false` | Optional |
296
318
  | `RAISE_ON_BULK_ERROR` | Controls whether bulk insert operations raise exceptions on errors. If set to `true`, the operation will stop and raise an exception when an error occurs. If set to `false`, errors will be logged, and the operation will continue. **Note:** STAC Item and ItemCollection validation errors will always raise, regardless of this flag. | `false` | Optional |
297
319
  | `DATABASE_REFRESH` | Controls whether database operations refresh the index immediately after changes. If set to `true`, changes will be immediately searchable. If set to `false`, changes may not be immediately visible but can improve performance for bulk operations. If set to `wait_for`, changes will wait for the next refresh cycle to become visible. | `false` | Optional |
298
- | `ENABLE_COLLECTIONS_SEARCH` | Enable collection search extensions (sort, fields). | `true` | Optional |
299
- | `ENABLE_TRANSACTIONS_EXTENSIONS` | Enables or disables the Transactions and Bulk Transactions API extensions. If set to `false`, the POST `/collections` route and related transaction endpoints (including bulk transaction operations) will be unavailable in the API. This is useful for deployments where mutating the catalog via the API should be prevented. | `true` | Optional |
320
+ | `ENABLE_COLLECTIONS_SEARCH` | Enable collection search extensions (sort, fields, free text search, structured filtering, and datetime filtering) on the core `/collections` endpoint. | `true` | Optional |
321
+ | `ENABLE_COLLECTIONS_SEARCH_ROUTE` | Enable the custom `/collections-search` endpoint (both GET and POST methods). When disabled, the custom endpoint will not be available, but collection search extensions will still be available on the core `/collections` endpoint if `ENABLE_COLLECTIONS_SEARCH` is true. | `false` | Optional |
322
+ | `ENABLE_TRANSACTIONS_EXTENSIONS` | Enables or disables the Transactions and Bulk Transactions API extensions. This is useful for deployments where mutating the catalog via the API should be prevented. If set to `true`, the POST `/collections` route for search will be unavailable in the API. | `true` | Optional |
300
323
  | `STAC_ITEM_LIMIT` | Sets the environment variable for result limiting to SFEOS for the number of returned items and STAC collections. | `10` | Optional |
301
324
  | `STAC_INDEX_ASSETS` | Controls if Assets are indexed when added to Elasticsearch/Opensearch. This allows asset fields to be included in search queries. | `false` | Optional |
302
325
  | `ENV_MAX_LIMIT` | Configures the environment variable in SFEOS to override the default `MAX_LIMIT`, which controls the limit parameter for returned items and STAC collections. | `10,000` | Optional |
303
- | `USE_DATETIME` | Configures the datetime search behavior in SFEOS. When enabled, searches both datetime field and falls back to start_datetime/end_datetime range for items with null datetime. When disabled, searches only by start_datetime/end_datetime range. | True | Optional |
326
+ | `USE_DATETIME` | Configures the datetime search behavior in SFEOS. When enabled, searches both datetime field and falls back to start_datetime/end_datetime range for items with null datetime. When disabled, searches only by start_datetime/end_datetime range. | `true` | Optional |
304
327
 
305
328
  > [!NOTE]
306
329
  > The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, `ES_VERIFY_CERTS` and `ES_TIMEOUT` apply to both Elasticsearch and OpenSearch backends, so there is no need to rename the key names to `OS_` even if you're using OpenSearch.
@@ -446,7 +469,6 @@ The system uses a precise naming convention:
446
469
  - `ENABLE_COLLECTIONS_SEARCH`: Set to `true` (default) to enable collection search extensions (sort, fields). Set to `false` to disable.
447
470
  - `ENABLE_TRANSACTIONS_EXTENSIONS`: Set to `true` (default) to enable transaction extensions. Set to `false` to disable.
448
471
 
449
-
450
472
  ## Collection Pagination
451
473
 
452
474
  - **Overview**: The collections route supports pagination through optional query parameters.
@@ -66,13 +66,13 @@ This project is built on the following technologies: STAC, stac-fastapi, FastAPI
66
66
  ## Table of Contents
67
67
 
68
68
  - [stac-fastapi-elasticsearch-opensearch](#stac-fastapi-elasticsearch-opensearch)
69
- - [Sponsors \& Supporters](#sponsors--supporters)
69
+ - [Sponsors & Supporters](#sponsors--supporters)
70
70
  - [Project Introduction - What is SFEOS?](#project-introduction---what-is-sfeos)
71
71
  - [Common Deployment Patterns](#common-deployment-patterns)
72
72
  - [Technologies](#technologies)
73
73
  - [Table of Contents](#table-of-contents)
74
74
  - [Collection Search Extensions](#collection-search-extensions)
75
- - [Documentation \& Resources](#documentation--resources)
75
+ - [Documentation & Resources](#documentation--resources)
76
76
  - [Package Structure](#package-structure)
77
77
  - [Examples](#examples)
78
78
  - [Performance](#performance)
@@ -115,7 +115,11 @@ This project is built on the following technologies: STAC, stac-fastapi, FastAPI
115
115
 
116
116
  ## Collection Search Extensions
117
117
 
118
- SFEOS implements extended capabilities for the `/collections` endpoint, allowing for more powerful collection discovery:
118
+ SFEOS provides enhanced collection search capabilities through two primary routes:
119
+ - **GET/POST `/collections`**: The standard STAC endpoint with extended query parameters
120
+ - **GET/POST `/collections-search`**: A custom endpoint that supports the same parameters, created to avoid conflicts with the STAC Transactions extension if enabled (which uses POST `/collections` for collection creation)
121
+
122
+ These endpoints support advanced collection discovery features including:
119
123
 
120
124
  - **Sorting**: Sort collections by sortable fields using the `sortby` parameter
121
125
  - Example: `/collections?sortby=+id` (ascending sort by ID)
@@ -131,9 +135,26 @@ SFEOS implements extended capabilities for the `/collections` endpoint, allowing
131
135
  - Searches across multiple text fields including title, description, and keywords
132
136
  - Supports partial word matching and relevance-based sorting
133
137
 
138
+ - **Structured Filtering**: Filter collections using CQL2 expressions
139
+ - JSON format: `/collections?filter={"op":"=","args":[{"property":"id"},"sentinel-2"]}&filter-lang=cql2-json`
140
+ - Text format: `/collections?filter=id='sentinel-2'&filter-lang=cql2-text` (note: string values must be quoted)
141
+ - Advanced text format: `/collections?filter=id LIKE '%sentinel%'&filter-lang=cql2-text` (supports LIKE, BETWEEN, etc.)
142
+ - Supports both CQL2 JSON and CQL2 text formats with various operators
143
+ - Enables precise filtering on any collection property
144
+
145
+ - **Datetime Filtering**: Filter collections by their temporal extent using the `datetime` parameter
146
+ - Example: `/collections?datetime=2020-01-01T00:00:00Z/2020-12-31T23:59:59Z` (finds collections with temporal extents that overlap this range)
147
+ - Example: `/collections?datetime=2020-06-15T12:00:00Z` (finds collections whose temporal extent includes this specific time)
148
+ - Example: `/collections?datetime=2020-01-01T00:00:00Z/..` (finds collections with temporal extents that extend to or beyond January 1, 2020)
149
+ - Example: `/collections?datetime=../2020-12-31T23:59:59Z` (finds collections with temporal extents that begin on or before December 31, 2020)
150
+ - Collections are matched if their temporal extent overlaps with the provided datetime parameter
151
+ - This allows for efficient discovery of collections based on time periods
152
+
134
153
  These extensions make it easier to build user interfaces that display and navigate through collections efficiently.
135
154
 
136
- > **Configuration**: Collection search extensions can be disabled by setting the `ENABLE_COLLECTIONS_SEARCH` environment variable to `false`. By default, these extensions are enabled.
155
+ > **Configuration**: Collection search extensions (sorting, field selection, free text search, structured filtering, and datetime filtering) for the `/collections` endpoint can be disabled by setting the `ENABLE_COLLECTIONS_SEARCH` environment variable to `false`. By default, these extensions are enabled.
156
+ >
157
+ > **Configuration**: The custom `/collections-search` endpoint can be enabled by setting the `ENABLE_COLLECTIONS_SEARCH_ROUTE` environment variable to `true`. By default, this endpoint is **disabled**.
137
158
 
138
159
  > **Note**: Sorting is only available on fields that are indexed for sorting in Elasticsearch/OpenSearch. With the default mappings, you can sort on:
139
160
  > - `id` (keyword field)
@@ -144,6 +165,7 @@ These extensions make it easier to build user interfaces that display and naviga
144
165
  >
145
166
  > **Important**: Adding keyword fields to make text fields sortable can significantly increase the index size, especially for large text fields. Consider the storage implications when deciding which fields to make sortable.
146
167
 
168
+
147
169
  ## Package Structure
148
170
 
149
171
  This project is organized into several packages, each with a specific purpose:
@@ -156,7 +178,7 @@ This project is organized into several packages, each with a specific purpose:
156
178
  - Shared logic and utilities that improve code reuse between backends
157
179
 
158
180
  - **stac_fastapi_elasticsearch**: Complete implementation of the STAC API using Elasticsearch as the backend database. This package depends on both `stac_fastapi_core` and `sfeos_helpers`.
159
- -
181
+
160
182
  - **stac_fastapi_opensearch**: Complete implementation of the STAC API using OpenSearch as the backend database. This package depends on both `stac_fastapi_core` and `sfeos_helpers`.
161
183
 
162
184
  ## Examples
@@ -274,12 +296,13 @@ You can customize additional settings in your `.env` file:
274
296
  | `ENABLE_DIRECT_RESPONSE` | Enable direct response for maximum performance (disables all FastAPI dependencies, including authentication, custom status codes, and validation) | `false` | Optional |
275
297
  | `RAISE_ON_BULK_ERROR` | Controls whether bulk insert operations raise exceptions on errors. If set to `true`, the operation will stop and raise an exception when an error occurs. If set to `false`, errors will be logged, and the operation will continue. **Note:** STAC Item and ItemCollection validation errors will always raise, regardless of this flag. | `false` | Optional |
276
298
  | `DATABASE_REFRESH` | Controls whether database operations refresh the index immediately after changes. If set to `true`, changes will be immediately searchable. If set to `false`, changes may not be immediately visible but can improve performance for bulk operations. If set to `wait_for`, changes will wait for the next refresh cycle to become visible. | `false` | Optional |
277
- | `ENABLE_COLLECTIONS_SEARCH` | Enable collection search extensions (sort, fields). | `true` | Optional |
278
- | `ENABLE_TRANSACTIONS_EXTENSIONS` | Enables or disables the Transactions and Bulk Transactions API extensions. If set to `false`, the POST `/collections` route and related transaction endpoints (including bulk transaction operations) will be unavailable in the API. This is useful for deployments where mutating the catalog via the API should be prevented. | `true` | Optional |
299
+ | `ENABLE_COLLECTIONS_SEARCH` | Enable collection search extensions (sort, fields, free text search, structured filtering, and datetime filtering) on the core `/collections` endpoint. | `true` | Optional |
300
+ | `ENABLE_COLLECTIONS_SEARCH_ROUTE` | Enable the custom `/collections-search` endpoint (both GET and POST methods). When disabled, the custom endpoint will not be available, but collection search extensions will still be available on the core `/collections` endpoint if `ENABLE_COLLECTIONS_SEARCH` is true. | `false` | Optional |
301
+ | `ENABLE_TRANSACTIONS_EXTENSIONS` | Enables or disables the Transactions and Bulk Transactions API extensions. This is useful for deployments where mutating the catalog via the API should be prevented. If set to `true`, the POST `/collections` route for search will be unavailable in the API. | `true` | Optional |
279
302
  | `STAC_ITEM_LIMIT` | Sets the environment variable for result limiting to SFEOS for the number of returned items and STAC collections. | `10` | Optional |
280
303
  | `STAC_INDEX_ASSETS` | Controls if Assets are indexed when added to Elasticsearch/Opensearch. This allows asset fields to be included in search queries. | `false` | Optional |
281
304
  | `ENV_MAX_LIMIT` | Configures the environment variable in SFEOS to override the default `MAX_LIMIT`, which controls the limit parameter for returned items and STAC collections. | `10,000` | Optional |
282
- | `USE_DATETIME` | Configures the datetime search behavior in SFEOS. When enabled, searches both datetime field and falls back to start_datetime/end_datetime range for items with null datetime. When disabled, searches only by start_datetime/end_datetime range. | True | Optional |
305
+ | `USE_DATETIME` | Configures the datetime search behavior in SFEOS. When enabled, searches both datetime field and falls back to start_datetime/end_datetime range for items with null datetime. When disabled, searches only by start_datetime/end_datetime range. | `true` | Optional |
283
306
 
284
307
  > [!NOTE]
285
308
  > The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, `ES_VERIFY_CERTS` and `ES_TIMEOUT` apply to both Elasticsearch and OpenSearch backends, so there is no need to rename the key names to `OS_` even if you're using OpenSearch.
@@ -425,7 +448,6 @@ The system uses a precise naming convention:
425
448
  - `ENABLE_COLLECTIONS_SEARCH`: Set to `true` (default) to enable collection search extensions (sort, fields). Set to `false` to disable.
426
449
  - `ENABLE_TRANSACTIONS_EXTENSIONS`: Set to `true` (default) to enable transaction extensions. Set to `false` to disable.
427
450
 
428
-
429
451
  ## Collection Pagination
430
452
 
431
453
  - **Overview**: The collections route supports pagination through optional query parameters.
@@ -6,8 +6,8 @@ with open("README.md") as f:
6
6
  desc = f.read()
7
7
 
8
8
  install_requires = [
9
- "stac-fastapi-core==6.4.0",
10
- "sfeos-helpers==6.4.0",
9
+ "stac-fastapi-core==6.5.1",
10
+ "sfeos-helpers==6.5.1",
11
11
  "opensearch-py~=2.8.0",
12
12
  "opensearch-py[async]~=2.8.0",
13
13
  "uvicorn~=0.23.0",
@@ -23,14 +23,19 @@ from stac_fastapi.core.extensions.aggregation import (
23
23
  EsAggregationExtensionGetRequest,
24
24
  EsAggregationExtensionPostRequest,
25
25
  )
26
+ from stac_fastapi.core.extensions.collections_search import (
27
+ CollectionsSearchEndpointExtension,
28
+ )
26
29
  from stac_fastapi.core.extensions.fields import FieldsExtension
27
30
  from stac_fastapi.core.rate_limit import setup_rate_limit
28
31
  from stac_fastapi.core.route_dependencies import get_route_dependencies
29
32
  from stac_fastapi.core.session import Session
30
33
  from stac_fastapi.core.utilities import get_bool_env
31
- from stac_fastapi.extensions.core import ( # CollectionSearchFilterExtension,
34
+ from stac_fastapi.extensions.core import (
32
35
  AggregationExtension,
33
36
  CollectionSearchExtension,
37
+ CollectionSearchFilterExtension,
38
+ CollectionSearchPostExtension,
34
39
  FilterExtension,
35
40
  FreeTextExtension,
36
41
  SortExtension,
@@ -57,8 +62,14 @@ logger = logging.getLogger(__name__)
57
62
 
58
63
  TRANSACTIONS_EXTENSIONS = get_bool_env("ENABLE_TRANSACTIONS_EXTENSIONS", default=True)
59
64
  ENABLE_COLLECTIONS_SEARCH = get_bool_env("ENABLE_COLLECTIONS_SEARCH", default=True)
65
+ ENABLE_COLLECTIONS_SEARCH_ROUTE = get_bool_env(
66
+ "ENABLE_COLLECTIONS_SEARCH_ROUTE", default=False
67
+ )
60
68
  logger.info("TRANSACTIONS_EXTENSIONS is set to %s", TRANSACTIONS_EXTENSIONS)
61
69
  logger.info("ENABLE_COLLECTIONS_SEARCH is set to %s", ENABLE_COLLECTIONS_SEARCH)
70
+ logger.info(
71
+ "ENABLE_COLLECTIONS_SEARCH_ROUTE is set to %s", ENABLE_COLLECTIONS_SEARCH_ROUTE
72
+ )
62
73
 
63
74
  settings = OpensearchSettings()
64
75
  session = Session.create_from_settings(settings)
@@ -116,16 +127,18 @@ if TRANSACTIONS_EXTENSIONS:
116
127
 
117
128
  extensions = [aggregation_extension] + search_extensions
118
129
 
119
- # Create collection search extensions if enabled
120
- if ENABLE_COLLECTIONS_SEARCH:
130
+ # Collection search related variables
131
+ collections_get_request_model = None
132
+
133
+ if ENABLE_COLLECTIONS_SEARCH or ENABLE_COLLECTIONS_SEARCH_ROUTE:
121
134
  # Create collection search extensions
122
135
  collection_search_extensions = [
123
- # QueryExtension(conformance_classes=[QueryConformanceClasses.COLLECTIONS]),
136
+ QueryExtension(conformance_classes=[QueryConformanceClasses.COLLECTIONS]),
124
137
  SortExtension(conformance_classes=[SortConformanceClasses.COLLECTIONS]),
125
138
  FieldsExtension(conformance_classes=[FieldsConformanceClasses.COLLECTIONS]),
126
- # CollectionSearchFilterExtension(
127
- # conformance_classes=[FilterConformanceClasses.COLLECTIONS]
128
- # ),
139
+ CollectionSearchFilterExtension(
140
+ conformance_classes=[FilterConformanceClasses.COLLECTIONS]
141
+ ),
129
142
  FreeTextExtension(conformance_classes=[FreeTextConformanceClasses.COLLECTIONS]),
130
143
  ]
131
144
 
@@ -135,7 +148,58 @@ if ENABLE_COLLECTIONS_SEARCH:
135
148
  )
136
149
  collections_get_request_model = collection_search_ext.GET
137
150
 
151
+ # Create a post request model for collection search
152
+ collection_search_post_request_model = create_post_request_model(
153
+ collection_search_extensions
154
+ )
155
+
156
+ # Create collection search extensions if enabled
157
+ if ENABLE_COLLECTIONS_SEARCH:
158
+ # Initialize collection search POST extension
159
+ collection_search_post_ext = CollectionSearchPostExtension(
160
+ client=CoreClient(
161
+ database=database_logic,
162
+ session=session,
163
+ post_request_model=collection_search_post_request_model,
164
+ landing_page_id=os.getenv("STAC_FASTAPI_LANDING_PAGE_ID", "stac-fastapi"),
165
+ ),
166
+ settings=settings,
167
+ POST=collection_search_post_request_model,
168
+ conformance_classes=[
169
+ "https://api.stacspec.org/v1.0.0-rc.1/collection-search",
170
+ QueryConformanceClasses.COLLECTIONS,
171
+ FilterConformanceClasses.COLLECTIONS,
172
+ FreeTextConformanceClasses.COLLECTIONS,
173
+ SortConformanceClasses.COLLECTIONS,
174
+ FieldsConformanceClasses.COLLECTIONS,
175
+ ],
176
+ )
138
177
  extensions.append(collection_search_ext)
178
+ extensions.append(collection_search_post_ext)
179
+
180
+ if ENABLE_COLLECTIONS_SEARCH_ROUTE:
181
+ # Initialize collections-search endpoint extension
182
+ collections_search_endpoint_ext = CollectionsSearchEndpointExtension(
183
+ client=CoreClient(
184
+ database=database_logic,
185
+ session=session,
186
+ post_request_model=collection_search_post_request_model,
187
+ landing_page_id=os.getenv("STAC_FASTAPI_LANDING_PAGE_ID", "stac-fastapi"),
188
+ ),
189
+ settings=settings,
190
+ GET=collections_get_request_model,
191
+ POST=collection_search_post_request_model,
192
+ conformance_classes=[
193
+ "https://api.stacspec.org/v1.0.0-rc.1/collection-search",
194
+ QueryConformanceClasses.COLLECTIONS,
195
+ FilterConformanceClasses.COLLECTIONS,
196
+ FreeTextConformanceClasses.COLLECTIONS,
197
+ SortConformanceClasses.COLLECTIONS,
198
+ FieldsConformanceClasses.COLLECTIONS,
199
+ ],
200
+ )
201
+ extensions.append(collections_search_endpoint_ext)
202
+
139
203
 
140
204
  database_logic.extensions = [type(ext).__name__ for ext in extensions]
141
205
 
@@ -169,14 +233,15 @@ app_config = {
169
233
  post_request_model=post_request_model,
170
234
  landing_page_id=os.getenv("STAC_FASTAPI_LANDING_PAGE_ID", "stac-fastapi"),
171
235
  ),
236
+ "collections_get_request_model": collections_get_request_model,
172
237
  "search_get_request_model": create_get_request_model(search_extensions),
173
238
  "search_post_request_model": post_request_model,
174
239
  "items_get_request_model": items_get_request_model,
175
240
  "route_dependencies": get_route_dependencies(),
176
241
  }
177
242
 
178
- # Add collections_get_request_model if collection search is enabled
179
- if ENABLE_COLLECTIONS_SEARCH:
243
+ # Add collections_get_request_model if it was created
244
+ if collections_get_request_model:
180
245
  app_config["collections_get_request_model"] = collections_get_request_model
181
246
 
182
247
  api = StacApi(**app_config)
@@ -160,8 +160,11 @@ class DatabaseLogic(BaseDatabaseLogic):
160
160
  request: Request,
161
161
  sort: Optional[List[Dict[str, Any]]] = None,
162
162
  q: Optional[List[str]] = None,
163
- ) -> Tuple[List[Dict[str, Any]], Optional[str]]:
164
- """Retrieve a list of collections from Elasticsearch, supporting pagination.
163
+ filter: Optional[Dict[str, Any]] = None,
164
+ query: Optional[Dict[str, Dict[str, Any]]] = None,
165
+ datetime: Optional[str] = None,
166
+ ) -> Tuple[List[Dict[str, Any]], Optional[str], Optional[int]]:
167
+ """Retrieve a list of collections from OpenSearch, supporting pagination.
165
168
 
166
169
  Args:
167
170
  token (Optional[str]): The pagination token.
@@ -169,6 +172,9 @@ class DatabaseLogic(BaseDatabaseLogic):
169
172
  request (Request): The FastAPI request object.
170
173
  sort (Optional[List[Dict[str, Any]]]): Optional sort parameter from the request.
171
174
  q (Optional[List[str]]): Free text search terms.
175
+ query (Optional[Dict[str, Dict[str, Any]]]): Query extension parameters.
176
+ filter (Optional[Dict[str, Any]]): Structured query in CQL2 format.
177
+ datetime (Optional[str]): Temporal filter.
172
178
 
173
179
  Returns:
174
180
  A tuple of (collections, next pagination token if any).
@@ -206,8 +212,24 @@ class DatabaseLogic(BaseDatabaseLogic):
206
212
  "size": limit,
207
213
  }
208
214
 
215
+ # Handle search_after token - split by '|' to get all sort values
216
+ search_after = None
209
217
  if token:
210
- body["search_after"] = [token]
218
+ try:
219
+ # The token should be a pipe-separated string of sort values
220
+ # e.g., "2023-01-01T00:00:00Z|collection-1"
221
+ search_after = token.split("|")
222
+ # If the number of sort fields doesn't match token parts, ignore the token
223
+ if len(search_after) != len(formatted_sort):
224
+ search_after = None
225
+ except Exception:
226
+ search_after = None
227
+
228
+ if search_after is not None:
229
+ body["search_after"] = search_after
230
+
231
+ # Build the query part of the body
232
+ query_parts = []
211
233
 
212
234
  # Apply free text query if provided
213
235
  if q:
@@ -235,16 +257,86 @@ class DatabaseLogic(BaseDatabaseLogic):
235
257
  }
236
258
  )
237
259
 
238
- # Add the query to the body using bool query with should clauses
239
- body["query"] = {
240
- "bool": {"should": should_clauses, "minimum_should_match": 1}
241
- }
260
+ # Add the free text query to the query parts
261
+ query_parts.append(
262
+ {"bool": {"should": should_clauses, "minimum_should_match": 1}}
263
+ )
242
264
 
243
- response = await self.client.search(
244
- index=COLLECTIONS_INDEX,
245
- body=body,
265
+ # Apply structured filter if provided
266
+ if filter:
267
+ # Convert string filter to dict if needed
268
+ if isinstance(filter, str):
269
+ filter = orjson.loads(filter)
270
+ # Convert the filter to an OpenSearch query using the filter module
271
+ es_query = filter_module.to_es(await self.get_queryables_mapping(), filter)
272
+ query_parts.append(es_query)
273
+
274
+ # Apply query extension if provided
275
+ if query:
276
+ try:
277
+ # First create a search object to apply filters
278
+ search = Search(index=COLLECTIONS_INDEX)
279
+
280
+ # Process each field and operator in the query
281
+ for field_name, expr in query.items():
282
+ for op, value in expr.items():
283
+ # For collections, we don't need to prefix with 'properties__'
284
+ field = field_name
285
+ # Apply the filter using apply_stacql_filter
286
+ search = self.apply_stacql_filter(
287
+ search=search, op=op, field=field, value=value
288
+ )
289
+
290
+ # Convert the search object to a query dict and add it to query_parts
291
+ search_dict = search.to_dict()
292
+ if "query" in search_dict:
293
+ query_parts.append(search_dict["query"])
294
+
295
+ except Exception as e:
296
+ logger.error(f"Error converting query to OpenSearch: {e}")
297
+ # If there's an error, add a query that matches nothing
298
+ query_parts.append({"bool": {"must_not": {"match_all": {}}}})
299
+ raise
300
+
301
+ # Combine all query parts with AND logic if there are multiple
302
+ datetime_filter = None
303
+ if datetime:
304
+ datetime_filter = self._apply_collection_datetime_filter(datetime)
305
+ if datetime_filter:
306
+ query_parts.append(datetime_filter)
307
+
308
+ # Combine all query parts with AND logic
309
+ if query_parts:
310
+ body["query"] = (
311
+ query_parts[0]
312
+ if len(query_parts) == 1
313
+ else {"bool": {"must": query_parts}}
314
+ )
315
+
316
+ # Create a copy of the body for count query (without pagination and sorting)
317
+ count_body = body.copy()
318
+ if "search_after" in count_body:
319
+ del count_body["search_after"]
320
+ count_body["size"] = 0
321
+
322
+ # Create async tasks for both search and count
323
+ search_task = asyncio.create_task(
324
+ self.client.search(
325
+ index=COLLECTIONS_INDEX,
326
+ body=body,
327
+ )
246
328
  )
247
329
 
330
+ count_task = asyncio.create_task(
331
+ self.client.count(
332
+ index=COLLECTIONS_INDEX,
333
+ body={"query": body.get("query", {"match_all": {}})},
334
+ )
335
+ )
336
+
337
+ # Wait for search task to complete
338
+ response = await search_task
339
+
248
340
  hits = response["hits"]["hits"]
249
341
  collections = [
250
342
  self.collection_serializer.db_to_stac(
@@ -255,12 +347,26 @@ class DatabaseLogic(BaseDatabaseLogic):
255
347
 
256
348
  next_token = None
257
349
  if len(hits) == limit:
258
- # Ensure we have a valid sort value for next_token
259
350
  next_token_values = hits[-1].get("sort")
260
351
  if next_token_values:
261
- next_token = next_token_values[0]
352
+ # Join all sort values with '|' to create the token
353
+ next_token = "|".join(str(val) for val in next_token_values)
262
354
 
263
- return collections, next_token
355
+ # Get the total count of collections
356
+ matched = (
357
+ response["hits"]["total"]["value"]
358
+ if response["hits"]["total"]["relation"] == "eq"
359
+ else None
360
+ )
361
+
362
+ # If count task is done, use its result
363
+ if count_task.done():
364
+ try:
365
+ matched = count_task.result().get("count")
366
+ except Exception as e:
367
+ logger.error(f"Count task failed: {e}")
368
+
369
+ return collections, next_token, matched
264
370
 
265
371
  async def get_one_item(self, collection_id: str, item_id: str) -> Dict:
266
372
  """Retrieve a single item from the database.
@@ -276,7 +382,7 @@ class DatabaseLogic(BaseDatabaseLogic):
276
382
  NotFoundError: If the specified Item does not exist in the Collection.
277
383
 
278
384
  Notes:
279
- The Item is retrieved from the Elasticsearch database using the `client.get` method,
385
+ The Item is retrieved from the Opensearch database using the `client.get` method,
280
386
  with the index for the Collection as the target index and the combined `mk_item_id` as the document id.
281
387
  """
282
388
  try:
@@ -348,6 +454,41 @@ class DatabaseLogic(BaseDatabaseLogic):
348
454
  search=search, free_text_queries=free_text_queries
349
455
  )
350
456
 
457
+ @staticmethod
458
+ def _apply_collection_datetime_filter(
459
+ datetime_str: Optional[str],
460
+ ) -> Optional[Dict[str, Any]]:
461
+ """Create a temporal filter for collections based on their extent."""
462
+ if not datetime_str:
463
+ return None
464
+
465
+ # Parse the datetime string into start and end
466
+ if "/" in datetime_str:
467
+ start, end = datetime_str.split("/")
468
+ # Replace open-ended ranges with concrete dates
469
+ if start == "..":
470
+ # For open-ended start, use a very early date
471
+ start = "1800-01-01T00:00:00Z"
472
+ if end == "..":
473
+ # For open-ended end, use a far future date
474
+ end = "2999-12-31T23:59:59Z"
475
+ else:
476
+ # If it's just a single date, use it for both start and end
477
+ start = end = datetime_str
478
+
479
+ return {
480
+ "bool": {
481
+ "must": [
482
+ # Check if any date in the array is less than or equal to the query end date
483
+ # This will match if the collection's start date is before or equal to the query end date
484
+ {"range": {"extent.temporal.interval": {"lte": end}}},
485
+ # Check if any date in the array is greater than or equal to the query start date
486
+ # This will match if the collection's end date is after or equal to the query start date
487
+ {"range": {"extent.temporal.interval": {"gte": start}}},
488
+ ]
489
+ }
490
+ }
491
+
351
492
  @staticmethod
352
493
  def apply_datetime_filter(
353
494
  search: Search, datetime: Optional[str]
@@ -542,18 +683,31 @@ class DatabaseLogic(BaseDatabaseLogic):
542
683
 
543
684
  Args:
544
685
  search (Search): The search object to apply the filter to.
545
- op (str): The comparison operator to use. Can be 'eq' (equal), 'gt' (greater than), 'gte' (greater than or equal),
546
- 'lt' (less than), or 'lte' (less than or equal).
686
+ op (str): The comparison operator to use. Can be 'eq' (equal), 'ne'/'neq' (not equal), 'gt' (greater than),
687
+ 'gte' (greater than or equal), 'lt' (less than), or 'lte' (less than or equal).
547
688
  field (str): The field to perform the comparison on.
548
689
  value (float): The value to compare the field against.
549
690
 
550
691
  Returns:
551
692
  search (Search): The search object with the specified filter applied.
552
693
  """
553
- if op != "eq":
554
- key_filter = {field: {f"{op}": value}}
694
+ if op == "eq":
695
+ search = search.filter("term", **{field: value})
696
+ elif op == "ne" or op == "neq":
697
+ # For not equal, use a bool query with must_not
698
+ search = search.exclude("term", **{field: value})
699
+ elif op in ["gt", "gte", "lt", "lte"]:
700
+ # For range operators
701
+ key_filter = {field: {op: value}}
555
702
  search = search.filter(Q("range", **key_filter))
556
- else:
703
+ elif op == "in":
704
+ # For in operator (value should be a list)
705
+ if isinstance(value, list):
706
+ search = search.filter("terms", **{field: value})
707
+ else:
708
+ search = search.filter("term", **{field: value})
709
+ elif op == "contains":
710
+ # For contains operator (for arrays)
557
711
  search = search.filter("term", **{field: value})
558
712
 
559
713
  return search
@@ -1,2 +1,2 @@
1
1
  """library version."""
2
- __version__ = "6.4.0"
2
+ __version__ = "6.5.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stac-fastapi-opensearch
3
- Version: 6.4.0
3
+ Version: 6.5.1
4
4
  Summary: Opensearch stac-fastapi backend.
5
5
  Home-page: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
6
6
  License: MIT
@@ -87,13 +87,13 @@ This project is built on the following technologies: STAC, stac-fastapi, FastAPI
87
87
  ## Table of Contents
88
88
 
89
89
  - [stac-fastapi-elasticsearch-opensearch](#stac-fastapi-elasticsearch-opensearch)
90
- - [Sponsors \& Supporters](#sponsors--supporters)
90
+ - [Sponsors & Supporters](#sponsors--supporters)
91
91
  - [Project Introduction - What is SFEOS?](#project-introduction---what-is-sfeos)
92
92
  - [Common Deployment Patterns](#common-deployment-patterns)
93
93
  - [Technologies](#technologies)
94
94
  - [Table of Contents](#table-of-contents)
95
95
  - [Collection Search Extensions](#collection-search-extensions)
96
- - [Documentation \& Resources](#documentation--resources)
96
+ - [Documentation & Resources](#documentation--resources)
97
97
  - [Package Structure](#package-structure)
98
98
  - [Examples](#examples)
99
99
  - [Performance](#performance)
@@ -136,7 +136,11 @@ This project is built on the following technologies: STAC, stac-fastapi, FastAPI
136
136
 
137
137
  ## Collection Search Extensions
138
138
 
139
- SFEOS implements extended capabilities for the `/collections` endpoint, allowing for more powerful collection discovery:
139
+ SFEOS provides enhanced collection search capabilities through two primary routes:
140
+ - **GET/POST `/collections`**: The standard STAC endpoint with extended query parameters
141
+ - **GET/POST `/collections-search`**: A custom endpoint that supports the same parameters, created to avoid conflicts with the STAC Transactions extension if enabled (which uses POST `/collections` for collection creation)
142
+
143
+ These endpoints support advanced collection discovery features including:
140
144
 
141
145
  - **Sorting**: Sort collections by sortable fields using the `sortby` parameter
142
146
  - Example: `/collections?sortby=+id` (ascending sort by ID)
@@ -152,9 +156,26 @@ SFEOS implements extended capabilities for the `/collections` endpoint, allowing
152
156
  - Searches across multiple text fields including title, description, and keywords
153
157
  - Supports partial word matching and relevance-based sorting
154
158
 
159
+ - **Structured Filtering**: Filter collections using CQL2 expressions
160
+ - JSON format: `/collections?filter={"op":"=","args":[{"property":"id"},"sentinel-2"]}&filter-lang=cql2-json`
161
+ - Text format: `/collections?filter=id='sentinel-2'&filter-lang=cql2-text` (note: string values must be quoted)
162
+ - Advanced text format: `/collections?filter=id LIKE '%sentinel%'&filter-lang=cql2-text` (supports LIKE, BETWEEN, etc.)
163
+ - Supports both CQL2 JSON and CQL2 text formats with various operators
164
+ - Enables precise filtering on any collection property
165
+
166
+ - **Datetime Filtering**: Filter collections by their temporal extent using the `datetime` parameter
167
+ - Example: `/collections?datetime=2020-01-01T00:00:00Z/2020-12-31T23:59:59Z` (finds collections with temporal extents that overlap this range)
168
+ - Example: `/collections?datetime=2020-06-15T12:00:00Z` (finds collections whose temporal extent includes this specific time)
169
+ - Example: `/collections?datetime=2020-01-01T00:00:00Z/..` (finds collections with temporal extents that extend to or beyond January 1, 2020)
170
+ - Example: `/collections?datetime=../2020-12-31T23:59:59Z` (finds collections with temporal extents that begin on or before December 31, 2020)
171
+ - Collections are matched if their temporal extent overlaps with the provided datetime parameter
172
+ - This allows for efficient discovery of collections based on time periods
173
+
155
174
  These extensions make it easier to build user interfaces that display and navigate through collections efficiently.
156
175
 
157
- > **Configuration**: Collection search extensions can be disabled by setting the `ENABLE_COLLECTIONS_SEARCH` environment variable to `false`. By default, these extensions are enabled.
176
+ > **Configuration**: Collection search extensions (sorting, field selection, free text search, structured filtering, and datetime filtering) for the `/collections` endpoint can be disabled by setting the `ENABLE_COLLECTIONS_SEARCH` environment variable to `false`. By default, these extensions are enabled.
177
+ >
178
+ > **Configuration**: The custom `/collections-search` endpoint can be enabled by setting the `ENABLE_COLLECTIONS_SEARCH_ROUTE` environment variable to `true`. By default, this endpoint is **disabled**.
158
179
 
159
180
  > **Note**: Sorting is only available on fields that are indexed for sorting in Elasticsearch/OpenSearch. With the default mappings, you can sort on:
160
181
  > - `id` (keyword field)
@@ -165,6 +186,7 @@ These extensions make it easier to build user interfaces that display and naviga
165
186
  >
166
187
  > **Important**: Adding keyword fields to make text fields sortable can significantly increase the index size, especially for large text fields. Consider the storage implications when deciding which fields to make sortable.
167
188
 
189
+
168
190
  ## Package Structure
169
191
 
170
192
  This project is organized into several packages, each with a specific purpose:
@@ -177,7 +199,7 @@ This project is organized into several packages, each with a specific purpose:
177
199
  - Shared logic and utilities that improve code reuse between backends
178
200
 
179
201
  - **stac_fastapi_elasticsearch**: Complete implementation of the STAC API using Elasticsearch as the backend database. This package depends on both `stac_fastapi_core` and `sfeos_helpers`.
180
- -
202
+
181
203
  - **stac_fastapi_opensearch**: Complete implementation of the STAC API using OpenSearch as the backend database. This package depends on both `stac_fastapi_core` and `sfeos_helpers`.
182
204
 
183
205
  ## Examples
@@ -295,12 +317,13 @@ You can customize additional settings in your `.env` file:
295
317
  | `ENABLE_DIRECT_RESPONSE` | Enable direct response for maximum performance (disables all FastAPI dependencies, including authentication, custom status codes, and validation) | `false` | Optional |
296
318
  | `RAISE_ON_BULK_ERROR` | Controls whether bulk insert operations raise exceptions on errors. If set to `true`, the operation will stop and raise an exception when an error occurs. If set to `false`, errors will be logged, and the operation will continue. **Note:** STAC Item and ItemCollection validation errors will always raise, regardless of this flag. | `false` | Optional |
297
319
  | `DATABASE_REFRESH` | Controls whether database operations refresh the index immediately after changes. If set to `true`, changes will be immediately searchable. If set to `false`, changes may not be immediately visible but can improve performance for bulk operations. If set to `wait_for`, changes will wait for the next refresh cycle to become visible. | `false` | Optional |
298
- | `ENABLE_COLLECTIONS_SEARCH` | Enable collection search extensions (sort, fields). | `true` | Optional |
299
- | `ENABLE_TRANSACTIONS_EXTENSIONS` | Enables or disables the Transactions and Bulk Transactions API extensions. If set to `false`, the POST `/collections` route and related transaction endpoints (including bulk transaction operations) will be unavailable in the API. This is useful for deployments where mutating the catalog via the API should be prevented. | `true` | Optional |
320
+ | `ENABLE_COLLECTIONS_SEARCH` | Enable collection search extensions (sort, fields, free text search, structured filtering, and datetime filtering) on the core `/collections` endpoint. | `true` | Optional |
321
+ | `ENABLE_COLLECTIONS_SEARCH_ROUTE` | Enable the custom `/collections-search` endpoint (both GET and POST methods). When disabled, the custom endpoint will not be available, but collection search extensions will still be available on the core `/collections` endpoint if `ENABLE_COLLECTIONS_SEARCH` is true. | `false` | Optional |
322
+ | `ENABLE_TRANSACTIONS_EXTENSIONS` | Enables or disables the Transactions and Bulk Transactions API extensions. This is useful for deployments where mutating the catalog via the API should be prevented. If set to `true`, the POST `/collections` route for search will be unavailable in the API. | `true` | Optional |
300
323
  | `STAC_ITEM_LIMIT` | Sets the environment variable for result limiting to SFEOS for the number of returned items and STAC collections. | `10` | Optional |
301
324
  | `STAC_INDEX_ASSETS` | Controls if Assets are indexed when added to Elasticsearch/Opensearch. This allows asset fields to be included in search queries. | `false` | Optional |
302
325
  | `ENV_MAX_LIMIT` | Configures the environment variable in SFEOS to override the default `MAX_LIMIT`, which controls the limit parameter for returned items and STAC collections. | `10,000` | Optional |
303
- | `USE_DATETIME` | Configures the datetime search behavior in SFEOS. When enabled, searches both datetime field and falls back to start_datetime/end_datetime range for items with null datetime. When disabled, searches only by start_datetime/end_datetime range. | True | Optional |
326
+ | `USE_DATETIME` | Configures the datetime search behavior in SFEOS. When enabled, searches both datetime field and falls back to start_datetime/end_datetime range for items with null datetime. When disabled, searches only by start_datetime/end_datetime range. | `true` | Optional |
304
327
 
305
328
  > [!NOTE]
306
329
  > The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, `ES_VERIFY_CERTS` and `ES_TIMEOUT` apply to both Elasticsearch and OpenSearch backends, so there is no need to rename the key names to `OS_` even if you're using OpenSearch.
@@ -446,7 +469,6 @@ The system uses a precise naming convention:
446
469
  - `ENABLE_COLLECTIONS_SEARCH`: Set to `true` (default) to enable collection search extensions (sort, fields). Set to `false` to disable.
447
470
  - `ENABLE_TRANSACTIONS_EXTENSIONS`: Set to `true` (default) to enable transaction extensions. Set to `false` to disable.
448
471
 
449
-
450
472
  ## Collection Pagination
451
473
 
452
474
  - **Overview**: The collections route supports pagination through optional query parameters.
@@ -1,5 +1,5 @@
1
- stac-fastapi-core==6.4.0
2
- sfeos-helpers==6.4.0
1
+ stac-fastapi-core==6.5.1
2
+ sfeos-helpers==6.5.1
3
3
  opensearch-py~=2.8.0
4
4
  opensearch-py[async]~=2.8.0
5
5
  uvicorn~=0.23.0