flask_restplus:无法让flask_swagger_ui 与命名空间一起工作

问题描述

我们有一个大型 flask_restplus 应用程序,该应用程序已经使用了一年左右。我们现在想使用 flask_swagger_ui 在此应用程序中工作,为部分应用程序提供一些静态生成的 swagger 文档。

我们基于 flask_restplus 的应用程序已经在使用命名空间,但我发现的 flask_swagger_ui 文档似乎表明我们必须通过其 get_swaggerui_blueprint 方法使用蓝图才能提供服务这招摇。但是,当我们这样做时,flask_restplus 应用程序无法识别与此蓝图关联的 URL。我们想知道这是否可能是由于同一应用程序中命名空间和蓝图之间的某种不需要的交互......或者可能只是因为我们做错了什么......?

这是我认为是我们代码的相关片段......

app = flask.Flask(__name__)
api = flask_restplus.Api(
  app,version='1.0',title='Test Application',description='Test Application',doc='/docs/'
)

ns     = api.namespace('server',description='Main server',path='/server')
utilns = api.namespace('util',description='Util',path='/util')

SWAGGER_URL = '/swagger'
API_URL = 'http://petstore.swagger.io/v2/swagger.json' # just for testing

swaggerui_blueprint = get_swaggerui_blueprint(
    SWAGGER_URL,API_URL,config={
        'app_name': "Test application"
    },)
app.register_blueprint(swaggerui_blueprint)

# Set up endpoints under the namespaces defined above,# and do some more initialization.

app.run()

然而,如果我们尝试像这样访问我们的应用程序,http://our.domain.name:PORT/swagger/dist,它会失败如下...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 FINAL//EN">
<title>405 Method Not Available</title>
<h1>Method Not Allowed</h1>
<p>This method is not allowed for the requested URL.</p>

如果我们去掉“dist”,我们会得到同样的错误,如下所示: http://our.domain.name:PORT/swagger

如果我们引用静态 swagger.json 文件而不是 petshop URL,这也会失败。

所有其他命名空间定义的端点都可以正常工作。

谁能看到我们做错了什么?

非常感谢您。

解决方法

我偶然发现了解决方案。在 flask_restplus 中,任何蓝图和 @app.route 定义都必须出现在 flask_restplus.Api 实例化之前。我在任何文档中都找不到这个,我是从一个讨论中得到的,这个讨论涉及一个遇到并最终解决这个问题的人。因此,这确实是 flask_restplus 中蓝图和命名空间之间的一种奇怪且看似未记录的交互。

此外,我发现 url_prefix=SWAGGER_URL 需要与蓝图变量本身一起传递给 app.register_blueprint

一旦我开始执行以下操作,我的 swagger 查询就开始起作用了:

app = flask.Flask(__name__)

# Any @app.route and blueprint definitions must
# appear before the flask_restplus.Api
# instantiation.

SWAGGER_URL = '/swagger'
# Use the following API_URL just for testing ...
API_URL = 'http://petstore.swagger.io/v2/swagger.json'
swaggerui_blueprint = get_swaggerui_blueprint(
    SWAGGER_URL,API_URL,config={
        'app_name': "Test application"
    },)
app.register_blueprint(
    swaggerui_blueprint,url_prefix=SWAGGER_URL
)

# OK. Now we can instantiate flask_restplus.API

api = flask_restplus.Api(
    app,version='1.0',title='Test Application',description='Test Application',doc='/docs/'
)

ns     = api.namespace(
             'server',description='Main server',path='/server'
         )
utilns = api.namespace(
             'util',description='Util',path='/util'
         )

# Set up endpoints under the namespaces defined above,# and do some more initialization. And then ...

app.run()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...