Elasticsearch and Opensearch backends for the stac-fastapi project.
Featuring stac-fastapi.core for simplifying the creation and maintenance of custom STAC api backends.
Online Documentation: https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch
Source Code: https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
- Our Api core library can be used to create custom backends. See stac-fastapi-mongo for a working example.
- Reach out on our Gitter channel or feel free to add to our Discussions page here on github.
- There is Postman documentation here for examples on how to run some of the API routes locally - after starting the elasticsearch backend via the compose.yml file.
- The
/examplesfolder shows an example of running stac-fastapi-elasticsearch from PyPI in docker without needing any code from the repository. There is also a Postman collection here that you can load into Postman for testing the API routes.
The enable_direct_response option is provided by the stac-fastapi core library (introduced in stac-fastapi 5.2.0) and is available in this project starting from v4.0.0.
You can now control this setting via the ENABLE_DIRECT_RESPONSE environment variable.
When enabled (ENABLE_DIRECT_RESPONSE=true), endpoints return Starlette Response objects directly, bypassing FastAPI's default serialization for improved performance. However, all FastAPI dependencies (including authentication, custom status codes, and validation) are disabled for all routes.
This mode is best suited for public or read-only APIs where authentication and custom logic are not required. Default is false for safety.
See: issue #347
# For versions 4.0.0a1 and newer (PEP 625 compliant naming): pip install stac-fastapi-elasticsearch # Elasticsearch backend pip install stac-fastapi-opensearch # Opensearch backend pip install stac-fastapi-core # Core library # For versions 4.0.0a0 and older: pip install stac-fastapi.elasticsearch # Elasticsearch backend pip install stac-fastapi.opensearch # Opensearch backend pip install stac-fastapi.core # Core libraryImportant Note: Starting with version 4.0.0a1, package names have changed from using periods (e.g.,
stac-fastapi.core) to using hyphens (e.g.,stac-fastapi-core) to comply with PEP 625. The internal package structure uses underscores, but users should install with hyphens as shown above. Please update your requirements files accordingly.
We provide ready-to-use Docker images through GitHub Container Registry (ElasticSearch and OpenSearch backends). You can easily pull and run these images:
# For Elasticsearch backend docker pull ghcr.io/stac-utils/stac-fastapi-es:latest # For OpenSearch backend docker pull ghcr.io/stac-utils/stac-fastapi-os:latestYou need to ensure Docker Compose or Podman Compose installed and running on your machine. In the following command instead of docker compose you can use podman-compose as well.
docker compose up elasticsearch app-elasticsearchBy default, Docker Compose uses Elasticsearch 8.x and OpenSearch 2.11.1. If you wish to use a different version, put the following in a file named .env in the same directory you run Docker Compose from:
ELASTICSEARCH_VERSION=8.11.0 OPENSEARCH_VERSION=2.11.1 ENABLE_DIRECT_RESPONSE=falseThe most recent Elasticsearch 7.x versions should also work. See the opensearch-py docs for compatibility information.
You can customize additional settings in your .env file:
| Variable | Description | Default | Required |
|---|---|---|---|
ES_HOST | Hostname for external Elasticsearch/OpenSearch. | localhost | Optional |
ES_PORT | Port for Elasticsearch/OpenSearch. | 9200 (ES) / 9202 (OS) | Optional |
ES_USE_SSL | Use SSL for connecting to Elasticsearch/OpenSearch. | false | Optional |
ES_VERIFY_CERTS | Verify SSL certificates when connecting. | false | Optional |
STAC_FASTAPI_TITLE | Title of the API in the documentation. | stac-fastapi-elasticsearch or stac-fastapi-opensearch | Optional |
STAC_FASTAPI_DESCRIPTION | Description of the API in the documentation. | N/A | Optional |
STAC_FASTAPI_VERSION | API version. | 2.1 | Optional |
APP_HOST | Server bind address. | 0.0.0.0 | Optional |
APP_PORT | Server port. | 8080 | Optional |
ENVIRONMENT | Runtime environment. | local | Optional |
WEB_CONCURRENCY | Number of worker processes. | 10 | Optional |
RELOAD | Enable auto-reload for development. | true | Optional |
STAC_FASTAPI_RATE_LIMIT | API rate limit per client. | 200/minute | Optional |
BACKEND | Tests-related variable | elasticsearch or opensearch based on the backend | Optional |
ELASTICSEARCH_VERSION | Version of Elasticsearch to use. | 8.11.0 | Optional |
ENABLE_DIRECT_RESPONSE | Enable direct response for maximum performance (disables all FastAPI dependencies, including authentication, custom status codes, and validation) | false | Optional |
OPENSEARCH_VERSION | OpenSearch version | 2.11.1 | Optional |
RAISE_ON_BULK_ERROR | Controls whether bulk insert operations raise exceptions on errors. If set to true, the operation will stop and raise an exception when an error occurs. If set to false, errors will be logged, and the operation will continue. Note: STAC Item and ItemCollection validation errors will always raise, regardless of this flag. | false | Optional |
Note
The variables ES_HOST, ES_PORT, ES_USE_SSL, and ES_VERIFY_CERTS apply to both Elasticsearch and OpenSearch backends, so there is no need to rename the key names to OS_ even if you're using OpenSearch.
To create a new Collection:
curl -X "POST" "http://localhost:8080/collections" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "id": "my_collection" }'Note: this "Collections Transaction" behavior is not part of the STAC API, but may be soon.
By default the API title and description are set to stac-fastapi-<backend>. Change the API title and description from the default by setting the STAC_FASTAPI_TITLE and STAC_FASTAPI_DESCRIPTION environment variables, respectively.
By default the API will read from and write to the collections and items_<collection name> indices. To change the API collections index and the items index prefix, change the STAC_COLLECTIONS_INDEX and STAC_ITEMS_INDEX_PREFIX environment variables.
The application root path is left as the base url by default. If deploying to AWS Lambda with a Gateway API, you will need to define the app root path to be the same as the Gateway API stage name where you will deploy the API. The app root path can be defined with the STAC_FASTAPI_ROOT_PATH environment variable (/v1, for example)
The collections route handles optional limit and token parameters. The links field that is returned from the /collections route contains a next link with the token that can be used to get the next page of results.
curl -X "GET" "http://localhost:8080/collections?limit=1&token=example_token"Usage: data_loader.py [OPTIONS] Load STAC items into the database. Options: --base-url TEXT Base URL of the STAC API [required] --collection-id TEXT ID of the collection to which items are added --use-bulk Use bulk insert method for items --data-dir PATH Directory containing collection.json and feature collection file --help Show this message and exit.python3 data_loader.py --base-url http://localhost:8080Mappings apply to search index, not source. The mappings are stored in index templates on application startup. These templates will be used implicitly when creating new Collection and Item indices.
This section covers how to create a snapshot repository and then create and restore snapshots with this.
Create a snapshot repository. This puts the files in the elasticsearch/snapshots in this git repo clone, as the elasticsearch.yml and compose files create a mapping from that directory to /usr/share/elasticsearch/snapshots within the Elasticsearch container and grant permissions on using it.
curl -X "PUT" "http://localhost:9200/_snapshot/my_fs_backup" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "type": "fs", "settings": { "location": "/usr/share/elasticsearch/snapshots/my_fs_backup" } }'The next step is to create a snapshot of one or more indices into this snapshot repository. This command creates a snapshot named my_snapshot_2 and waits for the action to be completed before returning. This can also be done asynchronously, and queried for status. The indices parameter determines which indices are snapshotted, and can include wildcards.
curl -X "PUT" "http://localhost:9200/_snapshot/my_fs_backup/my_snapshot_2?wait_for_completion=true" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "metadata": { "taken_because": "dump of all items", "taken_by": "pvarner" }, "include_global_state": false, "ignore_unavailable": false, "indices": "items_my-collection" }'To see the status of this snapshot:
curl http://localhost:9200/_snapshot/my_fs_backup/my_snapshot_2To see all the snapshots:
curl http://localhost:9200/_snapshot/my_fs_backup/_allTo restore a snapshot, run something similar to the following. This specific command will restore any indices that match items_* and rename them so that the new index name will be suffixed with -copy.
curl -X "POST" "http://localhost:9200/_snapshot/my_fs_backup/my_snapshot_2/_restore?wait_for_completion=true" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "include_aliases": false, "include_global_state": false, "ignore_unavailable": true, "rename_replacement": "items_$1-copy", "indices": "items_*", "rename_pattern": "items_(.+)" }'Now the item documents have been restored in to the new index (e.g., my-collection-copy), but the value of the collection field in those documents is still the original value of my-collection. To update these to match the new collection name, run the following Elasticsearch Update By Query command, substituting the old collection name into the term filter and the new collection name into the script parameter:
curl -X "POST" "http://localhost:9200/items_my-collection-copy/_update_by_query" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "query": { "match_all": {} }, "script": { "lang": "painless", "params": { "collection": "my-collection-copy" }, "source": "ctx._source.collection = params.collection" } }'Then, create a new collection through the api with the new name for each of the restored indices:
curl -X "POST" "http://localhost:8080/collections" \ -H 'Content-Type: application/json' \ -d $'{ "id": "my-collection-copy" }'Voila! You have a copy of the collection now that has a resource URI (/collections/my-collection-copy) and can be correctly queried by collection name.
This section covers how to reindex documents stored in Elasticsearch/OpenSearch. A reindex operation might be useful to apply changes to documents or to correct dynamically generated mappings.
The index templates will make sure that manually created indices will also have the correct mappings and settings.
In this example, we will make a copy of an existing Item index items_my-collection-lower_my-collection-hex-000001 but change the Item identifier to be lowercase.
curl -X "POST" "http://localhost:9200/_reindex" \ -H 'Content-Type: application/json' \ -d $'{ "source": { "index": "items_my-collection-lower_my-collection-hex-000001" }, "dest": { "index": "items_my-collection-lower_my-collection-hex-000002" }, "script": { "source": "ctx._source.id = ctx._source.id.toLowerCase()", "lang": "painless" } }'If we are happy with the data in the newly created index, we can move the alias items_my-collection to the new index items_my-collection-lower_my-collection-hex-000002.
curl -X "POST" "http://localhost:9200/_aliases" \ -h 'Content-Type: application/json' \ -d $'{ "actions": [ { "remove": { "index": "*", "alias": "items_my-collection" } }, { "add": { "index": "items_my-collection-lower_my-collection-hex-000002", "alias": "items_my-collection" } } ] }'The modified Items with lowercase identifiers will now be visible to users accessing my-collection in the STAC API.
Authentication is an optional feature that can be enabled through Route Dependencies examples can be found and a more detailed explanation in examples/auth.
Aggregation of points and geometries, as well as frequency distribution aggregation of any other property including dates is supported in stac-fatsapi-elasticsearch-opensearch. Aggregations can be defined at the root Catalog level (/aggregations) and at the Collection level (/<collection_id>/aggregations). Details for supported aggregations can be found in the aggregation docs
Rate limiting is an optional security feature that controls API request frequency on a remote address basis. It's enabled by setting the STAC_FASTAPI_RATE_LIMIT environment variable, e.g., 500/minute. This limits each client to 500 requests per minute, helping prevent abuse and maintain API stability. Implementation examples are available in the examples/rate_limit directory.
