Skip to content

Commit 3aba909

Browse files
Merge branch 'main' into CAT-1558
2 parents 39f84fb + f834a9e commit 3aba909

File tree

11 files changed

+103
-16
lines changed

11 files changed

+103
-16
lines changed

CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
### Added
1111

12+
### Changed
13+
14+
### Fixed
15+
16+
### Removed
17+
18+
### Updated
19+
20+
## [v6.7.0] - 2025-10-27
21+
22+
### Added
23+
1224
- Environment variable `EXCLUDED_FROM_QUERYABLES` to exclude specific fields from queryables endpoint and filtering. Supports comma-separated list of fully qualified field names (e.g., `properties.auth:schemes,properties.storage:schemes`) [#489](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/489)
1325
- Added Redis caching configuration for navigation pagination support, enabling proper `prev` and `next` links in paginated responses. [#488](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/488)
1426

1527
### Changed
1628

1729
### Fixed
1830

31+
- Fixed filter parameter handling for GET `/collections-search` endpoint. Filter parameters (`filter` and `filter-lang`) are now properly passed through and processed. [#511](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/511)
32+
- Fixed `q` parameter in GET `/collections-search` endpoint to be converted to a list format, matching the behavior of the `/collections` endpoint for consistency. [#511](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/511)
33+
1934
### Removed
2035

2136
### Updated
@@ -594,7 +609,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
594609
- Use genexp in execute_search and get_all_collections to return results.
595610
- Added db_to_stac serializer to item_collection method in core.py.
596611

597-
[Unreleased]: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/compare/v6.6.0...main
612+
[Unreleased]: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/compare/v6.7.0...main
613+
[v6.7.0]: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/compare/v6.6.0...v6.7.0
598614
[v6.6.0]: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/compare/v6.5.1...v6.6.0
599615
[v6.5.1]: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/compare/v6.5.0...v6.5.1
600616
[v6.5.0]: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/compare/v6.4.0...v6.5.0

stac_fastapi/core/stac_fastapi/core/extensions/collections_search.py

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@ class CollectionsSearchRequest(ExtendedSearch):
2222
query: Optional[
2323
str
2424
] = None # Legacy query extension (deprecated but still supported)
25+
filter_expr: Optional[str] = None
26+
filter_lang: Optional[str] = None
2527

2628

2729
def build_get_collections_search_doc(original_endpoint):
2830
"""Return a documented GET endpoint wrapper for /collections-search."""
2931

3032
async def documented_endpoint(
3133
request: Request,
32-
q: Optional[str] = Query(
34+
q: Optional[Union[str, List[str]]] = Query(
3335
None,
3436
description="Free text search query",
3537
),
@@ -76,9 +78,63 @@ async def documented_endpoint(
7678
),
7779
alias="fields[]",
7880
),
81+
filter: Optional[str] = Query(
82+
None,
83+
description=(
84+
"Structured filter expression in CQL2 JSON or CQL2-text format"
85+
),
86+
example='{"op": "=", "args": [{"property": "properties.category"}, "level2"]}',
87+
),
88+
filter_lang: Optional[str] = Query(
89+
None,
90+
description=(
91+
"Filter language. Must be 'cql2-json' or 'cql2-text' if specified"
92+
),
93+
example="cql2-json",
94+
),
7995
):
80-
# Delegate to original endpoint which reads from request.query_params
81-
return await original_endpoint(request)
96+
# Delegate to original endpoint with parameters
97+
# Since FastAPI extracts parameters from the URL when they're defined as function parameters,
98+
# we need to create a request wrapper that provides our modified query_params
99+
100+
# Create a mutable copy of query_params
101+
if hasattr(request, "_query_params"):
102+
query_params = dict(request._query_params)
103+
else:
104+
query_params = dict(request.query_params)
105+
106+
# Add q parameter back to query_params if it was provided
107+
# Convert to list format to match /collections behavior
108+
if q is not None:
109+
if isinstance(q, str):
110+
# Single string should become a list with one element
111+
query_params["q"] = [q]
112+
elif isinstance(q, list):
113+
# Already a list, use as-is
114+
query_params["q"] = q
115+
116+
# Add filter parameters back to query_params if they were provided
117+
if filter is not None:
118+
query_params["filter"] = filter
119+
if filter_lang is not None:
120+
query_params["filter-lang"] = filter_lang
121+
122+
# Create a request wrapper that provides our modified query_params
123+
class RequestWrapper:
124+
def __init__(self, original_request, modified_query_params):
125+
self._original = original_request
126+
self._query_params = modified_query_params
127+
128+
@property
129+
def query_params(self):
130+
return self._query_params
131+
132+
def __getattr__(self, name):
133+
# Delegate all other attributes to the original request
134+
return getattr(self._original, name)
135+
136+
wrapped_request = RequestWrapper(request, query_params)
137+
return await original_endpoint(wrapped_request)
82138

83139
documented_endpoint.__name__ = original_endpoint.__name__
84140
return documented_endpoint
@@ -95,6 +151,8 @@ async def documented_post_endpoint(
95151
"Search parameters for collections.\n\n"
96152
"- `q`: Free text search query (string or list of strings)\n"
97153
"- `query`: Additional filtering expressed as a string (legacy support)\n"
154+
"- `filter`: Structured filter expression in CQL2 JSON or CQL2-text format\n"
155+
"- `filter_lang`: Filter language. Must be 'cql2-json' or 'cql2-text' if specified\n"
98156
"- `limit`: Maximum number of results to return (default: 10)\n"
99157
"- `token`: Pagination token for the next page of results\n"
100158
"- `bbox`: Bounding box [minx, miny, maxx, maxy] or [minx, miny, minz, maxx, maxy, maxz]\n"
@@ -105,6 +163,11 @@ async def documented_post_endpoint(
105163
example={
106164
"q": "landsat",
107165
"query": "platform=landsat AND collection_category=level2",
166+
"filter": {
167+
"op": "=",
168+
"args": [{"property": "properties.category"}, "level2"],
169+
},
170+
"filter_lang": "cql2-json",
108171
"limit": 10,
109172
"token": "next-page-token",
110173
"bbox": [-180, -90, 180, 90],
@@ -243,6 +306,14 @@ async def collections_search_get_endpoint(
243306
sortby = sortby_str.split(",")
244307
params["sortby"] = sortby
245308

309+
# Handle filter parameter mapping (fixed for collections-search)
310+
if "filter" in params:
311+
params["filter_expr"] = params.pop("filter")
312+
313+
# Handle filter-lang parameter mapping (fixed for collections-search)
314+
if "filter-lang" in params:
315+
params["filter_lang"] = params.pop("filter-lang")
316+
246317
collections = await self.client.all_collections(request=request, **params)
247318
return collections
248319

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""library version."""
2-
__version__ = "6.6.0"
2+
__version__ = "6.7.0"

stac_fastapi/elasticsearch/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ keywords = [
3030
]
3131
dynamic = ["version"]
3232
dependencies = [
33-
"stac-fastapi-core==6.6.0",
34-
"sfeos-helpers==6.6.0",
33+
"stac-fastapi-core==6.7.0",
34+
"sfeos-helpers==6.7.0",
3535
"elasticsearch[async]~=8.19.1",
3636
"uvicorn~=0.23.0",
3737
"starlette>=0.35.0,<0.36.0",

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/app.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
FieldsConformanceClasses.COLLECTIONS,
199199
],
200200
)
201+
extensions.append(collection_search_ext)
201202
extensions.append(collections_search_endpoint_ext)
202203

203204

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""library version."""
2-
__version__ = "6.6.0"
2+
__version__ = "6.7.0"

stac_fastapi/opensearch/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ keywords = [
3030
]
3131
dynamic = ["version"]
3232
dependencies = [
33-
"stac-fastapi-core==6.6.0",
34-
"sfeos-helpers==6.6.0",
33+
"stac-fastapi-core==6.7.0",
34+
"sfeos-helpers==6.7.0",
3535
"opensearch-py~=2.8.0",
3636
"opensearch-py[async]~=2.8.0",
3737
"uvicorn~=0.23.0",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""library version."""
2-
__version__ = "6.6.0"
2+
__version__ = "6.7.0"

stac_fastapi/sfeos_helpers/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ keywords = [
3131
]
3232
dynamic = ["version"]
3333
dependencies = [
34-
"stac-fastapi.core==6.6.0",
34+
"stac-fastapi.core==6.7.0",
3535
]
3636

3737
[project.urls]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""library version."""
2-
__version__ = "6.6.0"
2+
__version__ = "6.7.0"

0 commit comments

Comments
 (0)