flask-restful-swagger-2 is a wrapper for flask-restful which enables swagger support according to the swagger 2.0 specification.
This project is based on flask-restful-swagger, but it only supported swagger 1.2.
Install:
pip install flask-restful-swagger-2
To use it, change your import from from flask_restful import Api
to from flask_restful_swagger_2 import Api
.
from flask import Flask
# Instead of using this: from flask_restful import Api
# Use this:
from flask_restful_swagger_2 import Api
app = Flask(__name__)
# Use the swagger Api class as you would use the flask restful class.
# It supports several (optional) parameters, these are the defaults:
api = Api(app, api_version='0.0', api_spec_url='/api/swagger')
The Api class supports the following parameters:
Parameter | Description |
---|---|
add_api_spec_resource |
Set to True to add an endpoint to serve the swagger specification (defaults to True ). |
api_version |
The API version string (defaults to '0.0'). Maps to the version field of the info object. |
api_spec_base |
Instead of specifying individual swagger fields, you can pass in a minimal schema object to use as a template. Note that parameters specified explicity will overwrite the values in this template. |
api_spec_url |
The URL path that serves the swagger specification document (defaults to /api/swagger ). The path is appended with .json and .html (i.e. /api/swagger.json and /api/swagger.html ). |
base_path |
The base path on which the API is served. Maps to the basePath field of the schema object. |
consumes |
A list of MIME types the API can consume. Maps to the consumes field of the schema object. |
contact |
The contact information for the API. Maps to the contact field of the info object. |
description |
A short description of the application. Maps to the description field of the info object. |
external_docs |
Additional external documentation. Maps to the externalDocs field of the schema object. |
host |
The host serving the API. Maps to the host field of the schema object. |
license |
The license information for the API. Maps to the license field of the info object. |
parameters |
The parameters that can be used across operations. Maps to the parameters field of the schema object. |
produces |
A list of MIME types the API can produce. Maps to the produces field of the schema object. |
responses |
The responses that can be used across operations. Maps to the responses field of the schema object. |
schemes |
The transfer protocol of the API. Maps the the schemes field of the schema object. |
security |
The security schemes for the API as a whole. Maps to the security field of the schema object. |
security_definitions |
The security definitions for the API. Maps to the securityDefinitions field of the schema object. |
tags |
A list of tags used by the specification with additional metadata. Maps to the tags field fo the schema object. |
terms |
The terms of service for the API. Maps to the termsOfService field of the info object. |
title |
The title of the application (defaults to the flask app module name). Maps to the title field of the info object. |
Decorate your API endpoints with @swagger.doc
. It takes a dictionary in the format of a swagger operation object.
class UserItemResource(Resource):
@swagger.doc({
'tags': ['user'],
'description': 'Returns a user',
'parameters': [
{
'name': 'user_id',
'description': 'User identifier',
'in': 'path',
'type': 'integer'
}
],
'responses': {
'200': {
'description': 'User',
'schema': UserModel,
'examples': {
'application/json': {
'id': 1,
'name': 'somebody'
}
}
}
}
})
def get(self, user_id):
# Do some processing
return UserModel(id=1, name='somebody'}), 200 # generates json response {"id": 1, "name": "somebody"}
Use add_resource as usual.
api.add_resource(UserItemResource, '/api/users/<int:user_id>')
If a resource function contains the special argument _parser
, any query
type parameters in the
documentation will be automatically added to a reqparse parser and assigned to the _parser
argument.
Create a model by inheriting from flask_restful_swagger_2.Schema
from flask_restful_swagger_2 import Schema
class EmailModel(Schema):
type = 'string'
format = 'email'
class KeysModel(Schema):
type = 'object'
properties = {
'name': {
'type': 'string'
}
}
class UserModel(Schema):
type = 'object'
properties = {
'id': {
'type': 'integer',
'format': 'int64',
},
'name': {
'type': 'string'
},
'mail': EmailModel,
'keys': KeysModel.array()
}
required = ['name']
You can build your models according to the swagger schema object specification
It is recommended that you always return a model in your views so that your code and documentation are in sync.
You can specify RequestParser object if you want to pass its arguments to spec. In such case, there is not need to define model manually
from flask_restful.reqparse import RequestParser
from flask_restful_swagger_2 import swagger, Resource
class GroupResource(Resource):
post_parser = RequestParser()
post_parser.add_argument('name', type=str, required=True)
post_parser.add_argument('id', type=int, help='Id of new group')
@swagger.doc({
'tags': ['groups'],
'description': 'Adds a group',
'reqparser': {'name': 'group parser',
'parser': post_parser},
'responses': {
'201': {
'description': 'Created group',
'examples': {
'application/json': {
'id': 1
}
}
}
}
})
def post(self):
...
Swagger schema (among other things):
{"GroupsModel": {
"properties": {
"id": {
"default": null,
"description": "Id of new group",
"name": "id",
"required": false,
"type": "integer"
},
"name": {
"default": null,
"description": null,
"name": "name",
"required": true,
"type": "string"
}
},
"type": "object"
}
In the example above, the view UserItemResource
is a subclass of Resource
, which is provided by flask_restful
. However,
flask_restful_swagger_2
provides a thin wrapper around Resource
to provide authentication. By using this, you can
not only prevent access to resources, but also hide the documentation depending on the provided api_key
.
Example:
# Import Api and Resource instead from flask_restful_swagger_2
from flask_restful_swagger_2 import Api, swagger, Resource
api = Api(app)
def auth(api_key, endpoint, method):
# Space for your fancy authentication. Return True if access is granted, otherwise False
# api_key is extracted from the url parameters (?api_key=foo)
# endpoint is the full swagger url (e.g. /some/{value}/endpoint)
# method is the HTTP method
return True
swagger.auth = auth
class MyView(Resource):
@swagger.doc({
# documentation...
})
def get(self):
return SomeModel(value=5)
api.add_resource(MyView, '/some/endpoint')
The get_swagger_doc
method of the Api instance returns the specification document object,
which may be useful for integration with other tools for generating formatted output or client code.
To use Flask Blueprints, create a function in your views module that creates the blueprint, registers the resources and returns it wrapped in an Api instance:
from flask import Blueprint, request
from flask_restful_swagger_2 import Api, swagger, Resource
class UserResource(Resource):
...
class UserItemResource(Resource):
...
def get_user_resources():
"""
Returns user resources.
:param app: The Flask instance
:return: User resources
"""
blueprint = Blueprint('user', __name__)
api = Api(blueprint, add_api_spec_resource=False)
api.add_resource(UserResource, '/api/users')
api.add_resource(UserItemResource, '/api/users/<int:user_id>')
return api
In your initialization module, collect the swagger document objects for each
set of resources, then use the get_swagger_blueprint
function to combine the
documents and specify the URL to serve them at (default is '/api/swagger').
Note that the get_swagger_blueprint
function accepts the same keyword parameters
as the Api
class to populate the fields of the combined swagger document.
Finally, register the swagger blueprint along with the blueprints for your
resources.
from flask_restful_swagger_2 import get_swagger_blueprint
...
# A list of swagger document objects
docs = []
# Get user resources
user_resources = get_user_resources()
# Retrieve and save the swagger document object (do this for each set of resources).
docs.append(user_resources.get_swagger_doc())
# Register the blueprint for user resources
app.register_blueprint(user_resources.blueprint)
# Prepare a blueprint to serve the combined list of swagger document objects and register it
app.register_blueprint(get_swagger_blueprint(docs, '/api/swagger', title='Example', api_version='1'))
Refer to the files in the example
folder for the complete code.
To run the example project in the example
folder:
pip install flask-restful-swagger-2
pip install flask-cors # needed to access spec from swagger-ui
python app.py
To run the example which uses Flask Blueprints:
python app_blueprint.py
The swagger spec will by default be at http://localhost:5000/api/swagger.json
. You can change the URL by passing
api_spec_url='/my/path'
to the Api
constructor. You can use swagger-ui
to explore your api. Try it online at http://petstore.swagger.io/
To run tests:
python setup.py test