stac-fastapi-elasticsearch 6.7.6__py3-none-any.whl → 6.8.0__py3-none-any.whl
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/app.py +20 -1
- stac_fastapi/elasticsearch/config.py +1 -1
- stac_fastapi/elasticsearch/database_logic.py +250 -33
- stac_fastapi/elasticsearch/version.py +1 -1
- {stac_fastapi_elasticsearch-6.7.6.dist-info → stac_fastapi_elasticsearch-6.8.0.dist-info}/METADATA +6 -6
- stac_fastapi_elasticsearch-6.8.0.dist-info/RECORD +9 -0
- stac_fastapi_elasticsearch-6.7.6.dist-info/RECORD +0 -9
- {stac_fastapi_elasticsearch-6.7.6.dist-info → stac_fastapi_elasticsearch-6.8.0.dist-info}/WHEEL +0 -0
- {stac_fastapi_elasticsearch-6.7.6.dist-info → stac_fastapi_elasticsearch-6.8.0.dist-info}/entry_points.txt +0 -0
|
@@ -23,6 +23,7 @@ from stac_fastapi.core.extensions.aggregation import (
|
|
|
23
23
|
EsAggregationExtensionGetRequest,
|
|
24
24
|
EsAggregationExtensionPostRequest,
|
|
25
25
|
)
|
|
26
|
+
from stac_fastapi.core.extensions.catalogs import CatalogsExtension
|
|
26
27
|
from stac_fastapi.core.extensions.collections_search import (
|
|
27
28
|
CollectionsSearchEndpointExtension,
|
|
28
29
|
)
|
|
@@ -65,11 +66,13 @@ ENABLE_COLLECTIONS_SEARCH = get_bool_env("ENABLE_COLLECTIONS_SEARCH", default=Tr
|
|
|
65
66
|
ENABLE_COLLECTIONS_SEARCH_ROUTE = get_bool_env(
|
|
66
67
|
"ENABLE_COLLECTIONS_SEARCH_ROUTE", default=False
|
|
67
68
|
)
|
|
69
|
+
ENABLE_CATALOGS_ROUTE = get_bool_env("ENABLE_CATALOGS_ROUTE", default=False)
|
|
68
70
|
logger.info("TRANSACTIONS_EXTENSIONS is set to %s", TRANSACTIONS_EXTENSIONS)
|
|
69
71
|
logger.info("ENABLE_COLLECTIONS_SEARCH is set to %s", ENABLE_COLLECTIONS_SEARCH)
|
|
70
72
|
logger.info(
|
|
71
73
|
"ENABLE_COLLECTIONS_SEARCH_ROUTE is set to %s", ENABLE_COLLECTIONS_SEARCH_ROUTE
|
|
72
74
|
)
|
|
75
|
+
logger.info("ENABLE_CATALOGS_ROUTE is set to %s", ENABLE_CATALOGS_ROUTE)
|
|
73
76
|
|
|
74
77
|
settings = ElasticsearchSettings()
|
|
75
78
|
session = Session.create_from_settings(settings)
|
|
@@ -202,6 +205,22 @@ if ENABLE_COLLECTIONS_SEARCH_ROUTE:
|
|
|
202
205
|
extensions.append(collections_search_endpoint_ext)
|
|
203
206
|
|
|
204
207
|
|
|
208
|
+
if ENABLE_CATALOGS_ROUTE:
|
|
209
|
+
catalogs_extension = CatalogsExtension(
|
|
210
|
+
client=CoreClient(
|
|
211
|
+
database=database_logic,
|
|
212
|
+
session=session,
|
|
213
|
+
post_request_model=collection_search_post_request_model,
|
|
214
|
+
landing_page_id=os.getenv("STAC_FASTAPI_LANDING_PAGE_ID", "stac-fastapi"),
|
|
215
|
+
),
|
|
216
|
+
settings=settings,
|
|
217
|
+
conformance_classes=[
|
|
218
|
+
"https://api.stacspec.org/v1.0.0-beta.1/catalogs-endpoint",
|
|
219
|
+
],
|
|
220
|
+
)
|
|
221
|
+
extensions.append(catalogs_extension)
|
|
222
|
+
|
|
223
|
+
|
|
205
224
|
database_logic.extensions = [type(ext).__name__ for ext in extensions]
|
|
206
225
|
|
|
207
226
|
post_request_model = create_post_request_model(search_extensions)
|
|
@@ -225,7 +244,7 @@ items_get_request_model = create_request_model(
|
|
|
225
244
|
app_config = {
|
|
226
245
|
"title": os.getenv("STAC_FASTAPI_TITLE", "stac-fastapi-elasticsearch"),
|
|
227
246
|
"description": os.getenv("STAC_FASTAPI_DESCRIPTION", "stac-fastapi-elasticsearch"),
|
|
228
|
-
"api_version": os.getenv("STAC_FASTAPI_VERSION", "6.
|
|
247
|
+
"api_version": os.getenv("STAC_FASTAPI_VERSION", "6.8.0"),
|
|
229
248
|
"settings": settings,
|
|
230
249
|
"extensions": extensions,
|
|
231
250
|
"client": CoreClient(
|
|
@@ -58,7 +58,7 @@ def _es_config() -> Dict[str, Any]:
|
|
|
58
58
|
|
|
59
59
|
# Include timeout setting if set
|
|
60
60
|
if request_timeout := os.getenv("ES_TIMEOUT"):
|
|
61
|
-
config["request_timeout"] = request_timeout
|
|
61
|
+
config["request_timeout"] = int(request_timeout)
|
|
62
62
|
|
|
63
63
|
# Explicitly exclude SSL settings when not using SSL
|
|
64
64
|
if not use_ssl:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Database logic."""
|
|
2
|
-
|
|
3
2
|
import asyncio
|
|
4
3
|
import logging
|
|
4
|
+
import os
|
|
5
5
|
from base64 import urlsafe_b64decode, urlsafe_b64encode
|
|
6
6
|
from copy import deepcopy
|
|
7
7
|
from typing import Any, Dict, Iterable, List, Optional, Tuple, Type
|
|
@@ -15,8 +15,13 @@ from elasticsearch.exceptions import NotFoundError as ESNotFoundError
|
|
|
15
15
|
from fastapi import HTTPException
|
|
16
16
|
from starlette.requests import Request
|
|
17
17
|
|
|
18
|
+
import stac_fastapi.sfeos_helpers.filter as filter_module
|
|
18
19
|
from stac_fastapi.core.base_database_logic import BaseDatabaseLogic
|
|
19
|
-
from stac_fastapi.core.serializers import
|
|
20
|
+
from stac_fastapi.core.serializers import (
|
|
21
|
+
CatalogSerializer,
|
|
22
|
+
CollectionSerializer,
|
|
23
|
+
ItemSerializer,
|
|
24
|
+
)
|
|
20
25
|
from stac_fastapi.core.utilities import MAX_LIMIT, bbox2polygon, get_bool_env
|
|
21
26
|
from stac_fastapi.elasticsearch.config import AsyncElasticsearchSettings
|
|
22
27
|
from stac_fastapi.elasticsearch.config import (
|
|
@@ -27,7 +32,6 @@ from stac_fastapi.extensions.core.transaction.request import (
|
|
|
27
32
|
PartialItem,
|
|
28
33
|
PatchOperation,
|
|
29
34
|
)
|
|
30
|
-
from stac_fastapi.sfeos_helpers import filter as filter_module
|
|
31
35
|
from stac_fastapi.sfeos_helpers.database import (
|
|
32
36
|
add_bbox_shape_to_collection,
|
|
33
37
|
apply_collections_bbox_filter_shared,
|
|
@@ -144,11 +148,32 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
144
148
|
collection_serializer: Type[CollectionSerializer] = attr.ib(
|
|
145
149
|
default=CollectionSerializer
|
|
146
150
|
)
|
|
151
|
+
catalog_serializer: Type[CatalogSerializer] = attr.ib(default=CatalogSerializer)
|
|
147
152
|
|
|
148
153
|
extensions: List[str] = attr.ib(default=attr.Factory(list))
|
|
149
154
|
|
|
150
155
|
aggregation_mapping: Dict[str, Dict[str, Any]] = AGGREGATION_MAPPING
|
|
151
156
|
|
|
157
|
+
# constants for field names
|
|
158
|
+
# they are used in multiple methods
|
|
159
|
+
# and could be overwritten in subclasses used with alternate opensearch mappings.
|
|
160
|
+
PROPERTIES_DATETIME_FIELD = os.getenv(
|
|
161
|
+
"STAC_FIELD_PROP_DATETIME", "properties.datetime"
|
|
162
|
+
)
|
|
163
|
+
PROPERTIES_START_DATETIME_FIELD = os.getenv(
|
|
164
|
+
"STAC_FIELD_PROP_START_DATETIME", "properties.start_datetime"
|
|
165
|
+
)
|
|
166
|
+
PROPERTIES_END_DATETIME_FIELD = os.getenv(
|
|
167
|
+
"STAC_FIELD_PROP_END_DATETIME", "properties.end_datetime"
|
|
168
|
+
)
|
|
169
|
+
COLLECTION_FIELD = os.getenv("STAC_FIELD_COLLECTION", "collection")
|
|
170
|
+
GEOMETRY_FIELD = os.getenv("STAC_FIELD_GEOMETRY", "geometry")
|
|
171
|
+
|
|
172
|
+
@staticmethod
|
|
173
|
+
def __nested_field__(field: str):
|
|
174
|
+
"""Convert opensearch field to nested field format."""
|
|
175
|
+
return field.replace(".", "__")
|
|
176
|
+
|
|
152
177
|
"""CORE LOGIC"""
|
|
153
178
|
|
|
154
179
|
async def get_all_collections(
|
|
@@ -431,7 +456,10 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
431
456
|
@staticmethod
|
|
432
457
|
def apply_collections_filter(search: Search, collection_ids: List[str]):
|
|
433
458
|
"""Database logic to search a list of STAC collection ids."""
|
|
434
|
-
|
|
459
|
+
collection_nested_field = DatabaseLogic.__nested_field__(
|
|
460
|
+
DatabaseLogic.COLLECTION_FIELD
|
|
461
|
+
)
|
|
462
|
+
return search.filter("terms", **{collection_nested_field: collection_ids})
|
|
435
463
|
|
|
436
464
|
@staticmethod
|
|
437
465
|
def apply_datetime_filter(
|
|
@@ -456,6 +484,16 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
456
484
|
if not datetime_search:
|
|
457
485
|
return search, datetime_search
|
|
458
486
|
|
|
487
|
+
nested_datetime_field = DatabaseLogic.__nested_field__(
|
|
488
|
+
DatabaseLogic.PROPERTIES_DATETIME_FIELD
|
|
489
|
+
)
|
|
490
|
+
nested_start_datetime_field = DatabaseLogic.__nested_field__(
|
|
491
|
+
DatabaseLogic.PROPERTIES_START_DATETIME_FIELD
|
|
492
|
+
)
|
|
493
|
+
nested_end_datetime_field = DatabaseLogic.__nested_field__(
|
|
494
|
+
DatabaseLogic.PROPERTIES_END_DATETIME_FIELD
|
|
495
|
+
)
|
|
496
|
+
|
|
459
497
|
if USE_DATETIME:
|
|
460
498
|
if "eq" in datetime_search:
|
|
461
499
|
# For exact matches, include:
|
|
@@ -465,28 +503,42 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
465
503
|
Q(
|
|
466
504
|
"bool",
|
|
467
505
|
filter=[
|
|
468
|
-
Q("exists", field=
|
|
506
|
+
Q("exists", field=DatabaseLogic.PROPERTIES_DATETIME_FIELD),
|
|
469
507
|
Q(
|
|
470
508
|
"term",
|
|
471
|
-
**{
|
|
509
|
+
**{nested_datetime_field: datetime_search["eq"]},
|
|
472
510
|
),
|
|
473
511
|
],
|
|
474
512
|
),
|
|
475
513
|
Q(
|
|
476
514
|
"bool",
|
|
477
|
-
must_not=[
|
|
515
|
+
must_not=[
|
|
516
|
+
Q("exists", field=DatabaseLogic.PROPERTIES_DATETIME_FIELD)
|
|
517
|
+
],
|
|
478
518
|
filter=[
|
|
479
|
-
Q(
|
|
480
|
-
|
|
519
|
+
Q(
|
|
520
|
+
"exists",
|
|
521
|
+
field=DatabaseLogic.PROPERTIES_START_DATETIME_FIELD,
|
|
522
|
+
),
|
|
523
|
+
Q(
|
|
524
|
+
"exists",
|
|
525
|
+
field=DatabaseLogic.PROPERTIES_END_DATETIME_FIELD,
|
|
526
|
+
),
|
|
481
527
|
Q(
|
|
482
528
|
"range",
|
|
483
|
-
|
|
484
|
-
|
|
529
|
+
**{
|
|
530
|
+
nested_start_datetime_field: {
|
|
531
|
+
"lte": datetime_search["eq"]
|
|
532
|
+
}
|
|
485
533
|
},
|
|
486
534
|
),
|
|
487
535
|
Q(
|
|
488
536
|
"range",
|
|
489
|
-
|
|
537
|
+
**{
|
|
538
|
+
nested_end_datetime_field: {
|
|
539
|
+
"gte": datetime_search["eq"]
|
|
540
|
+
}
|
|
541
|
+
},
|
|
490
542
|
),
|
|
491
543
|
],
|
|
492
544
|
),
|
|
@@ -499,32 +551,46 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
499
551
|
Q(
|
|
500
552
|
"bool",
|
|
501
553
|
filter=[
|
|
502
|
-
Q("exists", field=
|
|
554
|
+
Q("exists", field=DatabaseLogic.PROPERTIES_DATETIME_FIELD),
|
|
503
555
|
Q(
|
|
504
556
|
"range",
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
557
|
+
**{
|
|
558
|
+
nested_datetime_field: {
|
|
559
|
+
"gte": datetime_search["gte"],
|
|
560
|
+
"lte": datetime_search["lte"],
|
|
561
|
+
}
|
|
508
562
|
},
|
|
509
563
|
),
|
|
510
564
|
],
|
|
511
565
|
),
|
|
512
566
|
Q(
|
|
513
567
|
"bool",
|
|
514
|
-
must_not=[
|
|
568
|
+
must_not=[
|
|
569
|
+
Q("exists", field=DatabaseLogic.PROPERTIES_DATETIME_FIELD)
|
|
570
|
+
],
|
|
515
571
|
filter=[
|
|
516
|
-
Q(
|
|
517
|
-
|
|
572
|
+
Q(
|
|
573
|
+
"exists",
|
|
574
|
+
field=DatabaseLogic.PROPERTIES_START_DATETIME_FIELD,
|
|
575
|
+
),
|
|
576
|
+
Q(
|
|
577
|
+
"exists",
|
|
578
|
+
field=DatabaseLogic.PROPERTIES_END_DATETIME_FIELD,
|
|
579
|
+
),
|
|
518
580
|
Q(
|
|
519
581
|
"range",
|
|
520
|
-
|
|
521
|
-
|
|
582
|
+
**{
|
|
583
|
+
nested_start_datetime_field: {
|
|
584
|
+
"lte": datetime_search["lte"]
|
|
585
|
+
}
|
|
522
586
|
},
|
|
523
587
|
),
|
|
524
588
|
Q(
|
|
525
589
|
"range",
|
|
526
|
-
|
|
527
|
-
|
|
590
|
+
**{
|
|
591
|
+
nested_end_datetime_field: {
|
|
592
|
+
"gte": datetime_search["gte"]
|
|
593
|
+
}
|
|
528
594
|
},
|
|
529
595
|
),
|
|
530
596
|
],
|
|
@@ -540,15 +606,26 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
540
606
|
filter_query = Q(
|
|
541
607
|
"bool",
|
|
542
608
|
filter=[
|
|
543
|
-
Q(
|
|
544
|
-
|
|
609
|
+
Q(
|
|
610
|
+
"exists",
|
|
611
|
+
field=DatabaseLogic.PROPERTIES_START_DATETIME_FIELD,
|
|
612
|
+
),
|
|
613
|
+
Q("exists", field=DatabaseLogic.PROPERTIES_END_DATETIME_FIELD),
|
|
545
614
|
Q(
|
|
546
615
|
"range",
|
|
547
|
-
|
|
616
|
+
**{
|
|
617
|
+
nested_start_datetime_field: {
|
|
618
|
+
"lte": datetime_search["eq"]
|
|
619
|
+
}
|
|
620
|
+
},
|
|
548
621
|
),
|
|
549
622
|
Q(
|
|
550
623
|
"range",
|
|
551
|
-
|
|
624
|
+
**{
|
|
625
|
+
nested_end_datetime_field: {
|
|
626
|
+
"gte": datetime_search["eq"]
|
|
627
|
+
}
|
|
628
|
+
},
|
|
552
629
|
),
|
|
553
630
|
],
|
|
554
631
|
)
|
|
@@ -556,15 +633,26 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
556
633
|
filter_query = Q(
|
|
557
634
|
"bool",
|
|
558
635
|
filter=[
|
|
559
|
-
Q(
|
|
560
|
-
|
|
636
|
+
Q(
|
|
637
|
+
"exists",
|
|
638
|
+
field=DatabaseLogic.PROPERTIES_START_DATETIME_FIELD,
|
|
639
|
+
),
|
|
640
|
+
Q("exists", field=DatabaseLogic.PROPERTIES_END_DATETIME_FIELD),
|
|
561
641
|
Q(
|
|
562
642
|
"range",
|
|
563
|
-
|
|
643
|
+
**{
|
|
644
|
+
nested_start_datetime_field: {
|
|
645
|
+
"lte": datetime_search["lte"]
|
|
646
|
+
}
|
|
647
|
+
},
|
|
564
648
|
),
|
|
565
649
|
Q(
|
|
566
650
|
"range",
|
|
567
|
-
|
|
651
|
+
**{
|
|
652
|
+
nested_end_datetime_field: {
|
|
653
|
+
"gte": datetime_search["gte"]
|
|
654
|
+
}
|
|
655
|
+
},
|
|
568
656
|
),
|
|
569
657
|
],
|
|
570
658
|
)
|
|
@@ -589,7 +677,7 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
589
677
|
Q(
|
|
590
678
|
{
|
|
591
679
|
"geo_shape": {
|
|
592
|
-
|
|
680
|
+
DatabaseLogic.GEOMETRY_FIELD: {
|
|
593
681
|
"shape": {
|
|
594
682
|
"type": "polygon",
|
|
595
683
|
"coordinates": bbox2polygon(*bbox),
|
|
@@ -1703,7 +1791,7 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1703
1791
|
kwargs = kwargs or {}
|
|
1704
1792
|
|
|
1705
1793
|
# Resolve the `refresh` parameter
|
|
1706
|
-
refresh = kwargs.get("refresh", self.
|
|
1794
|
+
refresh = kwargs.get("refresh", self.sync_settings.database_refresh)
|
|
1707
1795
|
refresh = validate_refresh(refresh)
|
|
1708
1796
|
|
|
1709
1797
|
# Log the bulk insert attempt
|
|
@@ -1749,3 +1837,132 @@ class DatabaseLogic(BaseDatabaseLogic):
|
|
|
1749
1837
|
body={"query": {"match_all": {}}},
|
|
1750
1838
|
wait_for_completion=True,
|
|
1751
1839
|
)
|
|
1840
|
+
|
|
1841
|
+
"""CATALOGS LOGIC"""
|
|
1842
|
+
|
|
1843
|
+
async def get_all_catalogs(
|
|
1844
|
+
self,
|
|
1845
|
+
token: Optional[str],
|
|
1846
|
+
limit: int,
|
|
1847
|
+
request: Any = None,
|
|
1848
|
+
sort: Optional[List[Dict[str, Any]]] = None,
|
|
1849
|
+
) -> Tuple[List[Dict[str, Any]], Optional[str], Optional[int]]:
|
|
1850
|
+
"""Retrieve a list of catalogs from Elasticsearch, supporting pagination.
|
|
1851
|
+
|
|
1852
|
+
Args:
|
|
1853
|
+
token (Optional[str]): The pagination token.
|
|
1854
|
+
limit (int): The number of results to return.
|
|
1855
|
+
request (Any, optional): The FastAPI request object. Defaults to None.
|
|
1856
|
+
sort (Optional[List[Dict[str, Any]]], optional): Optional sort parameter. Defaults to None.
|
|
1857
|
+
|
|
1858
|
+
Returns:
|
|
1859
|
+
A tuple of (catalogs, next pagination token if any, optional count).
|
|
1860
|
+
"""
|
|
1861
|
+
# Define sortable fields for catalogs
|
|
1862
|
+
sortable_fields = ["id"]
|
|
1863
|
+
|
|
1864
|
+
# Format the sort parameter
|
|
1865
|
+
formatted_sort = []
|
|
1866
|
+
if sort:
|
|
1867
|
+
for item in sort:
|
|
1868
|
+
field = item.get("field")
|
|
1869
|
+
direction = item.get("direction", "asc")
|
|
1870
|
+
if field and field in sortable_fields:
|
|
1871
|
+
formatted_sort.append({field: {"order": direction}})
|
|
1872
|
+
|
|
1873
|
+
if not formatted_sort:
|
|
1874
|
+
formatted_sort = [{"id": {"order": "asc"}}]
|
|
1875
|
+
|
|
1876
|
+
body = {
|
|
1877
|
+
"sort": formatted_sort,
|
|
1878
|
+
"size": limit,
|
|
1879
|
+
"query": {"term": {"type": "Catalog"}},
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
# Handle search_after token
|
|
1883
|
+
search_after = None
|
|
1884
|
+
if token:
|
|
1885
|
+
try:
|
|
1886
|
+
search_after = token.split("|")
|
|
1887
|
+
if len(search_after) != len(formatted_sort):
|
|
1888
|
+
search_after = None
|
|
1889
|
+
except Exception:
|
|
1890
|
+
search_after = None
|
|
1891
|
+
|
|
1892
|
+
if search_after is not None:
|
|
1893
|
+
body["search_after"] = search_after
|
|
1894
|
+
|
|
1895
|
+
# Search for catalogs in collections index
|
|
1896
|
+
response = await self.client.search(
|
|
1897
|
+
index=COLLECTIONS_INDEX,
|
|
1898
|
+
body=body,
|
|
1899
|
+
)
|
|
1900
|
+
|
|
1901
|
+
hits = response["hits"]["hits"]
|
|
1902
|
+
catalogs = [hit["_source"] for hit in hits]
|
|
1903
|
+
|
|
1904
|
+
next_token = None
|
|
1905
|
+
if len(hits) == limit:
|
|
1906
|
+
next_token_values = hits[-1].get("sort")
|
|
1907
|
+
if next_token_values:
|
|
1908
|
+
next_token = "|".join(str(val) for val in next_token_values)
|
|
1909
|
+
|
|
1910
|
+
# Get the total count
|
|
1911
|
+
matched = (
|
|
1912
|
+
response["hits"]["total"]["value"]
|
|
1913
|
+
if response["hits"]["total"]["relation"] == "eq"
|
|
1914
|
+
else None
|
|
1915
|
+
)
|
|
1916
|
+
|
|
1917
|
+
return catalogs, next_token, matched
|
|
1918
|
+
|
|
1919
|
+
async def create_catalog(self, catalog: Dict, refresh: bool = False) -> None:
|
|
1920
|
+
"""Create a catalog in Elasticsearch.
|
|
1921
|
+
|
|
1922
|
+
Args:
|
|
1923
|
+
catalog (Dict): The catalog document to create.
|
|
1924
|
+
refresh (bool): Whether to refresh the index after creation.
|
|
1925
|
+
"""
|
|
1926
|
+
await self.client.index(
|
|
1927
|
+
index=COLLECTIONS_INDEX,
|
|
1928
|
+
id=catalog.get("id"),
|
|
1929
|
+
body=catalog,
|
|
1930
|
+
refresh=refresh,
|
|
1931
|
+
)
|
|
1932
|
+
|
|
1933
|
+
async def find_catalog(self, catalog_id: str) -> Dict:
|
|
1934
|
+
"""Find a catalog in Elasticsearch by ID.
|
|
1935
|
+
|
|
1936
|
+
Args:
|
|
1937
|
+
catalog_id (str): The ID of the catalog to find.
|
|
1938
|
+
|
|
1939
|
+
Returns:
|
|
1940
|
+
Dict: The catalog document.
|
|
1941
|
+
|
|
1942
|
+
Raises:
|
|
1943
|
+
NotFoundError: If the catalog is not found.
|
|
1944
|
+
"""
|
|
1945
|
+
try:
|
|
1946
|
+
response = await self.client.get(
|
|
1947
|
+
index=COLLECTIONS_INDEX,
|
|
1948
|
+
id=catalog_id,
|
|
1949
|
+
)
|
|
1950
|
+
# Verify it's a catalog
|
|
1951
|
+
if response["_source"].get("type") != "Catalog":
|
|
1952
|
+
raise NotFoundError(f"Catalog {catalog_id} not found")
|
|
1953
|
+
return response["_source"]
|
|
1954
|
+
except ESNotFoundError:
|
|
1955
|
+
raise NotFoundError(f"Catalog {catalog_id} not found")
|
|
1956
|
+
|
|
1957
|
+
async def delete_catalog(self, catalog_id: str, refresh: bool = False) -> None:
|
|
1958
|
+
"""Delete a catalog from Elasticsearch.
|
|
1959
|
+
|
|
1960
|
+
Args:
|
|
1961
|
+
catalog_id (str): The ID of the catalog to delete.
|
|
1962
|
+
refresh (bool): Whether to refresh the index after deletion.
|
|
1963
|
+
"""
|
|
1964
|
+
await self.client.delete(
|
|
1965
|
+
index=COLLECTIONS_INDEX,
|
|
1966
|
+
id=catalog_id,
|
|
1967
|
+
refresh=refresh,
|
|
1968
|
+
)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""library version."""
|
|
2
|
-
__version__ = "6.
|
|
2
|
+
__version__ = "6.8.0"
|
{stac_fastapi_elasticsearch-6.7.6.dist-info → stac_fastapi_elasticsearch-6.8.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stac_fastapi_elasticsearch
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.8.0
|
|
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.
|
|
19
|
-
Requires-Dist: stac-fastapi-core==6.
|
|
18
|
+
Requires-Dist: sfeos-helpers==6.8.0
|
|
19
|
+
Requires-Dist: stac-fastapi-core==6.8.0
|
|
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.
|
|
31
|
+
Requires-Dist: stac-fastapi-core[redis]==6.8.0; 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.
|
|
39
|
+
Requires-Dist: stac-fastapi-core[redis]==6.8.0; 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
|
|
@@ -53,7 +53,7 @@ Description-Content-Type: text/markdown
|
|
|
53
53
|
[](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/network/members)
|
|
54
54
|
[](https://pypi.org/project/stac-fastapi-elasticsearch/)
|
|
55
55
|
[](https://github.com/radiantearth/stac-spec/tree/v1.1.0)
|
|
56
|
-
[](https://github.com/stac-utils/stac-fastapi)
|
|
57
57
|
|
|
58
58
|
This is the Elasticsearch backend for stac-fastapi. For full documentation, please see the [main README](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/blob/main/README.md).
|
|
59
59
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
stac_fastapi/elasticsearch/__init__.py,sha256=w_MZutYLreNV372sCuO46bPb0TngmPs4u8737ueS0wE,31
|
|
2
|
+
stac_fastapi/elasticsearch/app.py,sha256=QOQ0H-duCZBFc_T_IH22BvZEAuPhHNKlfMDig3TJEaU,10762
|
|
3
|
+
stac_fastapi/elasticsearch/config.py,sha256=CCQlqvakTjFKxrdCW8222Wz9f2WrMxi1uVkyxqA1R60,5327
|
|
4
|
+
stac_fastapi/elasticsearch/database_logic.py,sha256=ZecJRkzd0w7itmKi2AAfvyQZ9mgWlyhlOPpeq_4uneg,76362
|
|
5
|
+
stac_fastapi/elasticsearch/version.py,sha256=ib-H9zXMsXhMlZkHut5gkqf27FPYcv0_wBkKUIXnJbA,45
|
|
6
|
+
stac_fastapi_elasticsearch-6.8.0.dist-info/METADATA,sha256=GLYnhDcBBAD8UDVYMf6QGDHO4jtCl5_2Pyr8yYBUnO8,4072
|
|
7
|
+
stac_fastapi_elasticsearch-6.8.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
8
|
+
stac_fastapi_elasticsearch-6.8.0.dist-info/entry_points.txt,sha256=aCKixki0LpUl64UPsPMtiNvfdyq-QsTCxVjJ54VF6Jk,82
|
|
9
|
+
stac_fastapi_elasticsearch-6.8.0.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
stac_fastapi/elasticsearch/__init__.py,sha256=w_MZutYLreNV372sCuO46bPb0TngmPs4u8737ueS0wE,31
|
|
2
|
-
stac_fastapi/elasticsearch/app.py,sha256=f0CFbw6dCGOhW5pMPfCCo25ibv9fzfgcZwV8YoVoJO0,10024
|
|
3
|
-
stac_fastapi/elasticsearch/config.py,sha256=itvPYr4TiOg9pWQrycgGaQxQ_Vc2KKP3aHdtH0OUZvw,5322
|
|
4
|
-
stac_fastapi/elasticsearch/database_logic.py,sha256=mQgWkqcsVwxUHGzD8dh8n5KHSh83oLuX9DNx6m-YqDo,68730
|
|
5
|
-
stac_fastapi/elasticsearch/version.py,sha256=orOSypjxHuXOJkA8sMlrI-LUPRWXarswpIi-wr5CKPo,45
|
|
6
|
-
stac_fastapi_elasticsearch-6.7.6.dist-info/METADATA,sha256=PRk4oAUKq6x45Crc5klX3Qtc0sd4xV8P0KDxLcOEnhE,4072
|
|
7
|
-
stac_fastapi_elasticsearch-6.7.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
8
|
-
stac_fastapi_elasticsearch-6.7.6.dist-info/entry_points.txt,sha256=aCKixki0LpUl64UPsPMtiNvfdyq-QsTCxVjJ54VF6Jk,82
|
|
9
|
-
stac_fastapi_elasticsearch-6.7.6.dist-info/RECORD,,
|
{stac_fastapi_elasticsearch-6.7.6.dist-info → stac_fastapi_elasticsearch-6.8.0.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|