Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix content-type of /api response #287

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
### Fixed

* Links stored with Collections and Items (e.g. license links) are now returned with those STAC objects ([#282](https://github.com/stac-utils/stac-fastapi/pull/282))
* Content-type response headers for the /api endpoint now reflect those expected in the STAC api spec ([#287](https://github.com/stac-utils/stac-fastapi/pull/287))

## [2.2.0]

Expand Down
7 changes: 5 additions & 2 deletions stac_fastapi/api/stac_fastapi/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
SearchGetRequest,
_create_request_model,
)
from stac_fastapi.api.openapi import update_openapi
from stac_fastapi.api.routes import create_async_endpoint, create_sync_endpoint

# TODO: make this module not depend on `stac_fastapi.extensions`
Expand Down Expand Up @@ -64,8 +65,10 @@ class StacApi:
)
app: FastAPI = attr.ib(
default=attr.Factory(
lambda self: FastAPI(openapi_url=self.settings.openapi_url), takes_self=True
)
lambda self: FastAPI(openapi_url=self.settings.openapi_url),
takes_self=True,
),
converter=update_openapi,
)
router: APIRouter = attr.ib(default=attr.Factory(APIRouter))
title: str = attr.ib(default="stac-fastapi")
Expand Down
34 changes: 34 additions & 0 deletions stac_fastapi/api/stac_fastapi/api/openapi.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
"""openapi."""
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
from starlette.requests import Request
from starlette.responses import JSONResponse

from stac_fastapi.api.config import ApiExtensions
from stac_fastapi.types.config import ApiSettings


class VndOaiResponse(JSONResponse):
"""JSON with custom, vendor content-type."""

media_type = "application/vnd.oai.openapi+json;version=3.0"


def update_openapi(app: FastAPI) -> FastAPI:
"""Update OpenAPI response content-type.

This function modifies the openapi route to comply with the STAC API spec's
required content-type response header
"""
urls = (server_data.get("url") for server_data in app.servers)
server_urls = {url for url in urls if url}

async def openapi(req: Request) -> JSONResponse:
root_path = req.scope.get("root_path", "").rstrip("/")
if root_path not in server_urls:
if root_path and app.root_path_in_servers:
app.servers.insert(0, {"url": root_path})
server_urls.add(root_path)
return VndOaiResponse(app.openapi())

# Remove the default openapi route
app.router.routes = list(
filter(lambda r: r.path != app.openapi_url, app.router.routes)
)
# Add the updated openapi route
app.add_route(app.openapi_url, openapi, include_in_schema=False)
return app


# TODO: Remove or fix, this is currently unused
# and calls a missing method on ApiSettings
def config_openapi(app: FastAPI, settings: ApiSettings):
Expand Down
9 changes: 9 additions & 0 deletions stac_fastapi/pgstac/tests/api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@
]


@pytest.mark.asyncio
async def test_api_headers(app_client):
resp = await app_client.get("/api")
assert (
resp.headers["content-type"] == "application/vnd.oai.openapi+json;version=3.0"
)
assert resp.status_code == 200


@pytest.mark.asyncio
async def test_core_router(api_client):
core_routes = set(STAC_CORE_ROUTES)
Expand Down
8 changes: 8 additions & 0 deletions stac_fastapi/sqlalchemy/tests/api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
]


def test_api_headers(app_client):
resp = app_client.get("/api")
assert (
resp.headers["content-type"] == "application/vnd.oai.openapi+json;version=3.0"
)
assert resp.status_code == 200


def test_core_router(api_client):
core_routes = set(STAC_CORE_ROUTES)
api_routes = set(
Expand Down