sfeos-helpers 5.0.0a1__tar.gz → 6.1.0__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.
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/PKG-INFO +15 -13
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/README.md +14 -12
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/setup.py +1 -1
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/sfeos_helpers.egg-info/PKG-INFO +15 -13
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/sfeos_helpers.egg-info/SOURCES.txt +2 -1
- sfeos_helpers-6.1.0/sfeos_helpers.egg-info/requires.txt +1 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/query.py +32 -0
- sfeos_helpers-6.1.0/stac_fastapi/sfeos_helpers/database/utils.py +248 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/filter/client.py +23 -14
- sfeos_helpers-6.1.0/stac_fastapi/sfeos_helpers/models/patch.py +166 -0
- sfeos_helpers-6.1.0/stac_fastapi/sfeos_helpers/version.py +2 -0
- sfeos_helpers-5.0.0a1/sfeos_helpers.egg-info/requires.txt +0 -1
- sfeos_helpers-5.0.0a1/stac_fastapi/sfeos_helpers/database/utils.py +0 -50
- sfeos_helpers-5.0.0a1/stac_fastapi/sfeos_helpers/version.py +0 -2
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/setup.cfg +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/sfeos_helpers.egg-info/dependency_links.txt +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/sfeos_helpers.egg-info/not-zip-safe +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/sfeos_helpers.egg-info/top_level.txt +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/aggregation/__init__.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/aggregation/client.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/aggregation/format.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/__init__.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/datetime.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/document.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/index.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/mapping.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/filter/__init__.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/filter/cql2.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/filter/transform.py +0 -0
- {sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/mappings.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sfeos_helpers
|
|
3
|
-
Version:
|
|
3
|
+
Version: 6.1.0
|
|
4
4
|
Summary: Helper library for the Elasticsearch and Opensearch stac-fastapi backends.
|
|
5
5
|
Home-page: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
|
|
6
6
|
License: MIT
|
|
@@ -33,7 +33,7 @@ Description-Content-Type: text/markdown
|
|
|
33
33
|
[](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/network/members)
|
|
34
34
|
[](https://pypi.org/project/stac-fastapi-elasticsearch/)
|
|
35
35
|
[](https://github.com/radiantearth/stac-spec/tree/v1.1.0)
|
|
36
|
-
[](https://github.com/stac-utils/stac-fastapi)
|
|
37
37
|
|
|
38
38
|
## Sponsors & Supporters
|
|
39
39
|
|
|
@@ -223,28 +223,30 @@ You can customize additional settings in your `.env` file:
|
|
|
223
223
|
|------------------------------|--------------------------------------------------------------------------------------|--------------------------|---------------------------------------------------------------------------------------------|
|
|
224
224
|
| `ES_HOST` | Hostname for external Elasticsearch/OpenSearch. | `localhost` | Optional |
|
|
225
225
|
| `ES_PORT` | Port for Elasticsearch/OpenSearch. | `9200` (ES) / `9202` (OS)| Optional |
|
|
226
|
-
| `ES_USE_SSL` | Use SSL for connecting to Elasticsearch/OpenSearch. | `
|
|
227
|
-
| `ES_VERIFY_CERTS` | Verify SSL certificates when connecting. | `
|
|
226
|
+
| `ES_USE_SSL` | Use SSL for connecting to Elasticsearch/OpenSearch. | `true` | Optional |
|
|
227
|
+
| `ES_VERIFY_CERTS` | Verify SSL certificates when connecting. | `true` | Optional |
|
|
228
|
+
| `ES_API_KEY` | API Key for external Elasticsearch/OpenSearch. | N/A | Optional |
|
|
229
|
+
| `ES_TIMEOUT` | Client timeout for Elasticsearch/OpenSearch. | DB client default | Optional |
|
|
228
230
|
| `STAC_FASTAPI_TITLE` | Title of the API in the documentation. | `stac-fastapi-<backend>` | Optional |
|
|
229
231
|
| `STAC_FASTAPI_DESCRIPTION` | Description of the API in the documentation. | N/A | Optional |
|
|
230
232
|
| `STAC_FASTAPI_VERSION` | API version. | `2.1` | Optional |
|
|
231
|
-
| `STAC_FASTAPI_LANDING_PAGE_ID` | Landing page ID
|
|
233
|
+
| `STAC_FASTAPI_LANDING_PAGE_ID` | Landing page ID | `stac-fastapi` | Optional |
|
|
232
234
|
| `APP_HOST` | Server bind address. | `0.0.0.0` | Optional |
|
|
233
|
-
| `APP_PORT` | Server port. | `
|
|
235
|
+
| `APP_PORT` | Server port. | `8000` | Optional |
|
|
234
236
|
| `ENVIRONMENT` | Runtime environment. | `local` | Optional |
|
|
235
237
|
| `WEB_CONCURRENCY` | Number of worker processes. | `10` | Optional |
|
|
236
238
|
| `RELOAD` | Enable auto-reload for development. | `true` | Optional |
|
|
237
239
|
| `STAC_FASTAPI_RATE_LIMIT` | API rate limit per client. | `200/minute` | Optional |
|
|
238
|
-
| `BACKEND` | Tests-related variable | `elasticsearch` or `opensearch` based on the backend | Optional
|
|
239
|
-
| `ELASTICSEARCH_VERSION`
|
|
240
|
-
| `OPENSEARCH_VERSION` | OpenSearch version | `2.11.1` | Optional
|
|
241
|
-
| `ENABLE_DIRECT_RESPONSE`
|
|
242
|
-
| `RAISE_ON_BULK_ERROR`
|
|
243
|
-
| `DATABASE_REFRESH`
|
|
240
|
+
| `BACKEND` | Tests-related variable | `elasticsearch` or `opensearch` based on the backend | Optional |
|
|
241
|
+
| `ELASTICSEARCH_VERSION` | Version of Elasticsearch to use. | `8.11.0` | Optional |
|
|
242
|
+
| `OPENSEARCH_VERSION` | OpenSearch version | `2.11.1` | Optional |
|
|
243
|
+
| `ENABLE_DIRECT_RESPONSE` | Enable direct response for maximum performance (disables all FastAPI dependencies, including authentication, custom status codes, and validation) | `false` | Optional |
|
|
244
|
+
| `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 |
|
|
245
|
+
| `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 |
|
|
244
246
|
| `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 |
|
|
245
247
|
|
|
246
248
|
> [!NOTE]
|
|
247
|
-
> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `
|
|
249
|
+
> 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.
|
|
248
250
|
|
|
249
251
|
## Interacting with the API
|
|
250
252
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
[](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/network/members)
|
|
16
16
|
[](https://pypi.org/project/stac-fastapi-elasticsearch/)
|
|
17
17
|
[](https://github.com/radiantearth/stac-spec/tree/v1.1.0)
|
|
18
|
-
[](https://github.com/stac-utils/stac-fastapi)
|
|
19
19
|
|
|
20
20
|
## Sponsors & Supporters
|
|
21
21
|
|
|
@@ -205,28 +205,30 @@ You can customize additional settings in your `.env` file:
|
|
|
205
205
|
|------------------------------|--------------------------------------------------------------------------------------|--------------------------|---------------------------------------------------------------------------------------------|
|
|
206
206
|
| `ES_HOST` | Hostname for external Elasticsearch/OpenSearch. | `localhost` | Optional |
|
|
207
207
|
| `ES_PORT` | Port for Elasticsearch/OpenSearch. | `9200` (ES) / `9202` (OS)| Optional |
|
|
208
|
-
| `ES_USE_SSL` | Use SSL for connecting to Elasticsearch/OpenSearch. | `
|
|
209
|
-
| `ES_VERIFY_CERTS` | Verify SSL certificates when connecting. | `
|
|
208
|
+
| `ES_USE_SSL` | Use SSL for connecting to Elasticsearch/OpenSearch. | `true` | Optional |
|
|
209
|
+
| `ES_VERIFY_CERTS` | Verify SSL certificates when connecting. | `true` | Optional |
|
|
210
|
+
| `ES_API_KEY` | API Key for external Elasticsearch/OpenSearch. | N/A | Optional |
|
|
211
|
+
| `ES_TIMEOUT` | Client timeout for Elasticsearch/OpenSearch. | DB client default | Optional |
|
|
210
212
|
| `STAC_FASTAPI_TITLE` | Title of the API in the documentation. | `stac-fastapi-<backend>` | Optional |
|
|
211
213
|
| `STAC_FASTAPI_DESCRIPTION` | Description of the API in the documentation. | N/A | Optional |
|
|
212
214
|
| `STAC_FASTAPI_VERSION` | API version. | `2.1` | Optional |
|
|
213
|
-
| `STAC_FASTAPI_LANDING_PAGE_ID` | Landing page ID
|
|
215
|
+
| `STAC_FASTAPI_LANDING_PAGE_ID` | Landing page ID | `stac-fastapi` | Optional |
|
|
214
216
|
| `APP_HOST` | Server bind address. | `0.0.0.0` | Optional |
|
|
215
|
-
| `APP_PORT` | Server port. | `
|
|
217
|
+
| `APP_PORT` | Server port. | `8000` | Optional |
|
|
216
218
|
| `ENVIRONMENT` | Runtime environment. | `local` | Optional |
|
|
217
219
|
| `WEB_CONCURRENCY` | Number of worker processes. | `10` | Optional |
|
|
218
220
|
| `RELOAD` | Enable auto-reload for development. | `true` | Optional |
|
|
219
221
|
| `STAC_FASTAPI_RATE_LIMIT` | API rate limit per client. | `200/minute` | Optional |
|
|
220
|
-
| `BACKEND` | Tests-related variable | `elasticsearch` or `opensearch` based on the backend | Optional
|
|
221
|
-
| `ELASTICSEARCH_VERSION`
|
|
222
|
-
| `OPENSEARCH_VERSION` | OpenSearch version | `2.11.1` | Optional
|
|
223
|
-
| `ENABLE_DIRECT_RESPONSE`
|
|
224
|
-
| `RAISE_ON_BULK_ERROR`
|
|
225
|
-
| `DATABASE_REFRESH`
|
|
222
|
+
| `BACKEND` | Tests-related variable | `elasticsearch` or `opensearch` based on the backend | Optional |
|
|
223
|
+
| `ELASTICSEARCH_VERSION` | Version of Elasticsearch to use. | `8.11.0` | Optional |
|
|
224
|
+
| `OPENSEARCH_VERSION` | OpenSearch version | `2.11.1` | Optional |
|
|
225
|
+
| `ENABLE_DIRECT_RESPONSE` | Enable direct response for maximum performance (disables all FastAPI dependencies, including authentication, custom status codes, and validation) | `false` | Optional |
|
|
226
|
+
| `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 |
|
|
227
|
+
| `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 |
|
|
226
228
|
| `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 |
|
|
227
229
|
|
|
228
230
|
> [!NOTE]
|
|
229
|
-
> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `
|
|
231
|
+
> 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.
|
|
230
232
|
|
|
231
233
|
## Interacting with the API
|
|
232
234
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sfeos-helpers
|
|
3
|
-
Version:
|
|
3
|
+
Version: 6.1.0
|
|
4
4
|
Summary: Helper library for the Elasticsearch and Opensearch stac-fastapi backends.
|
|
5
5
|
Home-page: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
|
|
6
6
|
License: MIT
|
|
@@ -33,7 +33,7 @@ Description-Content-Type: text/markdown
|
|
|
33
33
|
[](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/network/members)
|
|
34
34
|
[](https://pypi.org/project/stac-fastapi-elasticsearch/)
|
|
35
35
|
[](https://github.com/radiantearth/stac-spec/tree/v1.1.0)
|
|
36
|
-
[](https://github.com/stac-utils/stac-fastapi)
|
|
37
37
|
|
|
38
38
|
## Sponsors & Supporters
|
|
39
39
|
|
|
@@ -223,28 +223,30 @@ You can customize additional settings in your `.env` file:
|
|
|
223
223
|
|------------------------------|--------------------------------------------------------------------------------------|--------------------------|---------------------------------------------------------------------------------------------|
|
|
224
224
|
| `ES_HOST` | Hostname for external Elasticsearch/OpenSearch. | `localhost` | Optional |
|
|
225
225
|
| `ES_PORT` | Port for Elasticsearch/OpenSearch. | `9200` (ES) / `9202` (OS)| Optional |
|
|
226
|
-
| `ES_USE_SSL` | Use SSL for connecting to Elasticsearch/OpenSearch. | `
|
|
227
|
-
| `ES_VERIFY_CERTS` | Verify SSL certificates when connecting. | `
|
|
226
|
+
| `ES_USE_SSL` | Use SSL for connecting to Elasticsearch/OpenSearch. | `true` | Optional |
|
|
227
|
+
| `ES_VERIFY_CERTS` | Verify SSL certificates when connecting. | `true` | Optional |
|
|
228
|
+
| `ES_API_KEY` | API Key for external Elasticsearch/OpenSearch. | N/A | Optional |
|
|
229
|
+
| `ES_TIMEOUT` | Client timeout for Elasticsearch/OpenSearch. | DB client default | Optional |
|
|
228
230
|
| `STAC_FASTAPI_TITLE` | Title of the API in the documentation. | `stac-fastapi-<backend>` | Optional |
|
|
229
231
|
| `STAC_FASTAPI_DESCRIPTION` | Description of the API in the documentation. | N/A | Optional |
|
|
230
232
|
| `STAC_FASTAPI_VERSION` | API version. | `2.1` | Optional |
|
|
231
|
-
| `STAC_FASTAPI_LANDING_PAGE_ID` | Landing page ID
|
|
233
|
+
| `STAC_FASTAPI_LANDING_PAGE_ID` | Landing page ID | `stac-fastapi` | Optional |
|
|
232
234
|
| `APP_HOST` | Server bind address. | `0.0.0.0` | Optional |
|
|
233
|
-
| `APP_PORT` | Server port. | `
|
|
235
|
+
| `APP_PORT` | Server port. | `8000` | Optional |
|
|
234
236
|
| `ENVIRONMENT` | Runtime environment. | `local` | Optional |
|
|
235
237
|
| `WEB_CONCURRENCY` | Number of worker processes. | `10` | Optional |
|
|
236
238
|
| `RELOAD` | Enable auto-reload for development. | `true` | Optional |
|
|
237
239
|
| `STAC_FASTAPI_RATE_LIMIT` | API rate limit per client. | `200/minute` | Optional |
|
|
238
|
-
| `BACKEND` | Tests-related variable | `elasticsearch` or `opensearch` based on the backend | Optional
|
|
239
|
-
| `ELASTICSEARCH_VERSION`
|
|
240
|
-
| `OPENSEARCH_VERSION` | OpenSearch version | `2.11.1` | Optional
|
|
241
|
-
| `ENABLE_DIRECT_RESPONSE`
|
|
242
|
-
| `RAISE_ON_BULK_ERROR`
|
|
243
|
-
| `DATABASE_REFRESH`
|
|
240
|
+
| `BACKEND` | Tests-related variable | `elasticsearch` or `opensearch` based on the backend | Optional |
|
|
241
|
+
| `ELASTICSEARCH_VERSION` | Version of Elasticsearch to use. | `8.11.0` | Optional |
|
|
242
|
+
| `OPENSEARCH_VERSION` | OpenSearch version | `2.11.1` | Optional |
|
|
243
|
+
| `ENABLE_DIRECT_RESPONSE` | Enable direct response for maximum performance (disables all FastAPI dependencies, including authentication, custom status codes, and validation) | `false` | Optional |
|
|
244
|
+
| `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 |
|
|
245
|
+
| `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 |
|
|
244
246
|
| `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 |
|
|
245
247
|
|
|
246
248
|
> [!NOTE]
|
|
247
|
-
> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `
|
|
249
|
+
> 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.
|
|
248
250
|
|
|
249
251
|
## Interacting with the API
|
|
250
252
|
|
|
@@ -22,4 +22,5 @@ stac_fastapi/sfeos_helpers/database/utils.py
|
|
|
22
22
|
stac_fastapi/sfeos_helpers/filter/__init__.py
|
|
23
23
|
stac_fastapi/sfeos_helpers/filter/client.py
|
|
24
24
|
stac_fastapi/sfeos_helpers/filter/cql2.py
|
|
25
|
-
stac_fastapi/sfeos_helpers/filter/transform.py
|
|
25
|
+
stac_fastapi/sfeos_helpers/filter/transform.py
|
|
26
|
+
stac_fastapi/sfeos_helpers/models/patch.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
stac-fastapi.core==6.1.0
|
|
@@ -7,6 +7,8 @@ from typing import Any, Dict, List, Optional
|
|
|
7
7
|
|
|
8
8
|
from stac_fastapi.sfeos_helpers.mappings import Geometry
|
|
9
9
|
|
|
10
|
+
ES_MAX_URL_LENGTH = 4096
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
def apply_free_text_filter_shared(
|
|
12
14
|
search: Any, free_text_queries: Optional[List[str]]
|
|
@@ -83,3 +85,33 @@ def populate_sort_shared(sortby: List) -> Optional[Dict[str, Dict[str, str]]]:
|
|
|
83
85
|
return {s.field: {"order": s.direction} for s in sortby}
|
|
84
86
|
else:
|
|
85
87
|
return None
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def add_collections_to_body(
|
|
91
|
+
collection_ids: List[str], query: Optional[Dict[str, Any]]
|
|
92
|
+
) -> Dict[str, Any]:
|
|
93
|
+
"""Add a list of collection ids to the body of a query.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
collection_ids (List[str]): A list of collections ids.
|
|
97
|
+
query (Optional[Dict[str, Any]]): The query to add collections to. If none, create a query that filters
|
|
98
|
+
the collection ids.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
Dict[str, Any]: A query that contains a filter on the given collection ids.
|
|
102
|
+
|
|
103
|
+
Notes:
|
|
104
|
+
This function is needed in the execute_search function when the size of the URL path will exceed the maximum of ES.
|
|
105
|
+
"""
|
|
106
|
+
index_filter = {"terms": {"collection": collection_ids}}
|
|
107
|
+
if query is None:
|
|
108
|
+
query = {"query": {}}
|
|
109
|
+
if "bool" not in query:
|
|
110
|
+
query["bool"] = {}
|
|
111
|
+
if "filter" not in query["bool"]:
|
|
112
|
+
query["bool"]["filter"] = []
|
|
113
|
+
|
|
114
|
+
filters = query["bool"]["filter"]
|
|
115
|
+
if index_filter not in filters:
|
|
116
|
+
filters.append(index_filter)
|
|
117
|
+
return query
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Utility functions for database operations in Elasticsearch/OpenSearch.
|
|
2
|
+
|
|
3
|
+
This module provides utility functions for working with database operations
|
|
4
|
+
in Elasticsearch/OpenSearch, such as parameter validation.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from typing import Dict, List, Union
|
|
9
|
+
|
|
10
|
+
from stac_fastapi.core.utilities import get_bool_env
|
|
11
|
+
from stac_fastapi.extensions.core.transaction.request import (
|
|
12
|
+
PatchAddReplaceTest,
|
|
13
|
+
PatchOperation,
|
|
14
|
+
PatchRemove,
|
|
15
|
+
)
|
|
16
|
+
from stac_fastapi.sfeos_helpers.models.patch import ElasticPath, ESCommandSet
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def validate_refresh(value: Union[str, bool]) -> str:
|
|
20
|
+
"""
|
|
21
|
+
Validate the `refresh` parameter value.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
value (Union[str, bool]): The `refresh` parameter value, which can be a string or a boolean.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
str: The validated value of the `refresh` parameter, which can be "true", "false", or "wait_for".
|
|
28
|
+
"""
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
# Handle boolean-like values using get_bool_env
|
|
32
|
+
if isinstance(value, bool) or value in {
|
|
33
|
+
"true",
|
|
34
|
+
"false",
|
|
35
|
+
"1",
|
|
36
|
+
"0",
|
|
37
|
+
"yes",
|
|
38
|
+
"no",
|
|
39
|
+
"y",
|
|
40
|
+
"n",
|
|
41
|
+
}:
|
|
42
|
+
is_true = get_bool_env("DATABASE_REFRESH", default=value)
|
|
43
|
+
return "true" if is_true else "false"
|
|
44
|
+
|
|
45
|
+
# Normalize to lowercase for case-insensitivity
|
|
46
|
+
value = value.lower()
|
|
47
|
+
|
|
48
|
+
# Handle "wait_for" explicitly
|
|
49
|
+
if value == "wait_for":
|
|
50
|
+
return "wait_for"
|
|
51
|
+
|
|
52
|
+
# Log a warning for invalid values and default to "false"
|
|
53
|
+
logger.warning(
|
|
54
|
+
f"Invalid value for `refresh`: '{value}'. Expected 'true', 'false', or 'wait_for'. Defaulting to 'false'."
|
|
55
|
+
)
|
|
56
|
+
return "false"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def merge_to_operations(data: Dict) -> List:
|
|
60
|
+
"""Convert merge operation to list of RF6902 operations.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
data: dictionary to convert.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
List: list of RF6902 operations.
|
|
67
|
+
"""
|
|
68
|
+
operations = []
|
|
69
|
+
|
|
70
|
+
for key, value in data.copy().items():
|
|
71
|
+
|
|
72
|
+
if value is None:
|
|
73
|
+
operations.append(PatchRemove(op="remove", path=key))
|
|
74
|
+
|
|
75
|
+
elif isinstance(value, dict):
|
|
76
|
+
nested_operations = merge_to_operations(value)
|
|
77
|
+
|
|
78
|
+
for nested_operation in nested_operations:
|
|
79
|
+
nested_operation.path = f"{key}.{nested_operation.path}"
|
|
80
|
+
operations.append(nested_operation)
|
|
81
|
+
|
|
82
|
+
else:
|
|
83
|
+
operations.append(PatchAddReplaceTest(op="add", path=key, value=value))
|
|
84
|
+
|
|
85
|
+
return operations
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def check_commands(
|
|
89
|
+
commands: ESCommandSet,
|
|
90
|
+
op: str,
|
|
91
|
+
path: ElasticPath,
|
|
92
|
+
from_path: bool = False,
|
|
93
|
+
) -> None:
|
|
94
|
+
"""Add Elasticsearch checks to operation.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
commands (List[str]): current commands
|
|
98
|
+
op (str): the operation of script
|
|
99
|
+
path (Dict): path of variable to run operation on
|
|
100
|
+
from_path (bool): True if path is a from path
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
if path.nest:
|
|
104
|
+
commands.add(
|
|
105
|
+
f"if (!ctx._source.containsKey('{path.nest}'))"
|
|
106
|
+
f"{{Debug.explain('{path.nest} does not exist');}}"
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
if path.index or op in ["remove", "replace", "test"] or from_path:
|
|
110
|
+
commands.add(
|
|
111
|
+
f"if (!ctx._source{path.es_nest}.containsKey('{path.key}'))"
|
|
112
|
+
f"{{Debug.explain('{path.key} does not exist in {path.nest}');}}"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
if from_path and path.index is not None:
|
|
116
|
+
commands.add(
|
|
117
|
+
f"if ((ctx._source{path.es_location} instanceof ArrayList"
|
|
118
|
+
f" && ctx._source{path.es_location}.size() < {path.index})"
|
|
119
|
+
f" || (!(ctx._source{path.es_location} instanceof ArrayList)"
|
|
120
|
+
f" && !ctx._source{path.es_location}.containsKey('{path.index}')))"
|
|
121
|
+
f"{{Debug.explain('{path.path} does not exist');}}"
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def remove_commands(commands: ESCommandSet, path: ElasticPath) -> None:
|
|
126
|
+
"""Remove value at path.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
commands (List[str]): current commands
|
|
130
|
+
path (ElasticPath): Path to value to be removed
|
|
131
|
+
|
|
132
|
+
"""
|
|
133
|
+
if path.index is not None:
|
|
134
|
+
commands.add(
|
|
135
|
+
f"def {path.variable_name} = ctx._source{path.es_location}.remove({path.index});"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
else:
|
|
139
|
+
commands.add(
|
|
140
|
+
f"def {path.variable_name} = ctx._source{path.es_nest}.remove('{path.key}');"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def add_commands(
|
|
145
|
+
commands: ESCommandSet,
|
|
146
|
+
operation: PatchOperation,
|
|
147
|
+
path: ElasticPath,
|
|
148
|
+
from_path: ElasticPath,
|
|
149
|
+
params: Dict,
|
|
150
|
+
) -> None:
|
|
151
|
+
"""Add value at path.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
commands (List[str]): current commands
|
|
155
|
+
operation (PatchOperation): operation to run
|
|
156
|
+
path (ElasticPath): path for value to be added
|
|
157
|
+
|
|
158
|
+
"""
|
|
159
|
+
if from_path is not None:
|
|
160
|
+
value = (
|
|
161
|
+
from_path.variable_name
|
|
162
|
+
if operation.op == "move"
|
|
163
|
+
else f"ctx._source.{from_path.es_path}"
|
|
164
|
+
)
|
|
165
|
+
else:
|
|
166
|
+
value = f"params.{path.param_key}"
|
|
167
|
+
params[path.param_key] = operation.value
|
|
168
|
+
|
|
169
|
+
if path.index is not None:
|
|
170
|
+
commands.add(
|
|
171
|
+
f"if (ctx._source{path.es_location} instanceof ArrayList)"
|
|
172
|
+
f"{{ctx._source{path.es_location}.{'add' if operation.op in ['add', 'move'] else 'set'}({path.index}, {value})}}"
|
|
173
|
+
f"else{{ctx._source.{path.es_path} = {value}}}"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
else:
|
|
177
|
+
commands.add(f"ctx._source.{path.es_path} = {value};")
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def test_commands(
|
|
181
|
+
commands: ESCommandSet, operation: PatchOperation, path: ElasticPath, params: Dict
|
|
182
|
+
) -> None:
|
|
183
|
+
"""Test value at path.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
commands (List[str]): current commands
|
|
187
|
+
operation (PatchOperation): operation to run
|
|
188
|
+
path (ElasticPath): path for value to be tested
|
|
189
|
+
"""
|
|
190
|
+
value = f"params.{path.param_key}"
|
|
191
|
+
params[path.param_key] = operation.value
|
|
192
|
+
|
|
193
|
+
commands.add(
|
|
194
|
+
f"if (ctx._source.{path.es_path} != {value})"
|
|
195
|
+
f"{{Debug.explain('Test failed `{path.path}` | "
|
|
196
|
+
f"{operation.json_value} != ' + ctx._source.{path.es_path});}}"
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def operations_to_script(operations: List) -> Dict:
|
|
201
|
+
"""Convert list of operation to painless script.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
operations: List of RF6902 operations.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
Dict: elasticsearch update script.
|
|
208
|
+
"""
|
|
209
|
+
commands: ESCommandSet = ESCommandSet()
|
|
210
|
+
params: Dict = {}
|
|
211
|
+
|
|
212
|
+
for operation in operations:
|
|
213
|
+
path = ElasticPath(path=operation.path)
|
|
214
|
+
from_path = (
|
|
215
|
+
ElasticPath(path=operation.from_) if hasattr(operation, "from_") else None
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
check_commands(commands=commands, op=operation.op, path=path)
|
|
219
|
+
if from_path is not None:
|
|
220
|
+
check_commands(
|
|
221
|
+
commands=commands, op=operation.op, path=from_path, from_path=True
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
if operation.op in ["remove", "move"]:
|
|
225
|
+
remove_path = from_path if from_path else path
|
|
226
|
+
remove_commands(commands=commands, path=remove_path)
|
|
227
|
+
|
|
228
|
+
if operation.op in ["add", "replace", "copy", "move"]:
|
|
229
|
+
add_commands(
|
|
230
|
+
commands=commands,
|
|
231
|
+
operation=operation,
|
|
232
|
+
path=path,
|
|
233
|
+
from_path=from_path,
|
|
234
|
+
params=params,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
if operation.op == "test":
|
|
238
|
+
test_commands(
|
|
239
|
+
commands=commands, operation=operation, path=path, params=params
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
source = "".join(commands)
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
"source": source,
|
|
246
|
+
"lang": "painless",
|
|
247
|
+
"params": params,
|
|
248
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""Filter client implementation for Elasticsearch/OpenSearch."""
|
|
2
2
|
|
|
3
3
|
from collections import deque
|
|
4
|
-
from typing import Any, Dict, Optional
|
|
4
|
+
from typing import Any, Dict, Optional, Tuple
|
|
5
5
|
|
|
6
6
|
import attr
|
|
7
7
|
|
|
8
8
|
from stac_fastapi.core.base_database_logic import BaseDatabaseLogic
|
|
9
|
-
from stac_fastapi.core.extensions.filter import DEFAULT_QUERYABLES
|
|
9
|
+
from stac_fastapi.core.extensions.filter import ALL_QUERYABLES, DEFAULT_QUERYABLES
|
|
10
10
|
from stac_fastapi.extensions.core.filter.client import AsyncBaseFiltersClient
|
|
11
11
|
from stac_fastapi.sfeos_helpers.mappings import ES_MAPPING_TYPE_TO_JSON
|
|
12
12
|
|
|
@@ -59,31 +59,31 @@ class EsAsyncBaseFiltersClient(AsyncBaseFiltersClient):
|
|
|
59
59
|
|
|
60
60
|
mapping_data = await self.database.get_items_mapping(collection_id)
|
|
61
61
|
mapping_properties = next(iter(mapping_data.values()))["mappings"]["properties"]
|
|
62
|
-
stack = deque(mapping_properties.items())
|
|
62
|
+
stack: deque[Tuple[str, Dict[str, Any]]] = deque(mapping_properties.items())
|
|
63
|
+
enum_fields: Dict[str, Dict[str, Any]] = {}
|
|
63
64
|
|
|
64
65
|
while stack:
|
|
65
|
-
|
|
66
|
+
field_fqn, field_def = stack.popleft()
|
|
66
67
|
|
|
67
68
|
# Iterate over nested fields
|
|
68
69
|
field_properties = field_def.get("properties")
|
|
69
70
|
if field_properties:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if field_name == "properties":
|
|
74
|
-
stack.extend(field_properties.items())
|
|
75
|
-
else:
|
|
76
|
-
stack.extend(
|
|
77
|
-
(f"{field_name}.{k}", v) for k, v in field_properties.items()
|
|
78
|
-
)
|
|
71
|
+
stack.extend(
|
|
72
|
+
(f"{field_fqn}.{k}", v) for k, v in field_properties.items()
|
|
73
|
+
)
|
|
79
74
|
|
|
80
75
|
# Skip non-indexed or disabled fields
|
|
81
76
|
field_type = field_def.get("type")
|
|
82
77
|
if not field_type or not field_def.get("enabled", True):
|
|
83
78
|
continue
|
|
84
79
|
|
|
80
|
+
# Fields in Item Properties should be exposed with their un-prefixed names,
|
|
81
|
+
# and not require expressions to prefix them with properties,
|
|
82
|
+
# e.g., eo:cloud_cover instead of properties.eo:cloud_cover.
|
|
83
|
+
field_name = field_fqn.removeprefix("properties.")
|
|
84
|
+
|
|
85
85
|
# Generate field properties
|
|
86
|
-
field_result =
|
|
86
|
+
field_result = ALL_QUERYABLES.get(field_name, {})
|
|
87
87
|
properties[field_name] = field_result
|
|
88
88
|
|
|
89
89
|
field_name_human = field_name.replace("_", " ").title()
|
|
@@ -95,4 +95,13 @@ class EsAsyncBaseFiltersClient(AsyncBaseFiltersClient):
|
|
|
95
95
|
if field_type in {"date", "date_nanos"}:
|
|
96
96
|
field_result.setdefault("format", "date-time")
|
|
97
97
|
|
|
98
|
+
if field_result.pop("$enum", False):
|
|
99
|
+
enum_fields[field_fqn] = field_result
|
|
100
|
+
|
|
101
|
+
if enum_fields:
|
|
102
|
+
for field_fqn, unique_values in (
|
|
103
|
+
await self.database.get_items_unique_values(collection_id, enum_fields)
|
|
104
|
+
).items():
|
|
105
|
+
enum_fields[field_fqn]["enum"] = unique_values
|
|
106
|
+
|
|
98
107
|
return queryables
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""patch helpers."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from typing import Any, Dict, Optional, Union
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, computed_field, model_validator
|
|
7
|
+
|
|
8
|
+
regex = re.compile(r"([^.' ]*:[^.'[ ]*)\.?")
|
|
9
|
+
replacements = str.maketrans({"/": "", ".": "", ":": "", "[": "", "]": ""})
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ESCommandSet:
|
|
13
|
+
"""Uses dictionary keys to behaviour of ordered set.
|
|
14
|
+
|
|
15
|
+
Yields:
|
|
16
|
+
str: Elasticsearch commands
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
dict_: Dict[str, None] = {}
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
"""Initialise ESCommandSet instance."""
|
|
23
|
+
self.dict_ = {}
|
|
24
|
+
|
|
25
|
+
def add(self, value: str):
|
|
26
|
+
"""Add command.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
value (str): value to be added
|
|
30
|
+
"""
|
|
31
|
+
self.dict_[value] = None
|
|
32
|
+
|
|
33
|
+
def remove(self, value: str):
|
|
34
|
+
"""Remove command.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
value (str): value to be removed
|
|
38
|
+
"""
|
|
39
|
+
del self.dict_[value]
|
|
40
|
+
|
|
41
|
+
def __iter__(self):
|
|
42
|
+
"""Iterate Elasticsearch commands.
|
|
43
|
+
|
|
44
|
+
Yields:
|
|
45
|
+
str: Elasticsearch command
|
|
46
|
+
"""
|
|
47
|
+
yield from self.dict_.keys()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def to_es(string: str):
|
|
51
|
+
"""Convert patch operation key to Elasticsearch key.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
string (str): string to be converted
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
_type_: converted string
|
|
58
|
+
"""
|
|
59
|
+
if matches := regex.findall(string):
|
|
60
|
+
for match in set(matches):
|
|
61
|
+
string = re.sub(rf"\.?{match}", f"['{match}']", string)
|
|
62
|
+
|
|
63
|
+
return string
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ElasticPath(BaseModel):
|
|
67
|
+
"""Converts a JSON path to an Elasticsearch path.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
path (str): JSON path to be converted.
|
|
71
|
+
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
path: str
|
|
75
|
+
nest: Optional[str] = None
|
|
76
|
+
partition: Optional[str] = None
|
|
77
|
+
key: Optional[str] = None
|
|
78
|
+
|
|
79
|
+
es_path: Optional[str] = None
|
|
80
|
+
es_nest: Optional[str] = None
|
|
81
|
+
es_key: Optional[str] = None
|
|
82
|
+
|
|
83
|
+
index_: Optional[int] = None
|
|
84
|
+
|
|
85
|
+
@model_validator(mode="before")
|
|
86
|
+
@classmethod
|
|
87
|
+
def validate_model(cls, data: Any):
|
|
88
|
+
"""Set optional fields from JSON path.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
data (Any): input data
|
|
92
|
+
"""
|
|
93
|
+
data["path"] = data["path"].lstrip("/").replace("/", ".")
|
|
94
|
+
data["nest"], data["partition"], data["key"] = data["path"].rpartition(".")
|
|
95
|
+
|
|
96
|
+
if data["key"].lstrip("-").isdigit() or data["key"] == "-":
|
|
97
|
+
data["index_"] = -1 if data["key"] == "-" else int(data["key"])
|
|
98
|
+
data["path"] = f"{data['nest']}[{data['index_']}]"
|
|
99
|
+
data["nest"], data["partition"], data["key"] = data["nest"].rpartition(".")
|
|
100
|
+
|
|
101
|
+
data["es_path"] = to_es(data["path"])
|
|
102
|
+
data["es_nest"] = f".{to_es(data['nest'])}" if data["nest"] else ""
|
|
103
|
+
data["es_key"] = to_es(data["key"])
|
|
104
|
+
|
|
105
|
+
return data
|
|
106
|
+
|
|
107
|
+
@computed_field # type: ignore[misc]
|
|
108
|
+
@property
|
|
109
|
+
def index(self) -> Union[int, str, None]:
|
|
110
|
+
"""Compute location of path.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
str: path index
|
|
114
|
+
"""
|
|
115
|
+
if self.index_ and self.index_ < 0:
|
|
116
|
+
|
|
117
|
+
return f"ctx._source.{self.location}.size() - {-self.index_}"
|
|
118
|
+
|
|
119
|
+
return self.index_
|
|
120
|
+
|
|
121
|
+
@computed_field # type: ignore[misc]
|
|
122
|
+
@property
|
|
123
|
+
def location(self) -> str:
|
|
124
|
+
"""Compute location of path.
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
str: path location
|
|
128
|
+
"""
|
|
129
|
+
return self.nest + self.partition + self.key
|
|
130
|
+
|
|
131
|
+
@computed_field # type: ignore[misc]
|
|
132
|
+
@property
|
|
133
|
+
def es_location(self) -> str:
|
|
134
|
+
"""Compute location of path.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
str: path location
|
|
138
|
+
"""
|
|
139
|
+
if self.es_key and ":" in self.es_key:
|
|
140
|
+
return self.es_nest + self.es_key
|
|
141
|
+
return self.es_nest + self.partition + self.es_key
|
|
142
|
+
|
|
143
|
+
@computed_field # type: ignore[misc]
|
|
144
|
+
@property
|
|
145
|
+
def variable_name(self) -> str:
|
|
146
|
+
"""Variable name for scripting.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
str: variable name
|
|
150
|
+
"""
|
|
151
|
+
if self.index is not None:
|
|
152
|
+
return f"{self.location.replace('.','_').replace(':','_')}_{self.index}"
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
f"{self.nest.replace('.','_').replace(':','_')}_{self.key.replace(':','_')}"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
@computed_field # type: ignore[misc]
|
|
159
|
+
@property
|
|
160
|
+
def param_key(self) -> str:
|
|
161
|
+
"""Param key for scripting.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
str: param key
|
|
165
|
+
"""
|
|
166
|
+
return self.path.translate(replacements)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
stac-fastapi.core==5.0.0a1
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"""Utility functions for database operations in Elasticsearch/OpenSearch.
|
|
2
|
-
|
|
3
|
-
This module provides utility functions for working with database operations
|
|
4
|
-
in Elasticsearch/OpenSearch, such as parameter validation.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import logging
|
|
8
|
-
from typing import Union
|
|
9
|
-
|
|
10
|
-
from stac_fastapi.core.utilities import get_bool_env
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def validate_refresh(value: Union[str, bool]) -> str:
|
|
14
|
-
"""
|
|
15
|
-
Validate the `refresh` parameter value.
|
|
16
|
-
|
|
17
|
-
Args:
|
|
18
|
-
value (Union[str, bool]): The `refresh` parameter value, which can be a string or a boolean.
|
|
19
|
-
|
|
20
|
-
Returns:
|
|
21
|
-
str: The validated value of the `refresh` parameter, which can be "true", "false", or "wait_for".
|
|
22
|
-
"""
|
|
23
|
-
logger = logging.getLogger(__name__)
|
|
24
|
-
|
|
25
|
-
# Handle boolean-like values using get_bool_env
|
|
26
|
-
if isinstance(value, bool) or value in {
|
|
27
|
-
"true",
|
|
28
|
-
"false",
|
|
29
|
-
"1",
|
|
30
|
-
"0",
|
|
31
|
-
"yes",
|
|
32
|
-
"no",
|
|
33
|
-
"y",
|
|
34
|
-
"n",
|
|
35
|
-
}:
|
|
36
|
-
is_true = get_bool_env("DATABASE_REFRESH", default=value)
|
|
37
|
-
return "true" if is_true else "false"
|
|
38
|
-
|
|
39
|
-
# Normalize to lowercase for case-insensitivity
|
|
40
|
-
value = value.lower()
|
|
41
|
-
|
|
42
|
-
# Handle "wait_for" explicitly
|
|
43
|
-
if value == "wait_for":
|
|
44
|
-
return "wait_for"
|
|
45
|
-
|
|
46
|
-
# Log a warning for invalid values and default to "false"
|
|
47
|
-
logger.warning(
|
|
48
|
-
f"Invalid value for `refresh`: '{value}'. Expected 'true', 'false', or 'wait_for'. Defaulting to 'false'."
|
|
49
|
-
)
|
|
50
|
-
return "false"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/aggregation/__init__.py
RENAMED
|
File without changes
|
{sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/aggregation/client.py
RENAMED
|
File without changes
|
{sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/aggregation/format.py
RENAMED
|
File without changes
|
{sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/__init__.py
RENAMED
|
File without changes
|
{sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/datetime.py
RENAMED
|
File without changes
|
{sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/document.py
RENAMED
|
File without changes
|
|
File without changes
|
{sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/database/mapping.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sfeos_helpers-5.0.0a1 → sfeos_helpers-6.1.0}/stac_fastapi/sfeos_helpers/filter/transform.py
RENAMED
|
File without changes
|
|
File without changes
|