-
Notifications
You must be signed in to change notification settings - Fork 27
/
app.py
169 lines (143 loc) · 5.01 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
"""FastAPI application using PGStac.
Enables the extensions specified as a comma-delimited list in
the ENABLED_EXTENSIONS environment variable (e.g. `transactions,sort,query`).
If the variable is not set, enables all extensions.
"""
import os
from brotli_asgi import BrotliMiddleware
from fastapi.responses import ORJSONResponse
from stac_fastapi.api.app import StacApi
from stac_fastapi.api.middleware import CORSMiddleware, ProxyHeaderMiddleware
from stac_fastapi.api.models import (
EmptyRequest,
ItemCollectionUri,
create_get_request_model,
create_post_request_model,
create_request_model,
)
from stac_fastapi.extensions.core import (
FieldsExtension,
FilterExtension,
SortExtension,
TokenPaginationExtension,
TransactionExtension,
)
from stac_fastapi.extensions.core.collection_search import CollectionSearchExtension
from stac_fastapi.extensions.third_party import BulkTransactionExtension
from starlette.middleware import Middleware
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.extensions import QueryExtension
from stac_fastapi.pgstac.extensions.filter import FiltersClient
from stac_fastapi.pgstac.transactions import BulkTransactionsClient, TransactionsClient
from stac_fastapi.pgstac.types.search import PgstacSearch
settings = Settings()
extensions_map = {
"transaction": TransactionExtension(
client=TransactionsClient(),
settings=settings,
response_class=ORJSONResponse,
),
"query": QueryExtension(),
"sort": SortExtension(),
"fields": FieldsExtension(),
"pagination": TokenPaginationExtension(),
"filter": FilterExtension(client=FiltersClient()),
"bulk_transactions": BulkTransactionExtension(client=BulkTransactionsClient()),
}
# some extensions are supported in combination with the collection search extension
collection_extensions_map = {
"query": QueryExtension(),
"sort": SortExtension(),
"fields": FieldsExtension(),
"filter": FilterExtension(client=FiltersClient()),
}
enabled_extensions = (
os.environ["ENABLED_EXTENSIONS"].split(",")
if "ENABLED_EXTENSIONS" in os.environ
else list(extensions_map.keys()) + ["collection_search"]
)
extensions = [
extension for key, extension in extensions_map.items() if key in enabled_extensions
]
items_get_request_model = (
create_request_model(
model_name="ItemCollectionUri",
base_model=ItemCollectionUri,
mixins=[TokenPaginationExtension().GET],
request_type="GET",
)
if any(isinstance(ext, TokenPaginationExtension) for ext in extensions)
else ItemCollectionUri
)
collection_search_extension = (
CollectionSearchExtension.from_extensions(
[
extension
for key, extension in collection_extensions_map.items()
if key in enabled_extensions
]
)
if "collection_search" in enabled_extensions
else None
)
collections_get_request_model = (
collection_search_extension.GET if collection_search_extension else EmptyRequest
)
post_request_model = create_post_request_model(extensions, base_model=PgstacSearch)
get_request_model = create_get_request_model(extensions)
api = StacApi(
settings=settings,
extensions=extensions + [collection_search_extension]
if collection_search_extension
else extensions,
client=CoreCrudClient(post_request_model=post_request_model), # type: ignore
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,
middlewares=[
Middleware(BrotliMiddleware),
Middleware(ProxyHeaderMiddleware),
Middleware(
CORSMiddleware,
allow_origins=settings.cors_origins,
allow_methods=settings.cors_methods,
),
],
)
app = api.app
@app.on_event("startup")
async def startup_event():
"""Connect to database on startup."""
await connect_to_db(app)
@app.on_event("shutdown")
async def shutdown_event():
"""Close database connection."""
await close_db_connection(app)
def run():
"""Run app from command line using uvicorn if available."""
try:
import uvicorn
uvicorn.run(
"stac_fastapi.pgstac.app:app",
host=settings.app_host,
port=settings.app_port,
log_level="info",
reload=settings.reload,
root_path=os.getenv("UVICORN_ROOT_PATH", ""),
)
except ImportError as e:
raise RuntimeError("Uvicorn must be installed in order to use command") from e
if __name__ == "__main__":
run()
def create_handler(app):
"""Create a handler to use with AWS Lambda if mangum available."""
try:
from mangum import Mangum
return Mangum(app)
except ImportError:
return None
handler = create_handler(app)