stac-fastapi-opensearch 6.10.0__tar.gz → 6.10.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/PKG-INFO +5 -5
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/pyproject.toml +4 -4
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/stac_fastapi/opensearch/app.py +1 -1
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/stac_fastapi/opensearch/database_logic.py +68 -46
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/stac_fastapi/opensearch/version.py +1 -1
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/.gitignore +0 -0
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/README.md +0 -0
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/pytest.ini +0 -0
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/stac_fastapi/opensearch/__init__.py +0 -0
- {stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/stac_fastapi/opensearch/config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stac_fastapi_opensearch
|
|
3
|
-
Version: 6.10.
|
|
3
|
+
Version: 6.10.1
|
|
4
4
|
Summary: An implementation of STAC API based on the FastAPI framework with Opensearch.
|
|
5
5
|
Project-URL: Homepage, https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
|
|
6
6
|
License: MIT
|
|
@@ -16,8 +16,8 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
16
16
|
Requires-Python: >=3.11
|
|
17
17
|
Requires-Dist: opensearch-py[async]~=2.8.0
|
|
18
18
|
Requires-Dist: opensearch-py~=2.8.0
|
|
19
|
-
Requires-Dist: sfeos-helpers==6.10.
|
|
20
|
-
Requires-Dist: stac-fastapi-core==6.10.
|
|
19
|
+
Requires-Dist: sfeos-helpers==6.10.1
|
|
20
|
+
Requires-Dist: stac-fastapi-core==6.10.1
|
|
21
21
|
Requires-Dist: starlette<0.36.0,>=0.35.0
|
|
22
22
|
Requires-Dist: uvicorn~=0.23.0
|
|
23
23
|
Provides-Extra: dev
|
|
@@ -29,13 +29,13 @@ Requires-Dist: pytest-cov~=4.0.0; extra == 'dev'
|
|
|
29
29
|
Requires-Dist: pytest~=8.0; extra == 'dev'
|
|
30
30
|
Requires-Dist: redis~=6.4.0; extra == 'dev'
|
|
31
31
|
Requires-Dist: retry~=0.9.2; extra == 'dev'
|
|
32
|
-
Requires-Dist: stac-fastapi-core[redis]==6.10.
|
|
32
|
+
Requires-Dist: stac-fastapi-core[redis]==6.10.1; extra == 'dev'
|
|
33
33
|
Provides-Extra: docs
|
|
34
34
|
Requires-Dist: mkdocs-material~=9.0.0; extra == 'docs'
|
|
35
35
|
Requires-Dist: mkdocs~=1.4.0; extra == 'docs'
|
|
36
36
|
Requires-Dist: pdocs~=1.2.0; extra == 'docs'
|
|
37
37
|
Provides-Extra: redis
|
|
38
|
-
Requires-Dist: stac-fastapi-core[redis]==6.10.
|
|
38
|
+
Requires-Dist: stac-fastapi-core[redis]==6.10.1; extra == 'redis'
|
|
39
39
|
Provides-Extra: server
|
|
40
40
|
Requires-Dist: uvicorn[standard]~=0.23.0; extra == 'server'
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
@@ -28,8 +28,8 @@ keywords = [
|
|
|
28
28
|
]
|
|
29
29
|
dynamic = ["version"]
|
|
30
30
|
dependencies = [
|
|
31
|
-
"stac-fastapi-core==6.10.
|
|
32
|
-
"sfeos-helpers==6.10.
|
|
31
|
+
"stac-fastapi-core==6.10.1",
|
|
32
|
+
"sfeos-helpers==6.10.1",
|
|
33
33
|
"opensearch-py~=2.8.0",
|
|
34
34
|
"opensearch-py[async]~=2.8.0",
|
|
35
35
|
"uvicorn~=0.23.0",
|
|
@@ -49,7 +49,7 @@ dev = [
|
|
|
49
49
|
"httpx>=0.24.0,<0.28.0",
|
|
50
50
|
"redis~=6.4.0",
|
|
51
51
|
"retry~=0.9.2",
|
|
52
|
-
"stac-fastapi-core[redis]==6.10.
|
|
52
|
+
"stac-fastapi-core[redis]==6.10.1",
|
|
53
53
|
]
|
|
54
54
|
docs = [
|
|
55
55
|
"mkdocs~=1.4.0",
|
|
@@ -57,7 +57,7 @@ docs = [
|
|
|
57
57
|
"pdocs~=1.2.0",
|
|
58
58
|
]
|
|
59
59
|
redis = [
|
|
60
|
-
"stac-fastapi-core[redis]==6.10.
|
|
60
|
+
"stac-fastapi-core[redis]==6.10.1",
|
|
61
61
|
]
|
|
62
62
|
server = [
|
|
63
63
|
"uvicorn[standard]~=0.23.0",
|
{stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/stac_fastapi/opensearch/app.py
RENAMED
|
@@ -243,7 +243,7 @@ items_get_request_model = create_request_model(
|
|
|
243
243
|
app_config = {
|
|
244
244
|
"title": os.getenv("STAC_FASTAPI_TITLE", "stac-fastapi-opensearch"),
|
|
245
245
|
"description": os.getenv("STAC_FASTAPI_DESCRIPTION", "stac-fastapi-opensearch"),
|
|
246
|
-
"api_version": os.getenv("STAC_FASTAPI_VERSION", "6.10.
|
|
246
|
+
"api_version": os.getenv("STAC_FASTAPI_VERSION", "6.10.1"),
|
|
247
247
|
"settings": settings,
|
|
248
248
|
"extensions": extensions,
|
|
249
249
|
"client": CoreClient(
|
|
@@ -29,11 +29,14 @@ from stac_fastapi.opensearch.config import (
|
|
|
29
29
|
)
|
|
30
30
|
from stac_fastapi.opensearch.config import OpensearchSettings as SyncSearchSettings
|
|
31
31
|
from stac_fastapi.sfeos_helpers.database import (
|
|
32
|
+
ItemAlreadyExistsError,
|
|
32
33
|
add_bbox_shape_to_collection,
|
|
33
34
|
apply_collections_bbox_filter_shared,
|
|
34
35
|
apply_collections_datetime_filter_shared,
|
|
35
36
|
apply_free_text_filter_shared,
|
|
36
37
|
apply_intersects_filter_shared,
|
|
38
|
+
check_item_exists_in_alias,
|
|
39
|
+
check_item_exists_in_alias_sync,
|
|
37
40
|
create_index_templates_shared,
|
|
38
41
|
delete_item_index_shared,
|
|
39
42
|
get_queryables_mapping_shared,
|
|
@@ -1000,6 +1003,44 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1000
1003
|
if not await self.client.exists(index=COLLECTIONS_INDEX, id=collection_id):
|
|
1001
1004
|
raise NotFoundError(f"Collection {collection_id} does not exist")
|
|
1002
1005
|
|
|
1006
|
+
async def _check_item_exists_in_collection(
|
|
1007
|
+
self, collection_id: str, item_id: str
|
|
1008
|
+
) -> bool:
|
|
1009
|
+
"""Check if an item exists across all indexes for a collection.
|
|
1010
|
+
|
|
1011
|
+
Args:
|
|
1012
|
+
collection_id (str): The collection identifier.
|
|
1013
|
+
item_id (str): The item identifier.
|
|
1014
|
+
|
|
1015
|
+
Returns:
|
|
1016
|
+
bool: True if the item exists in any index, False otherwise.
|
|
1017
|
+
"""
|
|
1018
|
+
alias = index_alias_by_collection_id(collection_id)
|
|
1019
|
+
doc_id = mk_item_id(item_id, collection_id)
|
|
1020
|
+
try:
|
|
1021
|
+
return await check_item_exists_in_alias(self.client, alias, doc_id)
|
|
1022
|
+
except Exception:
|
|
1023
|
+
return False
|
|
1024
|
+
|
|
1025
|
+
def _check_item_exists_in_collection_sync(
|
|
1026
|
+
self, collection_id: str, item_id: str
|
|
1027
|
+
) -> bool:
|
|
1028
|
+
"""Check if an item exists across all indexes for a collection (sync version).
|
|
1029
|
+
|
|
1030
|
+
Args:
|
|
1031
|
+
collection_id (str): The collection identifier.
|
|
1032
|
+
item_id (str): The item identifier.
|
|
1033
|
+
|
|
1034
|
+
Returns:
|
|
1035
|
+
bool: True if the item exists in any index, False otherwise.
|
|
1036
|
+
"""
|
|
1037
|
+
alias = index_alias_by_collection_id(collection_id)
|
|
1038
|
+
doc_id = mk_item_id(item_id, collection_id)
|
|
1039
|
+
try:
|
|
1040
|
+
return check_item_exists_in_alias_sync(self.sync_client, alias, doc_id)
|
|
1041
|
+
except Exception:
|
|
1042
|
+
return False
|
|
1043
|
+
|
|
1003
1044
|
async def async_prep_create_item(
|
|
1004
1045
|
self, item: Item, base_url: str, exist_ok: bool = False
|
|
1005
1046
|
) -> Item:
|
|
@@ -1015,31 +1056,21 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1015
1056
|
Item: The prepped item.
|
|
1016
1057
|
|
|
1017
1058
|
Raises:
|
|
1018
|
-
|
|
1059
|
+
ItemAlreadyExistsError: If the item already exists in the database.
|
|
1019
1060
|
|
|
1020
1061
|
"""
|
|
1021
1062
|
await self.check_collection_exists(collection_id=item["collection"])
|
|
1022
|
-
alias = index_alias_by_collection_id(item["collection"])
|
|
1023
|
-
doc_id = mk_item_id(item["id"], item["collection"])
|
|
1024
|
-
|
|
1025
|
-
if not exist_ok:
|
|
1026
|
-
alias_exists = await self.client.indices.exists_alias(name=alias)
|
|
1027
1063
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
for index in indices:
|
|
1033
|
-
if await self.client.exists(index=index, id=doc_id):
|
|
1034
|
-
raise ConflictError(
|
|
1035
|
-
f"Item {item['id']} in collection {item['collection']} already exists"
|
|
1036
|
-
)
|
|
1064
|
+
if not exist_ok and await self._check_item_exists_in_collection(
|
|
1065
|
+
item["collection"], item["id"]
|
|
1066
|
+
):
|
|
1067
|
+
raise ItemAlreadyExistsError(item["id"], item["collection"])
|
|
1037
1068
|
|
|
1038
1069
|
return self.item_serializer.stac_to_db(item, base_url)
|
|
1039
1070
|
|
|
1040
1071
|
async def bulk_async_prep_create_item(
|
|
1041
1072
|
self, item: Item, base_url: str, exist_ok: bool = False
|
|
1042
|
-
) -> Item:
|
|
1073
|
+
) -> Optional[Item]:
|
|
1043
1074
|
"""
|
|
1044
1075
|
Prepare an item for insertion into the database.
|
|
1045
1076
|
|
|
@@ -1067,20 +1098,19 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1067
1098
|
# Check if the collection exists
|
|
1068
1099
|
await self.check_collection_exists(collection_id=item["collection"])
|
|
1069
1100
|
|
|
1070
|
-
# Check if the item already exists in the database
|
|
1071
|
-
if not exist_ok and await self.
|
|
1072
|
-
|
|
1073
|
-
id=mk_item_id(item["id"], item["collection"]),
|
|
1101
|
+
# Check if the item already exists in the database (across all datetime indexes)
|
|
1102
|
+
if not exist_ok and await self._check_item_exists_in_collection(
|
|
1103
|
+
item["collection"], item["id"]
|
|
1074
1104
|
):
|
|
1075
|
-
error_message = (
|
|
1076
|
-
f"Item {item['id']} in collection {item['collection']} already exists."
|
|
1077
|
-
)
|
|
1078
1105
|
if self.async_settings.raise_on_bulk_error:
|
|
1079
|
-
raise
|
|
1106
|
+
raise ItemAlreadyExistsError(item["id"], item["collection"])
|
|
1080
1107
|
else:
|
|
1081
1108
|
logger.warning(
|
|
1082
|
-
f"{
|
|
1109
|
+
f"Item {item['id']} in collection {item['collection']} already exists. "
|
|
1110
|
+
"Skipping as `RAISE_ON_BULK_ERROR` is set to false."
|
|
1083
1111
|
)
|
|
1112
|
+
return None
|
|
1113
|
+
|
|
1084
1114
|
# Serialize the item into a database-compatible format
|
|
1085
1115
|
prepped_item = self.item_serializer.stac_to_db(item, base_url)
|
|
1086
1116
|
logger.debug(f"Item {item['id']} prepared successfully.")
|
|
@@ -1088,7 +1118,7 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1088
1118
|
|
|
1089
1119
|
def bulk_sync_prep_create_item(
|
|
1090
1120
|
self, item: Item, base_url: str, exist_ok: bool = False
|
|
1091
|
-
) -> Item:
|
|
1121
|
+
) -> Optional[Item]:
|
|
1092
1122
|
"""
|
|
1093
1123
|
Prepare an item for insertion into the database.
|
|
1094
1124
|
|
|
@@ -1117,26 +1147,18 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1117
1147
|
if not self.sync_client.exists(index=COLLECTIONS_INDEX, id=item["collection"]):
|
|
1118
1148
|
raise NotFoundError(f"Collection {item['collection']} does not exist")
|
|
1119
1149
|
|
|
1120
|
-
# Check if the item already exists in the database
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
if self.sync_client.exists(index=index, id=doc_id):
|
|
1133
|
-
error_message = f"Item {item['id']} in collection {item['collection']} already exists."
|
|
1134
|
-
if self.sync_settings.raise_on_bulk_error:
|
|
1135
|
-
raise ConflictError(error_message)
|
|
1136
|
-
else:
|
|
1137
|
-
logger.warning(
|
|
1138
|
-
f"{error_message} Continuing as `RAISE_ON_BULK_ERROR` is set to false."
|
|
1139
|
-
)
|
|
1150
|
+
# Check if the item already exists in the database (across all datetime indexes)
|
|
1151
|
+
if not exist_ok and self._check_item_exists_in_collection_sync(
|
|
1152
|
+
item["collection"], item["id"]
|
|
1153
|
+
):
|
|
1154
|
+
if self.sync_settings.raise_on_bulk_error:
|
|
1155
|
+
raise ItemAlreadyExistsError(item["id"], item["collection"])
|
|
1156
|
+
else:
|
|
1157
|
+
logger.warning(
|
|
1158
|
+
f"Item {item['id']} in collection {item['collection']} already exists. "
|
|
1159
|
+
"Skipping as `RAISE_ON_BULK_ERROR` is set to false."
|
|
1160
|
+
)
|
|
1161
|
+
return None
|
|
1140
1162
|
|
|
1141
1163
|
# Serialize the item into a database-compatible format
|
|
1142
1164
|
prepped_item = self.item_serializer.stac_to_db(item, base_url)
|
{stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/stac_fastapi/opensearch/version.py
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""library version."""
|
|
2
|
-
__version__ = "6.10.
|
|
2
|
+
__version__ = "6.10.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stac_fastapi_opensearch-6.10.0 → stac_fastapi_opensearch-6.10.1}/stac_fastapi/opensearch/config.py
RENAMED
|
File without changes
|