We have a large flask_restplus
application that's been in service for a year or so. We now would like to use flask_swagger_ui
to work within this application to serve some statically generated swagger docs for part of the application.
Our flask_restplus
-based application is already using namespaces, but the flask_swagger_ui
docs that I have found seem to suggest that we have to use blueprints via its get_swaggerui_blueprint
method in order to serve this swagger. However, when we do this, the flask_restplus
application doesn't recognize the URL associated with this blueprint. We're wondering if perhaps this might be due to some sort of unwanted interaction between namespaces and blueprints within the same application ... or perhaps could it just be due to the fact that we're doing something incorrectly ... ???
Here is what I believe is the pertinent fragment of our code ...
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()
However, if we try to access our app like this, http://our.domain.name:PORT/swagger/dist
, it fails as follows ...
<!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>
We get the same error if we leave off "dist", as follows:
http://our.domain.name:PORT/swagger
.
This also fails if we refer to a static swagger.json
file instead of the petshop URL.
All the other namespace-defined endpoints work fine.
Can anyone see what we are doing incorrectly?
Thank you very much in advance.
I stumbled upon the solution. In flask_restplus
, any blueprint and @app.route
definitions must appear before the flask_restplus.Api
instantiation. I couldn't find this in any documentation, and I got it from a discussion that involved someone who had encountered and finally fixed this issue. So, this is indeed a weird and seemingly undocumented interaction between blueprints and namespaces in flask_restplus
.
Also, I discovered that url_prefix=SWAGGER_URL
needs to be passed to app.register_blueprint
along with the blueprint variable, itself.
Once I started doing the following, my swagger queries began to work:
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()