Skip to content
18 changes: 0 additions & 18 deletions stac_fastapi/core/stac_fastapi/core/extensions/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,6 @@
"description": "Creation Timestamp",
"$ref": "https://schemas.stacspec.org/v1.0.0/item-spec/json-schema/datetime.json#/properties/updated",
},
"cloud_cover": {
"description": "Cloud Cover",
"$ref": "https://stac-extensions.github.io/eo/v1.0.0/schema.json#/definitions/fields/properties/eo:cloud_cover",
},
"cloud_shadow_percentage": {
"title": "Cloud Shadow Percentage",
"description": "Cloud Shadow Percentage",
"type": "number",
"minimum": 0,
"maximum": 100,
},
"nodata_pixel_percentage": {
"title": "No Data Pixel Percentage",
"description": "No Data Pixel Percentage",
"type": "number",
"minimum": 0,
"maximum": 100,
},
}
"""Queryables that are present in all collections."""

Expand Down
57 changes: 31 additions & 26 deletions stac_fastapi/opensearch/stac_fastapi/opensearch/database_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
import asyncio
import logging
from base64 import urlsafe_b64decode, urlsafe_b64encode
from collections.abc import Iterable
from copy import deepcopy
from typing import Any, Dict, Iterable, List, Optional, Tuple, Type
from typing import Any, Dict, List, Optional, Tuple, Type

import attr
import orjson
from fastapi import HTTPException
from opensearchpy import exceptions, helpers
from opensearchpy.helpers.query import Q
from opensearchpy.helpers.search import Search
from starlette.requests import Request

from stac_fastapi.core.base_database_logic import BaseDatabaseLogic
from stac_fastapi.core.serializers import CollectionSerializer, ItemSerializer
from stac_fastapi.core.utilities import bbox2polygon, get_max_limit
Expand All @@ -26,7 +25,6 @@
AsyncOpensearchSettings as AsyncSearchSettings,
)
from stac_fastapi.opensearch.config import OpensearchSettings as SyncSearchSettings
from stac_fastapi.sfeos_helpers import filter as filter_module
from stac_fastapi.sfeos_helpers.database import (
apply_free_text_filter_shared,
apply_intersects_filter_shared,
Expand Down Expand Up @@ -66,6 +64,9 @@
from stac_fastapi.types.errors import ConflictError, NotFoundError
from stac_fastapi.types.links import resolve_links
from stac_fastapi.types.stac import Collection, Item
from starlette.requests import Request

from stac_fastapi.sfeos_helpers import filter as filter_module

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -387,19 +388,17 @@ def apply_bbox_filter(search: Search, bbox: List):
a geo_shape filter is added to the search object, set to intersect with the specified polygon.
"""
return search.filter(
Q(
{
"geo_shape": {
"geometry": {
"shape": {
"type": "polygon",
"coordinates": bbox2polygon(*bbox),
},
"relation": "intersects",
}
Q({
"geo_shape": {
"geometry": {
"shape": {
"type": "polygon",
"coordinates": bbox2polygon(*bbox),
},
"relation": "intersects",
}
}
)
})
)

@staticmethod
Expand Down Expand Up @@ -679,14 +678,21 @@ async def async_prep_create_item(

"""
await self.check_collection_exists(collection_id=item["collection"])
alias = index_alias_by_collection_id(item["collection"])
doc_id = mk_item_id(item["id"], item["collection"])

if not exist_ok and await self.client.exists(
index=index_alias_by_collection_id(item["collection"]),
id=mk_item_id(item["id"], item["collection"]),
):
raise ConflictError(
f"Item {item['id']} in collection {item['collection']} already exists"
)
if not exist_ok:
alias_exists = await self.client.indices.exists_alias(name=alias)

if alias_exists:
alias_info = await self.client.indices.get_alias(name=alias)
indices = list(alias_info.keys())

for index in indices:
if await self.client.exists(index=index, id=doc_id):
raise ConflictError(
f"Item {item['id']} in collection {item['collection']} already exists"
)

return self.item_serializer.stac_to_db(item, base_url)

Expand Down Expand Up @@ -903,7 +909,6 @@ async def json_patch_item(
"add",
"replace",
]:

if operation.path == "collection" and collection_id != operation.value:
await self.check_collection_exists(collection_id=operation.value)
new_collection_id = operation.value
Expand Down Expand Up @@ -957,8 +962,8 @@ async def json_patch_item(
"script": {
"lang": "painless",
"source": (
f"""ctx._id = ctx._id.replace('{collection_id}', '{new_collection_id}');""" # noqa: E702
f"""ctx._source.collection = '{new_collection_id}';""" # noqa: E702
f"""ctx._id = ctx._id.replace('{collection_id}', '{new_collection_id}');"""
f"""ctx._source.collection = '{new_collection_id}';"""
),
},
},
Expand Down Expand Up @@ -1180,7 +1185,7 @@ async def update_collection(
"source": {"index": f"{ITEMS_INDEX_PREFIX}{collection_id}"},
"script": {
"lang": "painless",
"source": f"""ctx._id = ctx._id.replace('{collection_id}', '{collection["id"]}'); ctx._source.collection = '{collection["id"]}' ;""", # noqa: E702
"source": f"""ctx._id = ctx._id.replace('{collection_id}', '{collection["id"]}'); ctx._source.collection = '{collection["id"]}' ;""",
},
},
wait_for_completion=True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Any, Dict, Optional, Tuple

import attr
from fastapi import Request

from stac_fastapi.core.base_database_logic import BaseDatabaseLogic
from stac_fastapi.core.extensions.filter import ALL_QUERYABLES, DEFAULT_QUERYABLES
Expand Down Expand Up @@ -37,9 +38,11 @@ async def get_queryables(
Returns:
Dict[str, Any]: A dictionary containing the queryables for the given collection.
"""
request: Optional[Request] = kwargs.get("request")
url_str: str = str(request.url) if request else ""
queryables: Dict[str, Any] = {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "https://stac-api.example.com/queryables",
"$schema": "https://json-schema.org/draft-07/schema",
"$id": f"{url_str}",
"type": "object",
"title": "Queryables for STAC API",
"description": "Queryable names for the STAC API Item Search filter.",
Expand All @@ -49,13 +52,11 @@ async def get_queryables(
if not collection_id:
return queryables

properties: Dict[str, Any] = queryables["properties"]
queryables.update(
{
"properties": properties,
"additionalProperties": False,
}
)
properties: Dict[str, Any] = queryables["properties"].copy()
queryables.update({
"properties": properties,
"additionalProperties": False,
})

mapping_data = await self.database.get_items_mapping(collection_id)
mapping_properties = next(iter(mapping_data.values()))["mappings"]["properties"]
Expand Down
Loading