stac-fastapi-core 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.
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/PKG-INFO +15 -13
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/README.md +14 -12
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/setup.py +4 -4
- stac_fastapi_core-6.1.0/stac_fastapi/core/base_database_logic.py +112 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/core.py +121 -2
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/filter.py +11 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/route_dependencies.py +6 -6
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/utilities.py +1 -0
- stac_fastapi_core-6.1.0/stac_fastapi/core/version.py +2 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/PKG-INFO +15 -13
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/requires.txt +4 -4
- stac_fastapi_core-5.0.0a1/stac_fastapi/core/base_database_logic.py +0 -54
- stac_fastapi_core-5.0.0a1/stac_fastapi/core/version.py +0 -2
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/setup.cfg +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/__init__.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/base_settings.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/basic_auth.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/datetime_utils.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/__init__.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/aggregation.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/fields.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/query.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/models/__init__.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/models/links.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/models/search.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/rate_limit.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/serializers.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/session.py +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/SOURCES.txt +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/dependency_links.txt +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/not-zip-safe +0 -0
- {stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stac_fastapi_core
|
|
3
|
-
Version:
|
|
3
|
+
Version: 6.1.0
|
|
4
4
|
Summary: Core 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
|
|
|
@@ -9,10 +9,10 @@ install_requires = [
|
|
|
9
9
|
"fastapi~=0.109.0",
|
|
10
10
|
"attrs>=23.2.0",
|
|
11
11
|
"pydantic>=2.4.1,<3.0.0",
|
|
12
|
-
"stac_pydantic~=3.
|
|
13
|
-
"stac-fastapi.
|
|
14
|
-
"stac-fastapi.
|
|
15
|
-
"stac-fastapi.
|
|
12
|
+
"stac_pydantic~=3.3.0",
|
|
13
|
+
"stac-fastapi.types==6.0.0",
|
|
14
|
+
"stac-fastapi.api==6.0.0",
|
|
15
|
+
"stac-fastapi.extensions==6.0.0",
|
|
16
16
|
"orjson~=3.9.0",
|
|
17
17
|
"overrides~=7.4.0",
|
|
18
18
|
"geojson-pydantic~=1.0.0",
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Base database logic."""
|
|
2
|
+
|
|
3
|
+
import abc
|
|
4
|
+
from typing import Any, Dict, Iterable, List, Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BaseDatabaseLogic(abc.ABC):
|
|
8
|
+
"""
|
|
9
|
+
Abstract base class for database logic.
|
|
10
|
+
|
|
11
|
+
This class defines the basic structure and operations for database interactions.
|
|
12
|
+
Subclasses must provide implementations for these methods.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@abc.abstractmethod
|
|
16
|
+
async def get_all_collections(
|
|
17
|
+
self, token: Optional[str], limit: int
|
|
18
|
+
) -> Iterable[Dict[str, Any]]:
|
|
19
|
+
"""Retrieve a list of all collections from the database."""
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
@abc.abstractmethod
|
|
23
|
+
async def get_one_item(self, collection_id: str, item_id: str) -> Dict:
|
|
24
|
+
"""Retrieve a single item from the database."""
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
@abc.abstractmethod
|
|
28
|
+
async def create_item(self, item: Dict, refresh: bool = False) -> None:
|
|
29
|
+
"""Create an item in the database."""
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
@abc.abstractmethod
|
|
33
|
+
async def merge_patch_item(
|
|
34
|
+
self,
|
|
35
|
+
collection_id: str,
|
|
36
|
+
item_id: str,
|
|
37
|
+
item: Dict,
|
|
38
|
+
base_url: str,
|
|
39
|
+
refresh: bool = True,
|
|
40
|
+
) -> Dict:
|
|
41
|
+
"""Patch a item in the database follows RF7396."""
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
@abc.abstractmethod
|
|
45
|
+
async def json_patch_item(
|
|
46
|
+
self,
|
|
47
|
+
collection_id: str,
|
|
48
|
+
item_id: str,
|
|
49
|
+
operations: List,
|
|
50
|
+
base_url: str,
|
|
51
|
+
refresh: bool = True,
|
|
52
|
+
) -> Dict:
|
|
53
|
+
"""Patch a item in the database follows RF6902."""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
@abc.abstractmethod
|
|
57
|
+
async def delete_item(
|
|
58
|
+
self, item_id: str, collection_id: str, refresh: bool = False
|
|
59
|
+
) -> None:
|
|
60
|
+
"""Delete an item from the database."""
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
@abc.abstractmethod
|
|
64
|
+
async def get_items_mapping(self, collection_id: str) -> Dict[str, Dict[str, Any]]:
|
|
65
|
+
"""Get the mapping for the items in the collection."""
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
@abc.abstractmethod
|
|
69
|
+
async def get_items_unique_values(
|
|
70
|
+
self, collection_id: str, field_names: Iterable[str], *, limit: int = ...
|
|
71
|
+
) -> Dict[str, List[str]]:
|
|
72
|
+
"""Get the unique values for the given fields in the collection."""
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
@abc.abstractmethod
|
|
76
|
+
async def create_collection(self, collection: Dict, refresh: bool = False) -> None:
|
|
77
|
+
"""Create a collection in the database."""
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
@abc.abstractmethod
|
|
81
|
+
async def merge_patch_collection(
|
|
82
|
+
self,
|
|
83
|
+
collection_id: str,
|
|
84
|
+
collection: Dict,
|
|
85
|
+
base_url: str,
|
|
86
|
+
refresh: bool = True,
|
|
87
|
+
) -> Dict:
|
|
88
|
+
"""Patch a collection in the database follows RF7396."""
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
@abc.abstractmethod
|
|
92
|
+
async def json_patch_collection(
|
|
93
|
+
self,
|
|
94
|
+
collection_id: str,
|
|
95
|
+
operations: List,
|
|
96
|
+
base_url: str,
|
|
97
|
+
refresh: bool = True,
|
|
98
|
+
) -> Dict:
|
|
99
|
+
"""Patch a collection in the database follows RF6902."""
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
@abc.abstractmethod
|
|
103
|
+
async def find_collection(self, collection_id: str) -> Dict:
|
|
104
|
+
"""Find a collection in the database."""
|
|
105
|
+
pass
|
|
106
|
+
|
|
107
|
+
@abc.abstractmethod
|
|
108
|
+
async def delete_collection(
|
|
109
|
+
self, collection_id: str, refresh: bool = False
|
|
110
|
+
) -> None:
|
|
111
|
+
"""Delete a collection from the database."""
|
|
112
|
+
pass
|
|
@@ -11,7 +11,7 @@ import attr
|
|
|
11
11
|
import orjson
|
|
12
12
|
from fastapi import HTTPException, Request
|
|
13
13
|
from overrides import overrides
|
|
14
|
-
from pydantic import ValidationError
|
|
14
|
+
from pydantic import TypeAdapter, ValidationError
|
|
15
15
|
from pygeofilter.backends.cql2_json import to_cql2
|
|
16
16
|
from pygeofilter.parsers.cql2_text import parse as parse_cql2_text
|
|
17
17
|
from stac_pydantic import Collection, Item, ItemCollection
|
|
@@ -26,6 +26,12 @@ from stac_fastapi.core.models.links import PagingLinks
|
|
|
26
26
|
from stac_fastapi.core.serializers import CollectionSerializer, ItemSerializer
|
|
27
27
|
from stac_fastapi.core.session import Session
|
|
28
28
|
from stac_fastapi.core.utilities import filter_fields
|
|
29
|
+
from stac_fastapi.extensions.core.transaction import AsyncBaseTransactionsClient
|
|
30
|
+
from stac_fastapi.extensions.core.transaction.request import (
|
|
31
|
+
PartialCollection,
|
|
32
|
+
PartialItem,
|
|
33
|
+
PatchOperation,
|
|
34
|
+
)
|
|
29
35
|
from stac_fastapi.extensions.third_party.bulk_transactions import (
|
|
30
36
|
BaseBulkTransactionsClient,
|
|
31
37
|
BulkTransactionMethod,
|
|
@@ -33,13 +39,16 @@ from stac_fastapi.extensions.third_party.bulk_transactions import (
|
|
|
33
39
|
)
|
|
34
40
|
from stac_fastapi.types import stac as stac_types
|
|
35
41
|
from stac_fastapi.types.conformance import BASE_CONFORMANCE_CLASSES
|
|
36
|
-
from stac_fastapi.types.core import AsyncBaseCoreClient
|
|
42
|
+
from stac_fastapi.types.core import AsyncBaseCoreClient
|
|
37
43
|
from stac_fastapi.types.extension import ApiExtension
|
|
38
44
|
from stac_fastapi.types.requests import get_base_url
|
|
39
45
|
from stac_fastapi.types.search import BaseSearchPostRequest
|
|
40
46
|
|
|
41
47
|
logger = logging.getLogger(__name__)
|
|
42
48
|
|
|
49
|
+
partialItemValidator = TypeAdapter(PartialItem)
|
|
50
|
+
partialCollectionValidator = TypeAdapter(PartialCollection)
|
|
51
|
+
|
|
43
52
|
|
|
44
53
|
@attr.s
|
|
45
54
|
class CoreClient(AsyncBaseCoreClient):
|
|
@@ -680,6 +689,63 @@ class TransactionsClient(AsyncBaseTransactionsClient):
|
|
|
680
689
|
|
|
681
690
|
return ItemSerializer.db_to_stac(item, base_url)
|
|
682
691
|
|
|
692
|
+
@overrides
|
|
693
|
+
async def patch_item(
|
|
694
|
+
self,
|
|
695
|
+
collection_id: str,
|
|
696
|
+
item_id: str,
|
|
697
|
+
patch: Union[PartialItem, List[PatchOperation]],
|
|
698
|
+
**kwargs,
|
|
699
|
+
):
|
|
700
|
+
"""Patch an item in the collection.
|
|
701
|
+
|
|
702
|
+
Args:
|
|
703
|
+
collection_id (str): The ID of the collection the item belongs to.
|
|
704
|
+
item_id (str): The ID of the item to be updated.
|
|
705
|
+
patch (Union[PartialItem, List[PatchOperation]]): The item data or operations.
|
|
706
|
+
kwargs: Other optional arguments, including the request object.
|
|
707
|
+
|
|
708
|
+
Returns:
|
|
709
|
+
stac_types.Item: The updated item object.
|
|
710
|
+
|
|
711
|
+
Raises:
|
|
712
|
+
NotFound: If the specified collection is not found in the database.
|
|
713
|
+
|
|
714
|
+
"""
|
|
715
|
+
base_url = str(kwargs["request"].base_url)
|
|
716
|
+
|
|
717
|
+
content_type = kwargs["request"].headers.get("content-type")
|
|
718
|
+
|
|
719
|
+
item = None
|
|
720
|
+
if isinstance(patch, list) and content_type == "application/json-patch+json":
|
|
721
|
+
item = await self.database.json_patch_item(
|
|
722
|
+
collection_id=collection_id,
|
|
723
|
+
item_id=item_id,
|
|
724
|
+
operations=patch,
|
|
725
|
+
base_url=base_url,
|
|
726
|
+
)
|
|
727
|
+
|
|
728
|
+
if isinstance(patch, dict):
|
|
729
|
+
patch = partialItemValidator.validate_python(patch)
|
|
730
|
+
|
|
731
|
+
if isinstance(patch, PartialItem) and content_type in [
|
|
732
|
+
"application/merge-patch+json",
|
|
733
|
+
"application/json",
|
|
734
|
+
]:
|
|
735
|
+
item = await self.database.merge_patch_item(
|
|
736
|
+
collection_id=collection_id,
|
|
737
|
+
item_id=item_id,
|
|
738
|
+
item=patch,
|
|
739
|
+
base_url=base_url,
|
|
740
|
+
)
|
|
741
|
+
|
|
742
|
+
if item:
|
|
743
|
+
return ItemSerializer.db_to_stac(item, base_url=base_url)
|
|
744
|
+
|
|
745
|
+
raise NotImplementedError(
|
|
746
|
+
f"Content-Type: {content_type} and body: {patch} combination not implemented"
|
|
747
|
+
)
|
|
748
|
+
|
|
683
749
|
@overrides
|
|
684
750
|
async def delete_item(self, item_id: str, collection_id: str, **kwargs) -> None:
|
|
685
751
|
"""Delete an item from a collection.
|
|
@@ -761,6 +827,59 @@ class TransactionsClient(AsyncBaseTransactionsClient):
|
|
|
761
827
|
extensions=[type(ext).__name__ for ext in self.database.extensions],
|
|
762
828
|
)
|
|
763
829
|
|
|
830
|
+
@overrides
|
|
831
|
+
async def patch_collection(
|
|
832
|
+
self,
|
|
833
|
+
collection_id: str,
|
|
834
|
+
patch: Union[PartialCollection, List[PatchOperation]],
|
|
835
|
+
**kwargs,
|
|
836
|
+
):
|
|
837
|
+
"""Update a collection.
|
|
838
|
+
|
|
839
|
+
Called with `PATCH /collections/{collection_id}`
|
|
840
|
+
|
|
841
|
+
Args:
|
|
842
|
+
collection_id: id of the collection.
|
|
843
|
+
patch: either the partial collection or list of patch operations.
|
|
844
|
+
|
|
845
|
+
Returns:
|
|
846
|
+
The patched collection.
|
|
847
|
+
"""
|
|
848
|
+
base_url = str(kwargs["request"].base_url)
|
|
849
|
+
content_type = kwargs["request"].headers.get("content-type")
|
|
850
|
+
|
|
851
|
+
collection = None
|
|
852
|
+
if isinstance(patch, list) and content_type == "application/json-patch+json":
|
|
853
|
+
collection = await self.database.json_patch_collection(
|
|
854
|
+
collection_id=collection_id,
|
|
855
|
+
operations=patch,
|
|
856
|
+
base_url=base_url,
|
|
857
|
+
)
|
|
858
|
+
|
|
859
|
+
if isinstance(patch, dict):
|
|
860
|
+
patch = partialCollectionValidator.validate_python(patch)
|
|
861
|
+
|
|
862
|
+
if isinstance(patch, PartialCollection) and content_type in [
|
|
863
|
+
"application/merge-patch+json",
|
|
864
|
+
"application/json",
|
|
865
|
+
]:
|
|
866
|
+
collection = await self.database.merge_patch_collection(
|
|
867
|
+
collection_id=collection_id,
|
|
868
|
+
collection=patch,
|
|
869
|
+
base_url=base_url,
|
|
870
|
+
)
|
|
871
|
+
|
|
872
|
+
if collection:
|
|
873
|
+
return CollectionSerializer.db_to_stac(
|
|
874
|
+
collection,
|
|
875
|
+
kwargs["request"],
|
|
876
|
+
extensions=[type(ext).__name__ for ext in self.database.extensions],
|
|
877
|
+
)
|
|
878
|
+
|
|
879
|
+
raise NotImplementedError(
|
|
880
|
+
f"Content-Type: {content_type} and body: {patch} combination not implemented"
|
|
881
|
+
)
|
|
882
|
+
|
|
764
883
|
@overrides
|
|
765
884
|
async def delete_collection(self, collection_id: str, **kwargs) -> None:
|
|
766
885
|
"""
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/filter.py
RENAMED
|
@@ -60,6 +60,17 @@ DEFAULT_QUERYABLES: Dict[str, Dict[str, Any]] = {
|
|
|
60
60
|
"maximum": 100,
|
|
61
61
|
},
|
|
62
62
|
}
|
|
63
|
+
"""Queryables that are present in all collections."""
|
|
64
|
+
|
|
65
|
+
OPTIONAL_QUERYABLES: Dict[str, Dict[str, Any]] = {
|
|
66
|
+
"platform": {
|
|
67
|
+
"$enum": True,
|
|
68
|
+
"description": "Satellite platform identifier",
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
"""Queryables that are present in some collections."""
|
|
72
|
+
|
|
73
|
+
ALL_QUERYABLES: Dict[str, Dict[str, Any]] = DEFAULT_QUERYABLES | OPTIONAL_QUERYABLES
|
|
63
74
|
|
|
64
75
|
|
|
65
76
|
class LogicalOp(str, Enum):
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/route_dependencies.py
RENAMED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
4
|
import inspect
|
|
5
|
-
import json
|
|
6
5
|
import logging
|
|
7
6
|
import os
|
|
8
7
|
from typing import List
|
|
9
8
|
|
|
9
|
+
import orjson
|
|
10
10
|
from fastapi import Depends
|
|
11
11
|
from jsonschema import validate
|
|
12
12
|
|
|
@@ -84,14 +84,14 @@ route_dependencies_schema = {
|
|
|
84
84
|
|
|
85
85
|
def get_route_dependencies_conf(route_dependencies_env: str) -> list:
|
|
86
86
|
"""Get Route dependencies configuration from file or environment variable."""
|
|
87
|
-
if os.path.
|
|
88
|
-
with open(route_dependencies_env,
|
|
89
|
-
route_dependencies_conf =
|
|
87
|
+
if os.path.isfile(route_dependencies_env):
|
|
88
|
+
with open(route_dependencies_env, "rb") as f:
|
|
89
|
+
route_dependencies_conf = orjson.loads(f.read())
|
|
90
90
|
|
|
91
91
|
else:
|
|
92
92
|
try:
|
|
93
|
-
route_dependencies_conf =
|
|
94
|
-
except
|
|
93
|
+
route_dependencies_conf = orjson.loads(route_dependencies_env)
|
|
94
|
+
except orjson.JSONDecodeError as exception:
|
|
95
95
|
_LOGGER.error("Invalid JSON format for route dependencies. %s", exception)
|
|
96
96
|
raise
|
|
97
97
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stac-fastapi-core
|
|
3
|
-
Version:
|
|
3
|
+
Version: 6.1.0
|
|
4
4
|
Summary: Core 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
|
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/requires.txt
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
fastapi~=0.109.0
|
|
2
2
|
attrs>=23.2.0
|
|
3
3
|
pydantic<3.0.0,>=2.4.1
|
|
4
|
-
stac_pydantic~=3.
|
|
5
|
-
stac-fastapi.
|
|
6
|
-
stac-fastapi.
|
|
7
|
-
stac-fastapi.
|
|
4
|
+
stac_pydantic~=3.3.0
|
|
5
|
+
stac-fastapi.types==6.0.0
|
|
6
|
+
stac-fastapi.api==6.0.0
|
|
7
|
+
stac-fastapi.extensions==6.0.0
|
|
8
8
|
orjson~=3.9.0
|
|
9
9
|
overrides~=7.4.0
|
|
10
10
|
geojson-pydantic~=1.0.0
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"""Base database logic."""
|
|
2
|
-
|
|
3
|
-
import abc
|
|
4
|
-
from typing import Any, Dict, Iterable, Optional
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class BaseDatabaseLogic(abc.ABC):
|
|
8
|
-
"""
|
|
9
|
-
Abstract base class for database logic.
|
|
10
|
-
|
|
11
|
-
This class defines the basic structure and operations for database interactions.
|
|
12
|
-
Subclasses must provide implementations for these methods.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
@abc.abstractmethod
|
|
16
|
-
async def get_all_collections(
|
|
17
|
-
self, token: Optional[str], limit: int
|
|
18
|
-
) -> Iterable[Dict[str, Any]]:
|
|
19
|
-
"""Retrieve a list of all collections from the database."""
|
|
20
|
-
pass
|
|
21
|
-
|
|
22
|
-
@abc.abstractmethod
|
|
23
|
-
async def get_one_item(self, collection_id: str, item_id: str) -> Dict:
|
|
24
|
-
"""Retrieve a single item from the database."""
|
|
25
|
-
pass
|
|
26
|
-
|
|
27
|
-
@abc.abstractmethod
|
|
28
|
-
async def create_item(self, item: Dict, refresh: bool = False) -> None:
|
|
29
|
-
"""Create an item in the database."""
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
@abc.abstractmethod
|
|
33
|
-
async def delete_item(
|
|
34
|
-
self, item_id: str, collection_id: str, refresh: bool = False
|
|
35
|
-
) -> None:
|
|
36
|
-
"""Delete an item from the database."""
|
|
37
|
-
pass
|
|
38
|
-
|
|
39
|
-
@abc.abstractmethod
|
|
40
|
-
async def create_collection(self, collection: Dict, refresh: bool = False) -> None:
|
|
41
|
-
"""Create a collection in the database."""
|
|
42
|
-
pass
|
|
43
|
-
|
|
44
|
-
@abc.abstractmethod
|
|
45
|
-
async def find_collection(self, collection_id: str) -> Dict:
|
|
46
|
-
"""Find a collection in the database."""
|
|
47
|
-
pass
|
|
48
|
-
|
|
49
|
-
@abc.abstractmethod
|
|
50
|
-
async def delete_collection(
|
|
51
|
-
self, collection_id: str, refresh: bool = False
|
|
52
|
-
) -> None:
|
|
53
|
-
"""Delete a collection from the database."""
|
|
54
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/__init__.py
RENAMED
|
File without changes
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/aggregation.py
RENAMED
|
File without changes
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi/core/extensions/fields.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{stac_fastapi_core-5.0.0a1 → stac_fastapi_core-6.1.0}/stac_fastapi_core.egg-info/top_level.txt
RENAMED
|
File without changes
|