Skip to content

Create shared sfeos helpers module #376

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5e99c8a
sfeos helpers module
jonhealy1 May 14, 2025
d3d4b16
move date fns, fliter fns
jonhealy1 May 14, 2025
d5b5009
db logic helpers
jonhealy1 May 15, 2025
8ad2cd6
Merge branch 'main' into sfeos-helpers
jonhealy1 May 16, 2025
14d88b2
update version
jonhealy1 May 16, 2025
67e1c4c
move to_es filter update to sfeos_helpers
jonhealy1 May 16, 2025
7ab88d4
es filter methods to sfeos helpers
jonhealy1 May 16, 2025
820c028
Merge branch 'main' into sfeos-helpers
jonhealy1 May 18, 2025
9ab8e99
create shared filter methods
jonhealy1 May 18, 2025
30ea1c7
shared delete items index
jonhealy1 May 18, 2025
e674381
share aggregations mapping
jonhealy1 May 18, 2025
b956bae
move logic to utilities
jonhealy1 May 18, 2025
149be4e
share queryables mapping
jonhealy1 May 18, 2025
9a68168
organization
jonhealy1 May 19, 2025
c0d5aac
create filter package
jonhealy1 May 19, 2025
a432274
database package
jonhealy1 May 19, 2025
36504af
move utility functions
jonhealy1 May 19, 2025
c39a85d
move return_date
jonhealy1 May 19, 2025
6903791
move format date range
jonhealy1 May 19, 2025
45dee7d
move refactor aggregations
jonhealy1 May 19, 2025
fc1488e
update banner
jonhealy1 May 19, 2025
e58cb68
update banner
jonhealy1 May 19, 2025
1f4e87d
update banner
jonhealy1 May 20, 2025
4664737
revert banner
jonhealy1 May 20, 2025
53c88e3
redesign readme
jonhealy1 May 20, 2025
aa6a256
add descriptions
jonhealy1 May 21, 2025
6426c56
move toc
jonhealy1 May 21, 2025
8fe1927
add readme updates
jonhealy1 May 23, 2025
2a71db9
Merge branch 'main' into sfeos-helpers
jonhealy1 May 23, 2025
7568d0c
add note
jonhealy1 May 23, 2025
187464d
Merge branch 'main' into sfeos-helpers
jonhealy1 May 27, 2025
0a8d9c8
make pr changes
jonhealy1 May 29, 2025
87cfbc2
Merge branch 'sfeos-helpers' of https://github.com/stac-utils/stac-fa…
jonhealy1 May 29, 2025
0345022
version to v5.0.0a0
jonhealy1 May 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
move utility functions
  • Loading branch information
jonhealy1 committed May 19, 2025
commit 36504af864915e611ca3d99b46b33c4f1b3497c7
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

from elasticsearch import Elasticsearch # type: ignore[attr-defined]
from stac_fastapi.core.base_settings import ApiBaseSettings
from stac_fastapi.sfeos_helpers.utilities import get_bool_env, validate_refresh
from stac_fastapi.core.utilities import get_bool_env
from stac_fastapi.sfeos_helpers.database import validate_refresh
from stac_fastapi.types.config import ApiSettings


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@
create_index_templates_shared,
delete_item_index_shared,
get_queryables_mapping_shared,
index_alias_by_collection_id,
index_by_collection_id,
indices,
mk_actions,
mk_item_id,
populate_sort_shared,
validate_refresh,
)
from stac_fastapi.sfeos_helpers.mappings import (
AGGREGATION_MAPPING,
Expand All @@ -37,14 +43,6 @@
ITEMS_INDEX_PREFIX,
Geometry,
)
from stac_fastapi.sfeos_helpers.utilities import (
index_alias_by_collection_id,
index_by_collection_id,
indices,
mk_actions,
mk_item_id,
validate_refresh,
)
from stac_fastapi.types.errors import ConflictError, NotFoundError
from stac_fastapi.types.stac import Collection, Item

Expand Down
3 changes: 2 additions & 1 deletion stac_fastapi/opensearch/stac_fastapi/opensearch/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from opensearchpy import AsyncOpenSearch, OpenSearch

