Skip to content

Commit 80a7255

Browse files
Merge pull request #163 from developmentseed/feat/enable-transactionn-extensions
feat (stac): enable transaction extensions
2 parents ee7834a + 02351ac commit 80a7255

File tree

4 files changed

+82
-32
lines changed

4 files changed

+82
-32
lines changed

docker-compose.custom.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ services:
4646
# https://github.com/developmentseed/eoAPI/issues/16
4747
# - TITILER_ENDPOINT=raster
4848
- TITILER_ENDPOINT=http://127.0.0.1:8082
49+
# PgSTAC extensions
50+
# - EOAPI_STAC_EXTENSIONS=["filter", "query", "sort", "fields", "pagination", "context", "transaction"]
51+
# - EOAPI_STAC_CORS_METHODS='GET,POST,PUT,OPTIONS'
4952
depends_on:
5053
- database
5154
- raster
@@ -171,6 +174,9 @@ services:
171174
# https://github.com/developmentseed/eoAPI/issues/16
172175
# - TITILER_ENDPOINT=raster
173176
- TITILER_ENDPOINT=http://127.0.0.1:8082
177+
# PgSTAC extensions
178+
# - EOAPI_STAC_EXTENSIONS=["filter", "query", "sort", "fields", "pagination", "context", "transaction"]
179+
# - EOAPI_STAC_CORS_METHODS='GET,POST,PUT,OPTIONS'
174180
depends_on:
175181
- database
176182
- raster-uvicorn

runtime/eoapi/stac/eoapi/stac/app.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
from contextlib import asynccontextmanager
44

55
from eoapi.stac.config import ApiSettings, TilesApiSettings
6-
from eoapi.stac.config import extensions as PgStacExtensions
7-
from eoapi.stac.config import get_request_model as GETModel
8-
from eoapi.stac.config import post_request_model as POSTModel
96
from eoapi.stac.extension import TiTilerExtension
7+
from eoapi.stac.extension import extensions_map as PgStacExtensions
108
from fastapi import FastAPI
119
from fastapi.responses import ORJSONResponse
1210
from stac_fastapi.api.app import StacApi
11+
from stac_fastapi.api.models import create_get_request_model, create_post_request_model
1312
from stac_fastapi.pgstac.config import Settings
1413
from stac_fastapi.pgstac.core import CoreCrudClient
1514
from stac_fastapi.pgstac.db import close_db_connection, connect_to_db
15+
from stac_fastapi.pgstac.types.search import PgstacSearch
1616
from starlette.middleware.cors import CORSMiddleware
1717
from starlette.requests import Request
1818
from starlette.responses import HTMLResponse
@@ -43,12 +43,22 @@ async def lifespan(app: FastAPI):
4343
await close_db_connection(app)
4444

4545

46+
if enabled_extensions := api_settings.extensions:
47+
extensions = [
48+
PgStacExtensions[extension_name] for extension_name in enabled_extensions
49+
]
50+
else:
51+
extensions = list(PgStacExtensions.values())
52+
53+
POSTModel = create_post_request_model(extensions, base_model=PgstacSearch)
54+
GETModel = create_get_request_model(extensions)
55+
4656
api = StacApi(
4757
app=FastAPI(title=api_settings.name, lifespan=lifespan),
4858
title=api_settings.name,
4959
description=api_settings.name,
5060
settings=settings,
51-
extensions=PgStacExtensions,
61+
extensions=extensions,
5262
client=CoreCrudClient(post_request_model=POSTModel),
5363
search_get_request_model=GETModel,
5464
search_post_request_model=POSTModel,
@@ -63,7 +73,7 @@ async def lifespan(app: FastAPI):
6373
CORSMiddleware,
6474
allow_origins=api_settings.cors_origins,
6575
allow_credentials=True,
66-
allow_methods=["GET", "POST", "OPTIONS"],
76+
allow_methods=api_settings.cors_methods,
6777
allow_headers=["*"],
6878
)
6979

runtime/eoapi/stac/eoapi/stac/config.py

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,39 @@
11
"""API settings."""
22

33
from functools import lru_cache
4-
from typing import Optional
4+
from typing import List, Optional
55

