apiflask / apiflask

A lightweight Python web API framework.

Home Page:https://apiflask.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add support for adding decorators to the OpenAPI spec and documentation UI endpoints

tsokalski opened this issue · comments

As a user of the APIFlask framework, I would like the ability to apply a decorator to the endpoints used to serve the OpenAPI spec as well as the documentation UI, so that I can execute additional logic before returning back the OpenAPI spec or the documentation UI to a client.

The more specific use case I have for this is to apply some security checks to validate that the client trying to access the documentation is allowed to access the endpoints that serve it.

I have currently achieved this by doing the following, but it's rather ugly - I had to look into the code in APIFlask._register_openapi_blueprint and replicate some of its logic to rewrite the view functions, which Flask advises against doing:

def _add_authentication_to_docs(app: APIFlask) -> None:
    if app.spec_path:
        _rewrite_view_function(app, "spec")
    if app.docs_path:
        _rewrite_view_function(app, "docs")
        if app.docs_ui == "swagger-ui" and app.docs_oauth2_redirect_path:
            _rewrite_view_function(app, "swagger_ui_oauth_redirect")


def _rewrite_view_function(app: APIFlask, method_name: str) -> None:
    # Flask warns you not to do this, but we don't really have a choice...
    app.view_functions[f"openapi.{method_name}"] = authenticate_apidocs()(app.view_functions[f"openapi.{method_name}"])

APIFairy provides this functionality via the APIFAIRY_APISPEC_DECORATORS and APIFAIRY_UI_DECORATORS config variables, which is much more straightforward:

app.config["APIFAIRY_APISPEC_DECORATORS"] = [authenticate_apidocs()]
app.config["APIFAIRY_UI_DECORATORS"] = [authenticate_apidocs()]

I am hoping that this framework might consider adopting similar functionality.

If your program already has an authentication(such as HTTPBasicAuth),could you wanna reuse it?

i wanna support this feature by #508
have any ideas for improvements?

I’m currently traveling :) I’ll be home in a few days and can provide some feedback then.

Thanks for looking into this!

If your program already has an authentication(such as HTTPBasicAuth),could you wanna reuse it?

The app's authentication is all custom-written, so I think the flexibility of applying an arbitrary decorator would be helpful for our use case.

i wanna support this feature by #508 have any ideas for improvements?

I took a look at your changes, they look excellent. The only thing I could potentially see being slightly useful would be to add support for attaching a decorator to the Swagger UI OAuth redirect URL, since APIFlask wires in that route as well, but I have no personal use for it so I'm quite happy with the current proposed changeset.

Thanks again!

I took a look at your changes, they look excellent. The only thing I could potentially see being slightly useful would be to add support for attaching a decorator to the Swagger UI OAuth redirect URL, since APIFlask wires in that route as well, but I have no personal use for it so I'm quite happy with the current proposed changeset.

It seems to me that this router only server the redirect, so I can't think of any scenarios where I need to add it,could you give me some prompt of specific scenarios?

I want support it by SWAGGER_UI_OAUTH_REDIRECT_DECORATORS

https://github.com/apiflask/apiflask/pull/508/files#diff-55322925cb31d71d2b3b276750c74f7761be9abf49ba290f80b955ceaeec927bR22

What do you think of this feature implementations? @greyli

此问题已在 代码厨房 上被提及。那里可能有相关详细信息:

https://codekitchen.community/t/topic/1124/1