from stac_fastapi.core.base_settings import ApiBaseSettings
from stac_fastapi.sfeos_helpers.utilities import get_bool_env, validate_refresh
from stac_fastapi.core.utilities import get_bool_env
from stac_fastapi.sfeos_helpers.database import validate_refresh
from stac_fastapi.types.config import ApiSettings


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@
create_index_templates_shared,
delete_item_index_shared,
get_queryables_mapping_shared,
index_alias_by_collection_id,
index_by_collection_id,
indices,
mk_actions,
mk_item_id,
populate_sort_shared,
validate_refresh,
)
from stac_fastapi.sfeos_helpers.mappings import (
AGGREGATION_MAPPING,
Expand All @@ -40,14 +46,6 @@
ITEMS_INDEX_PREFIX,
Geometry,
)
from stac_fastapi.sfeos_helpers.utilities import (
index_alias_by_collection_id,
index_by_collection_id,
indices,
mk_actions,
mk_item_id,
validate_refresh,
)
from stac_fastapi.types.errors import ConflictError, NotFoundError
from stac_fastapi.types.stac import Collection, Item

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ between the two implementations.

## Package Structure

The database package is organized into three main modules:
The database package is organized into five main modules:

- **index.py**: Contains functions for managing indices
- [create_index_templates_shared](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/database_logic_helpers.py:15:0-48:33): Creates index templates for Collections and Items
- [delete_item_index_shared](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/database_logic_helpers.py:128:0-153:30): Deletes an item index for a collection
- [index_by_collection_id](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/utilities.py:86:0-100:5): Translates a collection ID into an index name
- [index_alias_by_collection_id](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/utilities.py:103:0-115:5): Translates a collection ID into an index alias
- [indices](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/utilities.py:118:0-132:5): Gets a comma-separated string of index names

- **query.py**: Contains functions for building and manipulating queries
- [apply_free_text_filter_shared](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/database_logic_helpers.py:51:0-74:16): Applies a free text filter to a search
Expand All @@ -20,16 +23,39 @@ The database package is organized into three main modules:
- **mapping.py**: Contains functions for working with mappings
- [get_queryables_mapping_shared](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/database_logic_helpers.py:156:0-185:27): Retrieves mapping of Queryables for search

- **document.py**: Contains functions for working with documents
- [mk_item_id](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/utilities.py:140:0-150:5): Creates a document ID for an Item
- [mk_actions](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/utilities.py:153:0-175:5): Creates bulk actions for indexing items

