Skip to content

Instantly share code, notes, and snippets.

@vincentsarago
Created January 24, 2025 10:26
Show Gist options
  • Save vincentsarago/4ee0fdf471cf592a8ba642dcc72304d2 to your computer and use it in GitHub Desktop.
Save vincentsarago/4ee0fdf471cf592a8ba642dcc72304d2 to your computer and use it in GitHub Desktop.
Full stac-fastapi Application
import os
from fastapi.responses import ORJSONResponse
from stac_fastapi.api.app import StacApi
from stac_fastapi.api.models import (
EmptyRequest,
ItemCollectionUri,
create_get_request_model,
create_post_request_model,
create_request_model,
)
from stac_fastapi.api.openapi import update_openapi
from stac_fastapi.extensions.core import (
CollectionSearchFilterExtension,
ItemCollectionFilterExtension,
SearchFilterExtension,
FieldsExtension,
FreeTextExtension,
OffsetPaginationExtension,
SortExtension,
TokenPaginationExtension,
TransactionExtension,
CollectionSearchExtension,
)
from stac_fastapi.extensions.core.fields import FieldsConformanceClasses
from stac_fastapi.extensions.core.free_text import FreeTextConformanceClasses
from stac_fastapi.extensions.core.query import QueryConformanceClasses
from stac_fastapi.extensions.core.sort import SortConformanceClasses
from stac_fastapi.extensions.third_party import BulkTransactionExtension
from stac_fastapi.types.config import ApiSettings
from stac_fastapi.types.core import BaseCoreClient
settings = ApiSettings()
###############################################################################
# EXTENSIONS #
###############################################################################
# application extensions
application_extensions_map = {
"transaction": TransactionExtension(),
"bulk_transactions": BulkTransactionExtension(),
}
# search extensions
search_extensions_map = {
"query": QueryExtension(),
"sort": SortExtension(),
"fields": FieldsExtension(),
"filter": SearchFilterExtension(),
"pagination": TokenPaginationExtension(),
}
# collection_search extensions
cs_extensions_map = {
"query": QueryExtension(
conformance_classes=[QueryConformanceClasses.COLLECTIONS]
),
"sort": SortExtension(
conformance_classes=[SortConformanceClasses.COLLECTIONS]
),
"fields": FieldsExtension(
conformance_classes=[FieldsConformanceClasses.COLLECTIONS]
),
"filter": CollectionSearchFilterExtension(),
"free_text": FreeTextExtension(
conformance_classes=[FreeTextConformanceClasses.COLLECTIONS],
),
"pagination": OffsetPaginationExtension(),
}
# item_collection extensions
itm_col_extensions_map = {
"query": QueryExtension(
conformance_classes=[QueryConformanceClasses.ITEMS],
),
"sort": SortExtension(
conformance_classes=[SortConformanceClasses.ITEMS],
),
"fields": FieldsExtension(
conformance_classes=[FieldsConformanceClasses.ITEMS]
),
"filter": ItemCollectionFilterExtension(),
"pagination": TokenPaginationExtension(),
}
# List of all extensions
known_extensions = {
*application_extensions_map.keys(),
*search_extensions_map.keys(),
*cs_extensions_map.keys(),
*itm_col_extensions_map.keys(),
"collection_search",
}
# Env setting to limit enabled extensions
enabled_extensions = (
os.environ["ENABLED_EXTENSIONS"].split(",")
if "ENABLED_EXTENSIONS" in os.environ
else known_extensions
)
###############################################################################
# REQUEST MODELS #
###############################################################################
application_extensions = [
extension
for key, extension in application_extensions_map.items()
if key in enabled_extensions
]
# /search models
search_extensions = [
extension
for key, extension in search_extensions_map.items()
if key in enabled_extensions
]
post_request_model = create_post_request_model(search_extensions, base_model=PgstacSearch)
get_request_model = create_get_request_model(search_extensions)
application_extensions.extend(search_extensions)
# /collections/{collectionId}/items model
items_get_request_model = ItemCollectionUri
itm_col_extensions = [
extension
for key, extension in itm_col_extensions_map.items()
if key in enabled_extensions
]
if itm_col_extensions:
items_get_request_model = create_request_model(
model_name="ItemCollectionUri",
base_model=ItemCollectionUri,
extensions=itm_col_extensions,
request_type="GET",
)
application_extensions.extend(itm_col_extensions)
# /collections model
collections_get_request_model = EmptyRequest
if "collection_search" in enabled_extensions:
cs_extensions = [
extension
for key, extension in cs_extensions_map.items()
if key in enabled_extensions
]
collection_search_extension = CollectionSearchExtension.from_extensions(cs_extensions)
collections_get_request_model = collection_search_extension.GET
application_extensions.append(collection_search_extension)
###############################################################################
# FAKE CLIENT #
###############################################################################
class Client(BaseCoreClient):
def all_collections(self, *args, **kwargs):
raise NotImplementedError
def get_collection(self, *args, **kwargs):
raise NotImplementedError
def get_item(self, *args, **kwargs):
raise NotImplementedError
def get_search(self, *args, **kwargs):
raise NotImplementedError
def post_search(self, *args, **kwargs):
raise NotImplementedError
def item_collection(self, *args, **kwargs):
raise NotImplementedError
api = StacApi(
settings=settings,
extensions=application_extensions,
client=Client(),
response_class=ORJSONResponse,
items_get_request_model=items_get_request_model,
search_get_request_model=get_request_model,
search_post_request_model=post_request_model,
collections_get_request_model=collections_get_request_model,
)
app = api.app
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment