问题描述
我们有一个大型 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()