33import logging
44from contextlib import asynccontextmanager
55
6+ import attr
67import jinja2
78from eoapi .auth_utils import OpenIdConnectAuth , OpenIdConnectSettings
89from fastapi import FastAPI
910from fastapi .responses import ORJSONResponse
1011from stac_fastapi .api .app import StacApi
1112from stac_fastapi .api .models import (
13+ CollectionUri ,
14+ EmptyRequest ,
1215 ItemCollectionUri ,
13- create_get_request_model ,
16+ ItemUri ,
1417 create_post_request_model ,
1518 create_request_model ,
1619)
20+ from stac_fastapi .api .routes import create_async_endpoint
1721from stac_fastapi .extensions .core import (
1822 FieldsExtension ,
1923 FilterExtension ,
2327)
2428from stac_fastapi .extensions .third_party import BulkTransactionExtension
2529from stac_fastapi .pgstac .config import Settings
26- from stac_fastapi .pgstac .core import CoreCrudClient
2730from stac_fastapi .pgstac .db import close_db_connection , connect_to_db
2831from stac_fastapi .pgstac .extensions import QueryExtension
2932from stac_fastapi .pgstac .extensions .filter import FiltersClient
3033from stac_fastapi .pgstac .transactions import BulkTransactionsClient , TransactionsClient
3134from stac_fastapi .pgstac .types .search import PgstacSearch
35+ from stac_fastapi .types .search import BaseSearchGetRequest
36+ from stac_pydantic import api
37+ from stac_pydantic .shared import MimeTypes
3238from starlette .middleware import Middleware
3339from starlette .middleware .cors import CORSMiddleware
3440from starlette .requests import Request
3541from starlette .responses import HTMLResponse
3642from starlette .templating import Jinja2Templates
3743from starlette_cramjam .middleware import CompressionMiddleware
3844
45+ from .client import PgSTACClient
3946from .config import ApiSettings
40- from .extension import TiTilerExtension
47+ from .extension import HTMLorGeoJSONGetRequest , HTMLorJSONGetRequest , TiTilerExtension
4148from .logs import init_logging
4249
4350jinja2_env = jinja2 .Environment (
@@ -115,19 +122,121 @@ async def lifespan(app: FastAPI):
115122 )
116123
117124# Custom Models
118- items_get_model = ItemCollectionUri
119125if any (isinstance (ext , TokenPaginationExtension ) for ext in extensions ):
120126 items_get_model = create_request_model (
121127 model_name = "ItemCollectionUri" ,
122128 base_model = ItemCollectionUri ,
123- mixins = [TokenPaginationExtension ().GET ],
129+ mixins = [TokenPaginationExtension ().GET , HTMLorGeoJSONGetRequest ],
130+ request_type = "GET" ,
131+ )
132+ else :
133+ items_get_model = create_request_model (
134+ model_name = "ItemCollectionUri" ,
135+ base_model = ItemCollectionUri ,
136+ mixins = [HTMLorGeoJSONGetRequest ],
124137 request_type = "GET" ,
125138 )
126139
127- search_get_model = create_get_request_model (extensions )
140+ search_get_model = create_request_model (
141+ "SearchGetRequest" ,
142+ base_model = BaseSearchGetRequest ,
143+ extensions = extensions ,
144+ mixins = [HTMLorGeoJSONGetRequest ],
145+ request_type = "GET" ,
146+ )
128147search_post_model = create_post_request_model (extensions , base_model = PgstacSearch )
148+ collections_get_model = create_request_model (
149+ model_name = "CollectionsModel" ,
150+ base_model = EmptyRequest ,
151+ mixins = [HTMLorJSONGetRequest ],
152+ request_type = "GET" ,
153+ )
154+ collection_get_model = create_request_model (
155+ model_name = "CollectionUri" ,
156+ base_model = CollectionUri ,
157+ mixins = [HTMLorJSONGetRequest ],
158+ request_type = "GET" ,
159+ )
160+ item_get_model = create_request_model (
161+ model_name = "ItemUri" ,
162+ base_model = ItemUri ,
163+ mixins = [HTMLorGeoJSONGetRequest ],
164+ request_type = "GET" ,
165+ )
166+ conformance_get_model = create_request_model (
167+ model_name = "ConformanceModel" ,
168+ base_model = EmptyRequest ,
169+ mixins = [HTMLorJSONGetRequest ],
170+ request_type = "GET" ,
171+ )
172+ landing_get_model = create_request_model (
173+ model_name = "LandingModel" ,
174+ base_model = EmptyRequest ,
175+ mixins = [HTMLorJSONGetRequest ],
176+ request_type = "GET" ,
177+ )
178+
179+
180+ @attr .s
181+ class CustomStacApi (StacApi ):
182+ def register_landing_page (self ):
183+ """Register landing page (GET /).
184+
185+ Returns:
186+ None
187+ """
188+ self .router .add_api_route (
189+ name = "Landing Page" ,
190+ path = "/" ,
191+ response_model = (
192+ api .LandingPage if self .settings .enable_response_models else None
193+ ),
194+ responses = {
195+ 200 : {
196+ "content" : {
197+ MimeTypes .json .value : {},
198+ },
199+ "model" : api .LandingPage ,
200+ },
201+ },
202+ response_class = self .response_class ,
203+ response_model_exclude_unset = False ,
204+ response_model_exclude_none = True ,
205+ methods = ["GET" ],
206+ endpoint = create_async_endpoint (self .client .landing_page , landing_get_model ),
207+ )
208+
209+ def register_conformance_classes (self ):
210+ """Register conformance classes (GET /conformance).
211+
212+ Returns:
213+ None
214+ """
215+ self .router .add_api_route (
216+ name = "Conformance Classes" ,
217+ path = "/conformance" ,
218+ response_model = (
219+ api .Conformance if self .settings .enable_response_models else None
220+ ),
221+ responses = {
222+ 200 : {
223+ "content" : {
224+ MimeTypes .json .value : {},
225+ },
226+ "model" : api .Conformance ,
227+ },
228+ },
229+ response_class = self .response_class ,
230+ response_model_exclude_unset = True ,
231+ response_model_exclude_none = True ,
232+ methods = ["GET" ],
233+ endpoint = create_async_endpoint (
234+ self .client .conformance , conformance_get_model
235+ ),
236+ )
237+
129238
130- api = StacApi (
239+ stac_api = CustomStacApi ( # type: ignore
131240 app = FastAPI (
132241 title = api_settings .name ,
133242 lifespan = lifespan ,
@@ -143,14 +252,17 @@ async def lifespan(app: FastAPI):
143252 description = api_settings .name ,
144253 settings = settings ,
145254 extensions = extensions ,
146- client = CoreCrudClient (post_request_model = search_post_model ),
255+ client = PgSTACClient (post_request_model = search_post_model ), # type: ignore
147256 items_get_request_model = items_get_model ,
257+ item_get_request_model = item_get_model ,
258+ collections_get_request_model = collections_get_model ,
259+ collection_get_request_model = collection_get_model ,
148260 search_get_request_model = search_get_model ,
149261 search_post_request_model = search_post_model ,
150262 response_class = ORJSONResponse ,
151263 middlewares = middlewares ,
152264)
153- app = api .app
265+ app = stac_api .app
154266
155267
156268@app .get ("/index.html" , response_class = HTMLResponse )
0 commit comments