Before diving into Automation of Swagger API Doc with Flask restful, let’s clear the air and talk about some of the terms that we are going to use in the blog extensively.
What is Flask Restful?
Flask-RESTful is an extension for Flask that adds support for quickly building REST APIs. Flask-RESTful encourages best practices with minimal setup. If you are familiar with Flask, Flask-RESTful should be easy to pick up.
What is API Documentation?
API documentation is a technical instruction about how to effectively use an API. It’s a concise reference manual containing all the information required to work with the API like the URI, request parameters, functions, classes, return types, arguments and more, supported by tutorials and examples. API Documentation has traditionally been done using regular content creation and maintenance tools and text editors.
Something like this
What is Swagger API Doc?
Swagger allows you to describe the structure of your APIs so that machines can read them. By reading the API structure, Swagger can automatically build beautiful and interactive API documentation and also generates client libraries for the API in many languages. Swagger does this by asking your API to return a YAML or JSON that contains a detailed description of your entire API. This file is essentially a resource listing of your API which adheres to OpenAPI Specification.
And it automatically generates the API Doc like this using the swagger.json that we provide.
Cool Right!!
What if I tell you that you can generate your Swagger API Doc without even manually creating swagger.json or it will be created automatically! Wouldn’t that be nice?
Let’s start with writing a small micro-server using Flask that will have one GET API and to do that let’s install some libraries for it.
Prerequisites for Swagger API Doc
Install Flask Restful, Flask APISpec
pip install -U flask-restful
pip install -U flask-apispec
The above commands will additionally install Flask, Webargs and Marshmallow libraries. Webargs and Marshmallow are great libraries when it comes to parse the HTTP request parameters and convert complex data types into python native types.
All set!
Implementation
Let’s create the basic flask restful GET API. NOTE: Whole source code of the blog is available on Github
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__) # Flask app instance initiated
api = Api(app) # Flask restful wraps Flask app around it.# Restful way of creating APIs through Flask Restful
class AwesomeAPI(Resource):
def get(self):
'''
Get method represents a GET API method
'''
return {'message': 'My First Awesome API'}
api.add_resource(AwesomeAPI, '/awesome')
if __name__ == '__main__':
app.run(debug=True)
We have created an API /awesome that is having a GET Method and will respond with a static message as ‘My First Awesome API’. Let’s add marshalling around the response message to control what data you are actually rendering in your response.
from flask import Flask
from flask_restful import Resource, Api, fields, marshal_with
app = Flask(__name__) # Flask app instance initiated
api = Api(app) # Flask restful wraps Flask app around it.
awesome_response_schema = dict(
message=fields.String(default='')
) # Restful way of creating APIs through Flask Restful
class AwesomeAPI(Resource):
@marshal_with(awesome_response_schema) # marshalling
def get(self):
'''
Get method represents a GET API method
'''
return {'message': 'My First Awesome API'}
api.add_resource(AwesomeAPI, '/awesome')
if __name__ == '__main__':
app.run(debug=True)
If you run the program and hit the /awesome API then it will return something like this:
{
"message": "My First Awesome API"
}
Let’s create a Swagger API Doc of the above API. First, we have to add one more base class MethodResource of Flask APISpec in the class-based Resource and have to import the marshal_with from flask-apispec.
from flask_apispec import marshal_with from flask_apispec.views import MethodResource from marshmallow import Schema, fields class AwesomeResponseSchema(Schema): message = fields.Str(default='Success') class AwesomeAPI(MethodResource, Resource): @marshal_with(AwesomeResponseSchema) # marshalling with marshmallow library def get(self): ''' Get method represents a GET API method ''' return {'message': 'My First Awesome API'}
And just instantiate the flask-apispec with the Flask app.
from apispec import APISpec
from apispec.ext.marshmallow import MarshmallowPlugin
from flask_apispec.extension import FlaskApiSpec
app.config.update({
'APISPEC_SPEC': APISpec(
title='Awesome Project',
version='v1',
plugins=[MarshmallowPlugin()],
openapi_version='2.0.0'
),
'APISPEC_SWAGGER_URL': '/swagger/', # URI to access API Doc JSON
'APISPEC_SWAGGER_UI_URL': '/swagger-ui/' # URI to access UI of API Doc
})
docs = FlaskApiSpec(app)
docs.register(AwesomeAPI)
Now open the URL /swagger-ui cause we have defined the URL as swagger-ui. You can see the doc is very well generated with the API /awesome in it.
You can even test the API from the “Try It Out” section. In the above image, you can see it has automatically picked up the API URL response parameters, response content type. Now, let’s add some description and Title of the API.
@doc(description='My First GET Awesome API.', tags=['Awesome'])
@marshal_with(AwesomeResponseSchema) # marshalling with marshmallow library
def get(self):
'''
Get method represents a GET API method
'''
return {'message': 'My First Awesome API'}
You must have observed that there is no request parameter in the API. Let’s add another POST API with some request parameter.
from flask_apispec import marshal_with, doc, use_kwargs class AwesomeRequestSchema(Schema): api_type = fields.String(required=True, description="API type of awesome API") class AwesomeResponseSchema(Schema): message = fields.Str(default='Success') @doc(description='My First GET Awesome API.', tags=['Awesome']) @use_kwargs(AwesomeRequestSchema, location=('json')) @marshal_with(AwesomeResponseSchema) # marshalling def post(self): ''' Get method represents a GET API method ''' return {'message': 'My First Awesome API'}
Now POST method API doc is available on /swagger-ui with api_type as a request parameter.
So from here on, we don’t need to write anything explicitly for further APIs, flask-apispec will handle all the APIDoc internally using the configuration that we have implemented.
Conclusion
Flask APISpec is just a wrapper around Webargs and Marshmallow, that will help you to create Automated Swagger APIDocs without creating swagger.json manually. So that developers will put more efforts into building the APIs rather than documenting the APIs. For the whole source code, you can get it from the Github link here.
I hope, it has helped you. If you want to discuss anything or anything related to tech, you can contact me here or on the Contact page.
See you next time. Peace out ✌️