Skip to content

Commit

Permalink
Merge pull request #163 from developmentseed/feat/enable-transactionn…
Browse files Browse the repository at this point in the history
…-extensions

feat (stac): enable transaction extensions
  • Loading branch information
vincentsarago authored Nov 27, 2023
2 parents ee7834a + 02351ac commit 80a7255
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 32 deletions.
6 changes: 6 additions & 0 deletions docker-compose.custom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ services:
# https://github.com/developmentseed/eoAPI/issues/16
# - TITILER_ENDPOINT=raster
- TITILER_ENDPOINT=http://127.0.0.1:8082
# PgSTAC extensions
# - EOAPI_STAC_EXTENSIONS=["filter", "query", "sort", "fields", "pagination", "context", "transaction"]
# - EOAPI_STAC_CORS_METHODS='GET,POST,PUT,OPTIONS'
depends_on:
- database
- raster
Expand Down Expand Up @@ -171,6 +174,9 @@ services:
# https://github.com/developmentseed/eoAPI/issues/16
# - TITILER_ENDPOINT=raster
- TITILER_ENDPOINT=http://127.0.0.1:8082
# PgSTAC extensions
# - EOAPI_STAC_EXTENSIONS=["filter", "query", "sort", "fields", "pagination", "context", "transaction"]
# - EOAPI_STAC_CORS_METHODS='GET,POST,PUT,OPTIONS'
depends_on:
- database
- raster-uvicorn
Expand Down
20 changes: 15 additions & 5 deletions runtime/eoapi/stac/eoapi/stac/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
from contextlib import asynccontextmanager

from eoapi.stac.config import ApiSettings, TilesApiSettings
from eoapi.stac.config import extensions as PgStacExtensions
from eoapi.stac.config import get_request_model as GETModel
from eoapi.stac.config import post_request_model as POSTModel
from eoapi.stac.extension import TiTilerExtension
from eoapi.stac.extension import extensions_map as PgStacExtensions
from fastapi import FastAPI
from fastapi.responses import ORJSONResponse
from stac_fastapi.api.app import StacApi
from stac_fastapi.api.models import create_get_request_model, create_post_request_model
from stac_fastapi.pgstac.config import Settings
from stac_fastapi.pgstac.core import CoreCrudClient
from stac_fastapi.pgstac.db import close_db_connection, connect_to_db
from stac_fastapi.pgstac.types.search import PgstacSearch
from starlette.middleware.cors import CORSMiddleware
from starlette.requests import Request
from starlette.responses import HTMLResponse
Expand Down Expand Up @@ -43,12 +43,22 @@ async def lifespan(app: FastAPI):
await close_db_connection(app)


if enabled_extensions := api_settings.extensions:
extensions = [
PgStacExtensions[extension_name] for extension_name in enabled_extensions
]
else:
extensions = list(PgStacExtensions.values())

POSTModel = create_post_request_model(extensions, base_model=PgstacSearch)
GETModel = create_get_request_model(extensions)

api = StacApi(
app=FastAPI(title=api_settings.name, lifespan=lifespan),
title=api_settings.name,
description=api_settings.name,
settings=settings,
extensions=PgStacExtensions,
extensions=extensions,
client=CoreCrudClient(post_request_model=POSTModel),
search_get_request_model=GETModel,
search_post_request_model=POSTModel,
Expand All @@ -63,7 +73,7 @@ async def lifespan(app: FastAPI):
CORSMiddleware,
allow_origins=api_settings.cors_origins,
allow_credentials=True,
allow_methods=["GET", "POST", "OPTIONS"],
allow_methods=api_settings.cors_methods,
allow_headers=["*"],
)

Expand Down
42 changes: 16 additions & 26 deletions runtime/eoapi/stac/eoapi/stac/config.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
"""API settings."""

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

import pydantic
from stac_fastapi.api.models import create_get_request_model, create_post_request_model
from stac_fastapi.extensions.core import (
ContextExtension,
FieldsExtension,
FilterExtension,
QueryExtension,
SortExtension,
TokenPaginationExtension,
)
from stac_fastapi.pgstac.extensions.filter import FiltersClient
from stac_fastapi.pgstac.types.search import PgstacSearch


class _ApiSettings(pydantic.BaseSettings):
"""API settings"""

name: str = "eoAPI-stac"
cors_origins: str = "*"
cors_methods: str = "GET,POST,OPTIONS"
cachecontrol: str = "public, max-age=3600"
debug: bool = False

extensions: List[str] = [
"filter",
"query",
"sort",
"fields",
"pagination",
"context",
]

@pydantic.validator("cors_origins")
def parse_cors_origin(cls, v):
"""Parse CORS origins."""
return [origin.strip() for origin in v.split(",")]

@pydantic.validator("cors_methods")
def parse_cors_methods(cls, v):
"""Parse CORS methods."""
return [method.strip() for method in v.split(",")]

class Config:
"""model config"""

Expand Down Expand Up @@ -69,17 +73,3 @@ def TilesApiSettings() -> _TilesApiSettings:
"""
return _TilesApiSettings()


extensions = [
FilterExtension(
client=FiltersClient(),
),
QueryExtension(),
SortExtension(),
FieldsExtension(),
TokenPaginationExtension(),
ContextExtension(),
]
post_request_model = create_post_request_model(extensions, base_model=PgstacSearch)
get_request_model = create_get_request_model(extensions)
46 changes: 45 additions & 1 deletion runtime/eoapi/stac/eoapi/stac/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,58 @@
from urllib.parse import urlencode

import attr
import pydantic
from fastapi import APIRouter, FastAPI, HTTPException, Path, Query
from fastapi.responses import RedirectResponse
from fastapi.responses import ORJSONResponse, RedirectResponse
from stac_fastapi.extensions.core import (
ContextExtension,
FieldsExtension,
FilterExtension,
QueryExtension,
SortExtension,
TokenPaginationExtension,
TransactionExtension,
)
from stac_fastapi.extensions.third_party import BulkTransactionExtension
from stac_fastapi.pgstac.extensions.filter import FiltersClient
from stac_fastapi.pgstac.transactions import BulkTransactionsClient, TransactionsClient
from stac_fastapi.types.extension import ApiExtension
from starlette.requests import Request

router = APIRouter()


class TransactionSettings(pydantic.BaseSettings):
"""Simple API settings from stac-fastapi-pgstac Transaction Client.
ref: https://github.com/stac-utils/stac-fastapi/blob/09dac221d86fe70035aa6cddbc9a3f0de304aff5/stac_fastapi/types/stac_fastapi/types/config.py#L7-L37
"""

enable_response_models: bool = False

class Config:
"""Model config (https://pydantic-docs.helpmanual.io/usage/model_config/)."""

extra = "allow"
env_file = ".env"


extensions_map = {
"query": QueryExtension(),
"sort": SortExtension(),
"fields": FieldsExtension(),
"pagination": TokenPaginationExtension(),
"context": ContextExtension(),
"filter": FilterExtension(client=FiltersClient()),
"transaction": TransactionExtension(
client=TransactionsClient(),
settings=TransactionSettings(),
response_class=ORJSONResponse,
),
"bulk_transactions": BulkTransactionExtension(client=BulkTransactionsClient()),
}


@attr.s
class TiTilerExtension(ApiExtension):
"""TiTiler extension."""
Expand Down

0 comments on commit 80a7255

Please sign in to comment.