66
import pydantic
7-
from stac_fastapi.api.models import create_get_request_model, create_post_request_model
8-
from stac_fastapi.extensions.core import (
9-
ContextExtension,
10-
FieldsExtension,
11-
FilterExtension,
12-
QueryExtension,
13-
SortExtension,
14-
TokenPaginationExtension,
15-
)
16-
from stac_fastapi.pgstac.extensions.filter import FiltersClient
17-
from stac_fastapi.pgstac.types.search import PgstacSearch
187

198

209
class _ApiSettings(pydantic.BaseSettings):
2110
"""API settings"""
2211

2312
name: str = "eoAPI-stac"
2413
cors_origins: str = "*"
14+
cors_methods: str = "GET,POST,OPTIONS"
2515
cachecontrol: str = "public, max-age=3600"
2616
debug: bool = False
2717

18+
extensions: List[str] = [
19+
"filter",
20+
"query",
21+
"sort",
22+
"fields",
23+
"pagination",
24+
"context",
25+
]
26+
2827
@pydantic.validator("cors_origins")
2928
def parse_cors_origin(cls, v):
3029
"""Parse CORS origins."""
3130
return [origin.strip() for origin in v.split(",")]
3231

32+
@pydantic.validator("cors_methods")
33+
def parse_cors_methods(cls, v):
34+
"""Parse CORS methods."""
35+
return [method.strip() for method in v.split(",")]
36+
3337
class Config:
3438
"""model config"""
3539

@@ -69,17 +73,3 @@ def TilesApiSettings() -> _TilesApiSettings:
6973
7074
"""
7175
return _TilesApiSettings()
72-
73-
74-
extensions = [
75-
FilterExtension(
76-
client=FiltersClient(),
77-
),
78-
QueryExtension(),
79-
SortExtension(),
80-
FieldsExtension(),
81-
TokenPaginationExtension(),
82-
ContextExtension(),
83-
]
84-
post_request_model = create_post_request_model(extensions, base_model=PgstacSearch)
85-
get_request_model = create_get_request_model(extensions)

runtime/eoapi/stac/eoapi/stac/extension.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,58 @@
44
from urllib.parse import urlencode
55

66
import attr
7+
import pydantic
78
from fastapi import APIRouter, FastAPI, HTTPException, Path, Query
8-
from fastapi.responses import RedirectResponse
9+
from fastapi.responses import ORJSONResponse, RedirectResponse
10+
from stac_fastapi.extensions.core import (
11+
ContextExtension,
12+
FieldsExtension,
13+
FilterExtension,
14+
QueryExtension,
15+
SortExtension,
16+
TokenPaginationExtension,
17+
TransactionExtension,
18+
)
19+
from stac_fastapi.extensions.third_party import BulkTransactionExtension
20+
from stac_fastapi.pgstac.extensions.filter import FiltersClient
21+
from stac_fastapi.pgstac.transactions import BulkTransactionsClient, TransactionsClient
922
from stac_fastapi.types.extension import ApiExtension
1023
from starlette.requests import Request
1124

1225
router = APIRouter()
1326

1427

28+
class TransactionSettings(pydantic.BaseSettings):
29+
"""Simple API settings from stac-fastapi-pgstac Transaction Client.
30+
31+
ref: https://github.com/stac-utils/stac-fastapi/blob/09dac221d86fe70035aa6cddbc9a3f0de304aff5/stac_fastapi/types/stac_fastapi/types/config.py#L7-L37
32+
"""
33+
34+
enable_response_models: bool = False
35+
36+
class Config:
37+
"""Model config (https://pydantic-docs.helpmanual.io/usage/model_config/)."""
38+
39+
extra = "allow"
40+
env_file = ".env"
41+
42+
43+
extensions_map = {
44+
"query": QueryExtension(),
45+
"sort": SortExtension(),
46+
"fields": FieldsExtension(),
47+
"pagination": TokenPaginationExtension(),
48+
"context": ContextExtension(),
49+
"filter": FilterExtension(client=FiltersClient()),
50+
"transaction": TransactionExtension(
51+
client=TransactionsClient(),
52+
settings=TransactionSettings(),
53+
response_class=ORJSONResponse,
54+
),
55+
"bulk_transactions": BulkTransactionExtension(client=BulkTransactionsClient()),
56+
}
57+
58+
1559
@attr.s
1660
class TiTilerExtension(ApiExtension):
1761
"""TiTiler extension."""

0 commit comments

Comments
 (0)