Skip to content

Commit c806fdc

Browse files
authored
Merge branch 'main' into get-collections-search-sort
2 parents 71445b2 + b80cf30 commit c806fdc

File tree

5 files changed

+36
-39
lines changed

5 files changed

+36
-39
lines changed

CHANGELOG.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8-
98
## [Unreleased]
109

1110
### Added
@@ -14,6 +13,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1413

1514
### Changed
1615

16+
- Fixed a bug where missing `copy()` caused default queryables to be incorrectly enriched by results from previous queries. [#427](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/427)
17+
- Removed non-generic attributes (`cloud_cover`, `cloud_shadow_percentage`, `nodata_pixel_percentage`) not applicable to all collections (e.g., SAR data).[#427](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/427)
18+
- Updated `async_prep_create_item` to support OS item loading with multiple indices.[#427](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/427)
19+
- unified the type of queryables endpoint to `application/schema+json`. [#445](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/445)
1720
- updated `numReturned` & `numMatched` fields in itemCollection return to `numberReturned` & `numberMatched`. [#446](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/446)
1821

1922
## [v6.3.0] - 2025-09-16
@@ -49,7 +52,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
4952

5053
## [v6.2.0] - 2025-08-27
5154

52-
### Added
55+
### Added
5356

5457
- Added comprehensive index management system with dynamic selection and insertion strategies for improved performance and scalability [#405](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/405)
5558
- Added `ENABLE_DATETIME_INDEX_FILTERING` environment variable to enable datetime-based index selection using collection IDs. When enabled, the system creates indexes with UUID-based names and manages them through time-based aliases. Default is `false`. [#405](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/405)
@@ -83,7 +86,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
8386
### Added
8487

8588
- Added the ability to set timeout for Opensearch and Elasticsearch clients by setting the environmental variable `ES_TIMEOUT` [#408](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/408)
86-
- Added `collection-search#filter` conformance class to CollectionSearchExtension to enable compatibility with stac-auth-proxy collection filtering [#411](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/411)
89+
- Added `collection-search#filter` conformance class to CollectionSearchExtension to enable compatibility with stac-auth-proxy collection filtering [#411](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/411)
8790

8891
### Changed
8992

@@ -95,7 +98,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
9598

9699
### Added
97100

98-
- Added support for PATCH update through [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) and [RFC 7396](https://datatracker.ietf.org/doc/html/rfc7396) [#291](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/291)
101+
- Added support for PATCH update through [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) and [RFC 7396](https://datatracker.ietf.org/doc/html/rfc7396) [#291](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/291)
99102

100103
### Changed
101104

@@ -137,7 +140,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
137140

138141
- Removed `requests` dev dependency [#395](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/395)
139142

140-
141143
## [v4.2.0] - 2025-05-15
142144

143145
### Added
@@ -180,12 +182,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
180182
## [v4.0.0] - 2025-04-23
181183

182184
### Added
185+
183186
- Added support for dynamically-generated queryables based on Elasticsearch/OpenSearch mappings, with extensible metadata augmentation [#351](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/351)
184187
- Included default queryables configuration for seamless integration. [#351](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/351)
185188
- Added support for high-performance direct response mode for both Elasticsearch and Opensearch backends, controlled by the `ENABLE_DIRECT_RESPONSE` environment variable. When enabled (`ENABLE_DIRECT_RESPONSE=true`), endpoints return Starlette Response objects directly, bypassing FastAPI's jsonable_encoder and Pydantic serialization for significantly improved performance on large search responses. **Note:** In this mode, all FastAPI dependencies (including authentication, custom status codes, and validation) are disabled for all routes. Default is `false` for safety. A warning is logged at startup if enabled. See [issue #347](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/issues/347) and [PR #359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359).
186189
- Added robust tests for the `ENABLE_DIRECT_RESPONSE` environment variable, covering both Elasticsearch and OpenSearch backends. Tests gracefully handle missing backends by attempting to import both configs and skipping if neither is available. [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
187190

188191
### Changed
192+
189193
- Refactored database logic to reduce duplication [#351](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/351)
190194
- Replaced `fastapi-slim` with `fastapi` dependency [#351](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/351)
191195
- Changed minimum Python version to 3.9 [#354](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/354)
@@ -211,6 +215,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
211215
- Refactored all boolean environment variable parsing in both Elasticsearch and OpenSearch backends to use the shared `get_bool_env` utility. This ensures robust and consistent handling of environment variables such as `ES_USE_SSL`, `ES_HTTP_COMPRESS`, and `ES_VERIFY_CERTS` across both backends. [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
212216

213217
### Fixed
218+
214219
- Improved performance of `mk_actions` and `filter-links` methods [#351](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/351)
215220
- Fixed inheritance relating to BaseDatabaseSettings and ApiBaseSettings [#355](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/355)
216221
- Fixed delete_item and delete_collection methods return types [#355](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/355)

stac_fastapi/core/stac_fastapi/core/extensions/filter.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,24 +41,6 @@
4141
"description": "Creation Timestamp",
4242
"$ref": "https://schemas.stacspec.org/v1.0.0/item-spec/json-schema/datetime.json#/properties/updated",
4343
},
44-
"cloud_cover": {
45-
"description": "Cloud Cover",
46-
"$ref": "https://stac-extensions.github.io/eo/v1.0.0/schema.json#/definitions/fields/properties/eo:cloud_cover",
47-
},
48-
"cloud_shadow_percentage": {
49-
"title": "Cloud Shadow Percentage",
50-
"description": "Cloud Shadow Percentage",
51-
"type": "number",
52-
"minimum": 0,
53-
"maximum": 100,
54-
},
55-
"nodata_pixel_percentage": {
56-
"title": "No Data Pixel Percentage",
57-
"description": "No Data Pixel Percentage",
58-
"type": "number",
59-
"minimum": 0,
60-
"maximum": 100,
61-
},
6244
}
6345
"""Queryables that are present in all collections."""
6446

stac_fastapi/core/stac_fastapi/core/models/links.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def link_queryables(self) -> Dict[str, Any]:
139139
if "FilterExtension" in self.extensions:
140140
return dict(
141141
rel="queryables",
142-
type=MimeTypes.json.value,
142+
type=MimeTypes.jsonschema.value,
143143
href=urljoin(
144144
self.base_url, f"collections/{self.collection_id}/queryables"
145145
),

stac_fastapi/opensearch/stac_fastapi/opensearch/database_logic.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
import asyncio
44
import logging
55
from base64 import urlsafe_b64decode, urlsafe_b64encode
6+
from collections.abc import Iterable
67
from copy import deepcopy
7-
from typing import Any, Dict, Iterable, List, Optional, Tuple, Type
8+
from typing import Any, Dict, List, Optional, Tuple, Type
89

910
import attr
1011
import orjson
@@ -695,14 +696,21 @@ async def async_prep_create_item(
695696
696697
"""
697698
await self.check_collection_exists(collection_id=item["collection"])
699+
alias = index_alias_by_collection_id(item["collection"])
700+
doc_id = mk_item_id(item["id"], item["collection"])
698701

699-
if not exist_ok and await self.client.exists(
700-
index=index_alias_by_collection_id(item["collection"]),
701-
id=mk_item_id(item["id"], item["collection"]),
702-
):
703-
raise ConflictError(
704-
f"Item {item['id']} in collection {item['collection']} already exists"
705-
)
702+
if not exist_ok:
703+
alias_exists = await self.client.indices.exists_alias(name=alias)
704+
705+
if alias_exists:
706+
alias_info = await self.client.indices.get_alias(name=alias)
707+
indices = list(alias_info.keys())
708+
709+
for index in indices:
710+
if await self.client.exists(index=index, id=doc_id):
711+
raise ConflictError(
712+
f"Item {item['id']} in collection {item['collection']} already exists"
713+
)
706714

707715
return self.item_serializer.stac_to_db(item, base_url)
708716

@@ -919,7 +927,6 @@ async def json_patch_item(
919927
"add",
920928
"replace",
921929
]:
922-
923930
if operation.path == "collection" and collection_id != operation.value:
924931
await self.check_collection_exists(collection_id=operation.value)
925932
new_collection_id = operation.value
@@ -973,8 +980,8 @@ async def json_patch_item(
973980
"script": {
974981
"lang": "painless",
975982
"source": (
976-
f"""ctx._id = ctx._id.replace('{collection_id}', '{new_collection_id}');""" # noqa: E702
977-
f"""ctx._source.collection = '{new_collection_id}';""" # noqa: E702
983+
f"""ctx._id = ctx._id.replace('{collection_id}', '{new_collection_id}');"""
984+
f"""ctx._source.collection = '{new_collection_id}';"""
978985
),
979986
},
980987
},
@@ -1196,7 +1203,7 @@ async def update_collection(
11961203
"source": {"index": f"{ITEMS_INDEX_PREFIX}{collection_id}"},
11971204
"script": {
11981205
"lang": "painless",
1199-
"source": f"""ctx._id = ctx._id.replace('{collection_id}', '{collection["id"]}'); ctx._source.collection = '{collection["id"]}' ;""", # noqa: E702
1206+
"source": f"""ctx._id = ctx._id.replace('{collection_id}', '{collection["id"]}'); ctx._source.collection = '{collection["id"]}' ;""",
12001207
},
12011208
},
12021209
wait_for_completion=True,

stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/filter/client.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Any, Dict, Optional, Tuple
55

66
import attr
7+
from fastapi import Request
78

89
from stac_fastapi.core.base_database_logic import BaseDatabaseLogic
910
from stac_fastapi.core.extensions.filter import ALL_QUERYABLES, DEFAULT_QUERYABLES
@@ -37,9 +38,11 @@ async def get_queryables(
3738
Returns:
3839
Dict[str, Any]: A dictionary containing the queryables for the given collection.
3940
"""
41+
request: Optional[Request] = kwargs.get("request")
42+
url_str: str = str(request.url) if request else ""
4043
queryables: Dict[str, Any] = {
41-
"$schema": "https://json-schema.org/draft/2019-09/schema",
42-
"$id": "https://stac-api.example.com/queryables",
44+
"$schema": "https://json-schema.org/draft-07/schema",
45+
"$id": f"{url_str}",
4346
"type": "object",
4447
"title": "Queryables for STAC API",
4548
"description": "Queryable names for the STAC API Item Search filter.",
@@ -49,7 +52,7 @@ async def get_queryables(
4952
if not collection_id:
5053
return queryables
5154

52-
properties: Dict[str, Any] = queryables["properties"]
55+
properties: Dict[str, Any] = queryables["properties"].copy()
5356
queryables.update(
5457
{
5558
"properties": properties,

0 commit comments

Comments
 (0)