How to use Flasgger with Flask applications using Blueprints?

12,365

Solution 1

Now there is an example of blueprint app in https://github.com/rochacbruno/flasgger/blob/master/examples/example_blueprint.py

"""
A test to ensure routes from Blueprints are swagged as expected.
"""
from flask import Blueprint, Flask, jsonify

from flasgger import Swagger
from flasgger.utils import swag_from

app = Flask(__name__)

example_blueprint = Blueprint("example_blueprint", __name__)


@example_blueprint.route('/usernames/<username>', methods=['GET', 'POST'])
@swag_from('username_specs.yml', methods=['GET'])
@swag_from('username_specs.yml', methods=['POST'])
def usernames(username):
    return jsonify({'username': username})


@example_blueprint.route('/usernames2/<username>', methods=['GET', 'POST'])
def usernames2(username):
    """
    This is the summary defined in yaml file
    First line is the summary
    All following lines until the hyphens is added to description
    the format of the first lines until 3 hyphens will be not yaml compliant
    but everything below the 3 hyphens should be.
    ---
    tags:
      - users
    parameters:
      - in: path
        name: username
        type: string
        required: true
    responses:
      200:
        description: A single user item
        schema:
          id: rec_username
          properties:
            username:
              type: string
              description: The name of the user
              default: 'steve-harris'
    """
    return jsonify({'username': username})


app.register_blueprint(example_blueprint)

swag = Swagger(app)

if __name__ == "__main__":
    app.run(debug=True)

Solution 2

You just need to add your blueprint's name when you reference endpoint. Blueprints create namespaces. Example below. And useful tip: use app.logger.info(url_for('hello1')) for debugging problems with endpoint - it shows very useful error messages like this Could not build url for endpoint 'hello1'. Did you mean 'api_bp.hello1' instead?.

from flask import Flask, Blueprint, url_for
from flask_restful import Api, Resource
from flasgger import Swagger, swag_from

app = Flask(__name__)
api_blueprint = Blueprint('api_bp', __name__)
api = Api(api_blueprint)


class Hello(Resource):

    @swag_from('hello1.yml', endpoint='api_bp.hello1')
    @swag_from('hello2.yml', endpoint='api_bp.hello2')
    def get(self, user=''):
        name = user or 'stranger'
        resp = {'message': 'Hello %s!' % name}
        return resp


api.add_resource(Hello, '/hello', endpoint='hello1')
api.add_resource(Hello, '/hello/<string:user>', endpoint='hello2')

app.register_blueprint(api_blueprint)
swagger = Swagger(app)

app.run(debug=True)


Share:
12,365

Related videos on Youtube

Naymesh Mistry
Author by

Naymesh Mistry

Engineering and integrating Java enterprise software since 2005.

Updated on September 14, 2022

Comments

  • Naymesh Mistry
    Naymesh Mistry over 1 year

    I am adding Swagger UI to my Python Flask application using Flasgger. Most common examples on the Internet are for the basic Flask style using @app.route:

    from flasgger.utils import swag_from
    
    @app.route('/api/<string:username>')
    @swag_from('path/to/external_file.yml')
    def get(username):
        return jsonify({'username': username})
    

    That works.

    In my application however, I am not using @app.route decorators to define the endpoints. I am using flask Blueprints. Like following:

    from flask import Flask, Blueprint
    from flask_restful import Api, Resource
    from flasgger.utils import swag_from
    ...
    
    class TestResourceClass(Resource):
    
          @swag_from('docs_test_get.yml', endpoint='test')   
          def get() :
             print "This is the get method for GET /1.0/myapi/test endpoint"
    
    app = Flask(__name__)
    my_api_blueprint = Blueprint('my_api', __name__)
    my_api = Api(my_api_blueprint)
    
    app.register_blueprint(my_api_blueprint, url_prefix='/1.0/myapi/')
    
    my_api.add_resource(TestResourceClass, '/test/'
                            endpoint='test',
                            methods=['GET', 'POST', 'PUT', 'PATCH', 'DELETE'])
    ....
    

    As seen above, I used @swag_from decorator on the TestResourceClass.get() method which is bound to the GET method endpoint. I also have the endpoint=test matching in the two places.

    But I am not getting anything on the Swagger UI, it is all blank. The docs_test_get.yml file does contain the valid yaml markup to define the swagger spec.

    What am I missing? How can I get Flasgger Swagger UI working with Flask Blueprint based setup?

  • Naymesh Mistry
    Naymesh Mistry about 7 years
    I tested that file path is not an issue in swag_from when it is used in non blueprint style api definitions.
  • diplosaurus
    diplosaurus over 4 years
    Thank you, this is completely unclear from the flasgger docs and examples.