Skip to content

'/api' route does not handle 'Accept' header for OGC API Feautes - part 2 spec requirement. #281

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

Closed
NicolaiLolansen opened this issue Oct 29, 2021 · 2 comments
Assignees
Labels
spec Compliance with STAC/OGC specifications

Comments

@NicolaiLolansen
Copy link

'/api' route does not handle 'Accept' header for OGC API Feautes - part 2 spec requirement. Content-type of the route /api should be content-type: application/vnd.oai.openapi+json;version=3.0. Probably all that needs here is to instead of using JSONResponse, use something like:

class VndResponse(JSONResponse):
    media_type = application/vnd.oai.openapi+json;version=3.0

Recreate problem using teamengine:
http://cite.opengeospatial.org/teamengine/ ( or for local instances, a docker image is supplied here: https://cite.opengeospatial.org/teamengine/about/ogcapi-features-1.0/1.0/site/ see the docker section log in with ogctest:ogctest. If using docker you have to use the ip for localhost, use ipconfig or similar to find it)

Teamengine will check the OGC API implementation against spec, and notify you of any problems. Since Stac-Api is based on OGC API i would assume it to pass this check.

The teamengine test fails this task:

Test Name: api Definition Validation
Test Description: Implements A.2.3. API Definition Path {root}/api (link), Abstract Test 6 (Requirement /req/core/api-definition-success) | Details ↗Class Name:ApiDefinitionMethod Name:apiDefinitionValidationPath:org/opengis/cite/ogcapifeatures10/conformance/core/apidefinition/ApiDefinition
Test Result: FAILED

In laymans terms this test refers to https://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_api_definition_path_rootapi_link which states that api-definition-success (https://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_response_2)

should fulfill requirement 4 which states:

Requirement 4 /req/core/api-definition-success
A A GET request to the URI of an API definition linked from the landing page (link relations service-desc or service-doc) with an Accept header with the value of the link property type SHALL return a document consistent with the requested media type.

And right now the requested media-type is supposed to be content-type: application/vnd.oai.openapi+json;version=3.0 but is simply application/json and so the test fails.

I have tried looking into where to implement this, but i fail to see how exactly the /api route is handled, maybe it's something core to FastAPI itself.

@NicolaiLolansen
Copy link
Author

I have a work-around for this - in the sqlalchemy implementation.

What you can do is write an __attrs_pre_init__ function that overrides the FastAPI setup function with a reworked openapi function. It looks like this:

in app.py

    # Before initialization of StacAPI we change the setup method of FastAPI
    # to change the responsetype of openapi from JsonResponse to OAFeat compliant
    # VndResponse. Afaik this is the only way to do it.
    def __attrs_pre_init__(self):

        def setup(self) -> None:
            if self.openapi_url:
                urls = (server_data.get("url") for server_data in self.servers)
                server_urls = {url for url in urls if url}

                async def openapi(req: Request) -> VndResponse:
                    root_path = req.scope.get("root_path", "").rstrip("/")
                    if root_path not in server_urls:
                        if root_path and self.root_path_in_servers:
                            self.servers.insert(0, {"url": root_path})
                            server_urls.add(root_path)
                    # This is the response we have changed
                    return VndResponse(self.openapi())

                self.add_route(self.openapi_url, openapi, include_in_schema=True)

            if self.openapi_url and self.docs_url:

                async def swagger_ui_html(req: Request) -> HTMLResponse:
                    root_path = req.scope.get("root_path", "").rstrip("/")
                    openapi_url = root_path + self.openapi_url
                    oauth2_redirect_url = self.swagger_ui_oauth2_redirect_url
                    if oauth2_redirect_url:
                        oauth2_redirect_url = root_path + oauth2_redirect_url
                    return get_swagger_ui_html(
                        openapi_url=openapi_url,
                        title=self.title + " - Swagger UI",
                        oauth2_redirect_url=oauth2_redirect_url,
                        init_oauth=self.swagger_ui_init_oauth,
                    )

                self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False)

                if self.swagger_ui_oauth2_redirect_url:

                    async def swagger_ui_redirect(req: Request) -> HTMLResponse:
                        return get_swagger_ui_oauth2_redirect_html()

                    self.add_route(
                        self.swagger_ui_oauth2_redirect_url,
                        swagger_ui_redirect,
                        include_in_schema=False,
                    )

            if self.openapi_url and self.redoc_url:
                async def redoc_html(req: Request) -> HTMLResponse:
                    root_path = req.scope.get("root_path", "").rstrip("/")
                    openapi_url = root_path + self.openapi_url
                    return get_redoc_html(
                        openapi_url=openapi_url, title=self.title + " - ReDoc"
                    )

                self.add_route(self.redoc_url, redoc_html, include_in_schema=False)
        
        # override the setup function on the FastAPI class
        FastAPI.setup = setup

This seems kinda hacky, but not sure how else to do it.

The VndResponse looks like this:

class VndResponse(JSONResponse):
    media_type = "application/vnd.oai.openapi+json;version=3.0"

@NicolaiLolansen
Copy link
Author

Teamengine still seems somewhat unhappy still, i will look into it

@moradology moradology self-assigned this Nov 8, 2021
@moradology moradology added the spec Compliance with STAC/OGC specifications label Nov 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec Compliance with STAC/OGC specifications
Projects
None yet
Development

No branches or pull requests

2 participants