stac-fastapi-elasticsearch 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_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/PKG-INFO +5 -5
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/pyproject.toml +4 -4
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/stac_fastapi/elasticsearch/app.py +1 -1
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/stac_fastapi/elasticsearch/database_logic.py +67 -46
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/stac_fastapi/elasticsearch/version.py +1 -1
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/.gitignore +0 -0
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/README.md +0 -0
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/pytest.ini +0 -0
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/stac_fastapi/elasticsearch/__init__.py +0 -0
- {stac_fastapi_elasticsearch-6.10.0 → stac_fastapi_elasticsearch-6.10.1}/stac_fastapi/elasticsearch/config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stac_fastapi_elasticsearch
|
|
3
|
-
Version: 6.10.
|
|
3
|
+
Version: 6.10.1
|
|
4
4
|
Summary: An implementation of STAC API based on the FastAPI framework with Elasticsearch.
|
|
5
5
|
Project-URL: Homepage, https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
|
|
6
6
|
License: MIT
|
|
@@ -15,8 +15,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.14
|
|
16
16
|
Requires-Python: >=3.11
|
|
17
17
|
Requires-Dist: elasticsearch[async]~=8.19.1
|
|
18
|
-
Requires-Dist: sfeos-helpers==6.10.
|
|
19
|
-
Requires-Dist: stac-fastapi-core==6.10.
|
|
18
|
+
Requires-Dist: sfeos-helpers==6.10.1
|
|
19
|
+
Requires-Dist: stac-fastapi-core==6.10.1
|
|
20
20
|
Requires-Dist: starlette<0.36.0,>=0.35.0
|
|
21
21
|
Requires-Dist: uvicorn~=0.23.0
|
|
22
22
|
Provides-Extra: dev
|
|
@@ -28,7 +28,7 @@ Requires-Dist: pytest-cov~=4.0.0; extra == 'dev'
|
|
|
28
28
|
Requires-Dist: pytest~=8.0; extra == 'dev'
|
|
29
29
|
Requires-Dist: redis~=6.4.0; extra == 'dev'
|
|
30
30
|
Requires-Dist: retry~=0.9.2; extra == 'dev'
|
|
31
|
-
Requires-Dist: stac-fastapi-core[redis]==6.10.
|
|
31
|
+
Requires-Dist: stac-fastapi-core[redis]==6.10.1; extra == 'dev'
|
|
32
32
|
Provides-Extra: docs
|
|
33
33
|
Requires-Dist: mkdocs-material~=9.0.0; extra == 'docs'
|
|
34
34
|
Requires-Dist: mkdocs~=1.4.0; extra == 'docs'
|
|
@@ -36,7 +36,7 @@ Requires-Dist: pdocs~=1.2.0; extra == 'docs'
|
|
|
36
36
|
Requires-Dist: redis~=6.4.0; extra == 'docs'
|
|
37
37
|
Requires-Dist: retry~=0.9.2; extra == 'docs'
|
|
38
38
|
Provides-Extra: redis
|
|
39
|
-
Requires-Dist: stac-fastapi-core[redis]==6.10.
|
|
39
|
+
Requires-Dist: stac-fastapi-core[redis]==6.10.1; extra == 'redis'
|
|
40
40
|
Provides-Extra: server
|
|
41
41
|
Requires-Dist: uvicorn[standard]~=0.23.0; extra == 'server'
|
|
42
42
|
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
|
"elasticsearch[async]~=8.19.1",
|
|
34
34
|
"uvicorn~=0.23.0",
|
|
35
35
|
"starlette>=0.35.0,<0.36.0",
|
|
@@ -48,7 +48,7 @@ dev = [
|
|
|
48
48
|
"httpx>=0.24.0,<0.28.0",
|
|
49
49
|
"redis~=6.4.0",
|
|
50
50
|
"retry~=0.9.2",
|
|
51
|
-
"stac-fastapi-core[redis]==6.10.
|
|
51
|
+
"stac-fastapi-core[redis]==6.10.1",
|
|
52
52
|
]
|
|
53
53
|
docs = [
|
|
54
54
|
"mkdocs~=1.4.0",
|
|
@@ -58,7 +58,7 @@ docs = [
|
|
|
58
58
|
"retry~=0.9.2",
|
|
59
59
|
]
|
|
60
60
|
redis = [
|
|
61
|
-
"stac-fastapi-core[redis]==6.10.
|
|
61
|
+
"stac-fastapi-core[redis]==6.10.1",
|
|
62
62
|
]
|
|
63
63
|
server = [
|
|
64
64
|
"uvicorn[standard]~=0.23.0",
|
|
@@ -244,7 +244,7 @@ items_get_request_model = create_request_model(
|
|
|
244
244
|
app_config = {
|
|
245
245
|
"title": os.getenv("STAC_FASTAPI_TITLE", "stac-fastapi-elasticsearch"),
|
|
246
246
|
"description": os.getenv("STAC_FASTAPI_DESCRIPTION", "stac-fastapi-elasticsearch"),
|
|
247
|
-
"api_version": os.getenv("STAC_FASTAPI_VERSION", "6.10.
|
|
247
|
+
"api_version": os.getenv("STAC_FASTAPI_VERSION", "6.10.1"),
|
|
248
248
|
"settings": settings,
|
|
249
249
|
"extensions": extensions,
|
|
250
250
|
"client": CoreClient(
|
|
@@ -33,11 +33,14 @@ from stac_fastapi.extensions.core.transaction.request import (
|
|
|
33
33
|
PatchOperation,
|
|
34
34
|
)
|
|
35
35
|
from stac_fastapi.sfeos_helpers.database import (
|
|
36
|
+
ItemAlreadyExistsError,
|
|
36
37
|
add_bbox_shape_to_collection,
|
|
37
38
|
apply_collections_bbox_filter_shared,
|
|
38
39
|
apply_collections_datetime_filter_shared,
|
|
39
40
|
apply_free_text_filter_shared,
|
|
40
41
|
apply_intersects_filter_shared,
|
|
42
|
+
check_item_exists_in_alias,
|
|
43
|
+
check_item_exists_in_alias_sync,
|
|
41
44
|
create_index_templates_shared,
|
|
42
45
|
delete_item_index_shared,
|
|
43
46
|
get_queryables_mapping_shared,
|
|
@@ -996,6 +999,44 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
996
999
|
if not await self.client.exists(index=COLLECTIONS_INDEX, id=collection_id):
|
|
997
1000
|
raise NotFoundError(f"Collection {collection_id} does not exist")
|
|
998
1001
|
|
|
1002
|
+
async def _check_item_exists_in_collection(
|
|
1003
|
+
self, collection_id: str, item_id: str
|
|
1004
|
+
) -> bool:
|
|
1005
|
+
"""Check if an item exists across all indexes for a collection.
|
|
1006
|
+
|
|
1007
|
+
Args:
|
|
1008
|
+
collection_id (str): The collection identifier.
|
|
1009
|
+
item_id (str): The item identifier.
|
|
1010
|
+
|
|
1011
|
+
Returns:
|
|
1012
|
+
bool: True if the item exists in any index, False otherwise.
|
|
1013
|
+
"""
|
|
1014
|
+
alias = index_alias_by_collection_id(collection_id)
|
|
1015
|
+
doc_id = mk_item_id(item_id, collection_id)
|
|
1016
|
+
try:
|
|
1017
|
+
return await check_item_exists_in_alias(self.client, alias, doc_id)
|
|
1018
|
+
except Exception:
|
|
1019
|
+
return False
|
|
1020
|
+
|
|
1021
|
+
def _check_item_exists_in_collection_sync(
|
|
1022
|
+
self, collection_id: str, item_id: str
|
|
1023
|
+
) -> bool:
|
|
1024
|
+
"""Check if an item exists across all indexes for a collection (sync version).
|
|
1025
|
+
|
|
1026
|
+
Args:
|
|
1027
|
+
collection_id (str): The collection identifier.
|
|
1028
|
+
item_id (str): The item identifier.
|
|
1029
|
+
|
|
1030
|
+
Returns:
|
|
1031
|
+
bool: True if the item exists in any index, False otherwise.
|
|
1032
|
+
"""
|
|
1033
|
+
alias = index_alias_by_collection_id(collection_id)
|
|
1034
|
+
doc_id = mk_item_id(item_id, collection_id)
|
|
1035
|
+
try:
|
|
1036
|
+
return check_item_exists_in_alias_sync(self.sync_client, alias, doc_id)
|
|
1037
|
+
except Exception:
|
|
1038
|
+
return False
|
|
1039
|
+
|
|
999
1040
|
async def async_prep_create_item(
|
|
1000
1041
|
self, item: Item, base_url: str, exist_ok: bool = False
|
|
1001
1042
|
) -> Item:
|
|
@@ -1011,31 +1052,21 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1011
1052
|
Item: The prepped item.
|
|
1012
1053
|
|
|
1013
1054
|
Raises:
|
|
1014
|
-
|
|
1055
|
+
ItemAlreadyExistsError: If the item already exists in the database.
|
|
1015
1056
|
|
|
1016
1057
|
"""
|
|
1017
1058
|
await self.check_collection_exists(collection_id=item["collection"])
|
|
1018
|
-
alias = index_alias_by_collection_id(item["collection"])
|
|
1019
|
-
doc_id = mk_item_id(item["id"], item["collection"])
|
|
1020
|
-
|
|
1021
|
-
if not exist_ok:
|
|
1022
|
-
alias_exists = await self.client.indices.exists_alias(name=alias)
|
|
1023
|
-
|
|
1024
|
-
if alias_exists:
|
|
1025
|
-
alias_info = await self.client.indices.get_alias(name=alias)
|
|
1026
|
-
indices = list(alias_info.keys())
|
|
1027
1059
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
)
|
|
1060
|
+
if not exist_ok and await self._check_item_exists_in_collection(
|
|
1061
|
+
item["collection"], item["id"]
|
|
1062
|
+
):
|
|
1063
|
+
raise ItemAlreadyExistsError(item["id"], item["collection"])
|
|
1033
1064
|
|
|
1034
1065
|
return self.item_serializer.stac_to_db(item, base_url)
|
|
1035
1066
|
|
|
1036
1067
|
async def bulk_async_prep_create_item(
|
|
1037
1068
|
self, item: Item, base_url: str, exist_ok: bool = False
|
|
1038
|
-
) -> Item:
|
|
1069
|
+
) -> Optional[Item]:
|
|
1039
1070
|
"""
|
|
1040
1071
|
Prepare an item for insertion into the database.
|
|
1041
1072
|
|
|
@@ -1063,20 +1094,18 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1063
1094
|
# Check if the collection exists
|
|
1064
1095
|
await self.check_collection_exists(collection_id=item["collection"])
|
|
1065
1096
|
|
|
1066
|
-
# Check if the item already exists in the database
|
|
1067
|
-
if not exist_ok and await self.
|
|
1068
|
-
|
|
1069
|
-
id=mk_item_id(item["id"], item["collection"]),
|
|
1097
|
+
# Check if the item already exists in the database (across all datetime indexes)
|
|
1098
|
+
if not exist_ok and await self._check_item_exists_in_collection(
|
|
1099
|
+
item["collection"], item["id"]
|
|
1070
1100
|
):
|
|
1071
|
-
error_message = (
|
|
1072
|
-
f"Item {item['id']} in collection {item['collection']} already exists."
|
|
1073
|
-
)
|
|
1074
1101
|
if self.async_settings.raise_on_bulk_error:
|
|
1075
|
-
raise
|
|
1102
|
+
raise ItemAlreadyExistsError(item["id"], item["collection"])
|
|
1076
1103
|
else:
|
|
1077
1104
|
logger.warning(
|
|
1078
|
-
f"{
|
|
1105
|
+
f"Item {item['id']} in collection {item['collection']} already exists. "
|
|
1106
|
+
"Skipping as `RAISE_ON_BULK_ERROR` is set to false."
|
|
1079
1107
|
)
|
|
1108
|
+
return None
|
|
1080
1109
|
|
|
1081
1110
|
# Serialize the item into a database-compatible format
|
|
1082
1111
|
prepped_item = self.item_serializer.stac_to_db(item, base_url)
|
|
@@ -1085,7 +1114,7 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1085
1114
|
|
|
1086
1115
|
def bulk_sync_prep_create_item(
|
|
1087
1116
|
self, item: Item, base_url: str, exist_ok: bool = False
|
|
1088
|
-
) -> Item:
|
|
1117
|
+
) -> Optional[Item]:
|
|
1089
1118
|
"""
|
|
1090
1119
|
Prepare an item for insertion into the database.
|
|
1091
1120
|
|
|
@@ -1114,26 +1143,18 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1114
1143
|
if not self.sync_client.exists(index=COLLECTIONS_INDEX, id=item["collection"]):
|
|
1115
1144
|
raise NotFoundError(f"Collection {item['collection']} does not exist")
|
|
1116
1145
|
|
|
1117
|
-
# Check if the item already exists in the database
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
if self.sync_client.exists(index=index, id=doc_id):
|
|
1130
|
-
error_message = f"Item {item['id']} in collection {item['collection']} already exists."
|
|
1131
|
-
if self.sync_settings.raise_on_bulk_error:
|
|
1132
|
-
raise ConflictError(error_message)
|
|
1133
|
-
else:
|
|
1134
|
-
logger.warning(
|
|
1135
|
-
f"{error_message} Continuing as `RAISE_ON_BULK_ERROR` is set to false."
|
|
1136
|
-
)
|
|
1146
|
+
# Check if the item already exists in the database (across all datetime indexes)
|
|
1147
|
+
if not exist_ok and self._check_item_exists_in_collection_sync(
|
|
1148
|
+
item["collection"], item["id"]
|
|
1149
|
+
):
|
|
1150
|
+
if self.sync_settings.raise_on_bulk_error:
|
|
1151
|
+
raise ItemAlreadyExistsError(item["id"], item["collection"])
|
|
1152
|
+
else:
|
|
1153
|
+
logger.warning(
|
|
1154
|
+
f"Item {item['id']} in collection {item['collection']} already exists. "
|
|
1155
|
+
"Skipping as `RAISE_ON_BULK_ERROR` is set to false."
|
|
1156
|
+
)
|
|
1157
|
+
return None
|
|
1137
1158
|
|
|
1138
1159
|
# Serialize the item into a database-compatible format
|
|
1139
1160
|
prepped_item = self.item_serializer.stac_to_db(item, base_url)
|
|
@@ -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
|
|
File without changes
|