- **utils.py**: Contains utility functions for database operations
- [validate_refresh](cci:1://file:///home/computer/Code/stac-fastapi-elasticsearch-opensearch/stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/utilities.py:41:0-78:5): Validates the refresh parameter value

## Usage

Import the necessary components from the database package:

```python
from stac_fastapi.sfeos_helpers.database import (
# Index operations
create_index_templates_shared,
delete_item_index_shared,
index_alias_by_collection_id,
index_by_collection_id,
indices,

# Query operations
apply_free_text_filter_shared,
apply_intersects_filter_shared,
populate_sort_shared,

# Mapping operations
get_queryables_mapping_shared,
)

# Document operations
mk_item_id,
mk_actions,

# Utility functions
validate_refresh,
)
```
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
1. Index management functions for creating and deleting indices
2. Query building functions for constructing search queries
3. Mapping functions for working with Elasticsearch/OpenSearch mappings
4. Document operations for working with documents
5. Utility functions for database operations

The database package is organized as follows:
- index.py: Index management functions
- query.py: Query building functions
- mapping.py: Mapping functions
- document.py: Document operations
- utils.py: Utility functions

When adding new functionality to this package, consider:
1. Will this code be used by both Elasticsearch and OpenSearch implementations?
Expand All @@ -24,19 +28,38 @@
"""

# Re-export all functions for backward compatibility
from .index import create_index_templates_shared, delete_item_index_shared
from .document import mk_actions, mk_item_id
from .index import (
create_index_templates_shared,
delete_item_index_shared,
index_alias_by_collection_id,
index_by_collection_id,
indices,
)
from .mapping import get_queryables_mapping_shared
from .query import (
apply_free_text_filter_shared,
apply_intersects_filter_shared,
populate_sort_shared,
)
from .utils import validate_refresh

__all__ = [
# Index operations
"create_index_templates_shared",
"delete_item_index_shared",
"index_alias_by_collection_id",
"index_by_collection_id",
"indices",
# Query operations
"apply_free_text_filter_shared",
"apply_intersects_filter_shared",
"populate_sort_shared",
# Mapping operations
"get_queryables_mapping_shared",
# Document operations
"mk_item_id",
"mk_actions",
# Utility functions
"validate_refresh",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""Document operations for Elasticsearch/OpenSearch.

This module provides functions for working with documents in Elasticsearch/OpenSearch,
including document ID generation and bulk action creation.
"""

from typing import Any, Dict, List

from stac_fastapi.sfeos_helpers.database.index import index_alias_by_collection_id
from stac_fastapi.types.stac import Item


def mk_item_id(item_id: str, collection_id: str) -> str:
"""Create the document id for an Item in Elasticsearch.

Args:
item_id (str): The id of the Item.
collection_id (str): The id of the Collection that the Item belongs to.

Returns:
str: The document id for the Item, combining the Item id and the Collection id, separated by a `|` character.
"""
return f"{item_id}|{collection_id}"


def mk_actions(collection_id: str, processed_items: List[Item]) -> List[Dict[str, Any]]:
"""Create Elasticsearch bulk actions for a list of processed items.

Args:
collection_id (str): The identifier for the collection the items belong to.
processed_items (List[Item]): The list of processed items to be bulk indexed.

Returns:
List[Dict[str, Union[str, Dict]]]: The list of bulk actions to be executed,
each action being a dictionary with the following keys:
- `_index`: the index to store the document in.
- `_id`: the document's identifier.
- `_source`: the source of the document.
"""
index_alias = index_alias_by_collection_id(collection_id)
return [
{
"_index": index_alias,
"_id": mk_item_id(item["id"], item["collection"]),
"_source": item,
}
for item in processed_items
]
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,67 @@
This module provides functions for creating and managing indices in Elasticsearch/OpenSearch.
"""

from typing import Any
from functools import lru_cache
from typing import Any, List, Optional

from stac_fastapi.sfeos_helpers.mappings import (
_ES_INDEX_NAME_UNSUPPORTED_CHARS_TABLE,
COLLECTIONS_INDEX,
ES_COLLECTIONS_MAPPINGS,
ES_ITEMS_MAPPINGS,
ES_ITEMS_SETTINGS,
ITEM_INDICES,
ITEMS_INDEX_PREFIX,
)
from stac_fastapi.sfeos_helpers.utilities import index_alias_by_collection_id


@lru_cache(256)
def index_by_collection_id(collection_id: str) -> str:
"""
Translate a collection id into an Elasticsearch index name.

Args:
collection_id (str): The collection id to translate into an index name.

Returns:
str: The index name derived from the collection id.
"""
cleaned = collection_id.translate(_ES_INDEX_NAME_UNSUPPORTED_CHARS_TABLE)
return (
f"{ITEMS_INDEX_PREFIX}{cleaned.lower()}_{collection_id.encode('utf-8').hex()}"
)


@lru_cache(256)
def index_alias_by_collection_id(collection_id: str) -> str:
"""
Translate a collection id into an Elasticsearch index alias.

Args:
collection_id (str): The collection id to translate into an index alias.

Returns:
str: The index alias derived from the collection id.
"""
cleaned = collection_id.translate(_ES_INDEX_NAME_UNSUPPORTED_CHARS_TABLE)
return f"{ITEMS_INDEX_PREFIX}{cleaned}"


def indices(collection_ids: Optional[List[str]]) -> str:
"""
Get a comma-separated string of index names for a given list of collection ids.

Args:
collection_ids: A list of collection ids.

Returns:
A string of comma-separated index names. If `collection_ids` is empty, returns the default indices.
"""
return (
",".join(map(index_alias_by_collection_id, collection_ids))
if collection_ids
else ITEM_INDICES
)


async def create_index_templates_shared(settings: Any) -> None:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Utility functions for database operations in Elasticsearch/OpenSearch.

This module provides utility functions for working with database operations
in Elasticsearch/OpenSearch, such as parameter validation.
"""

import logging
from typing import Union

from stac_fastapi.core.utilities import get_bool_env


def validate_refresh(value: Union[str, bool]) -> str:
"""
Validate the `refresh` parameter value.

Args:
value (Union[str, bool]): The `refresh` parameter value, which can be a string or a boolean.

Returns:
str: The validated value of the `refresh` parameter, which can be "true", "false", or "wait_for".
"""
logger = logging.getLogger(__name__)

# Handle boolean-like values using get_bool_env
if isinstance(value, bool) or value in {
"true",
"false",
"1",
"0",
"yes",
"no",
"y",
"n",
}:
is_true = get_bool_env("DATABASE_REFRESH", default=value)
return "true" if is_true else "false"

# Normalize to lowercase for case-insensitivity
value = value.lower()

# Handle "wait_for" explicitly
if value == "wait_for":
return "wait_for"

# Log a warning for invalid values and default to "false"
logger.warning(
f"Invalid value for `refresh`: '{value}'. Expected 'true', 'false', or 'wait_for'. Defaulting to 'false'."
)
return "false"
Loading