Flask RestPlus API

Flask-RESTPlus is an extension for Flask that adds support for quickly building REST APIs. Flask-RESTPlus encourages best practices with minimal setup. If you are familiar with Flask, Flask-RESTPlus should be easy to pick up. It provides a coherent collection of decorators and tools to describe your API and expose its documentation properly (using Swagger).

Installation

pip install flask-restplus

Create a simple get and post request

from flask import Flask 
from flask_restplus import Api, Resource, fields #pip install flask-restplus
from werkzeug.utils import cached_property #pip install Werkzeug==0.16.1

app = Flask(__name__)
api = Api(app)

user = api.model('User', {'username' : fields.String('Username.')})

users = []

@api.route('/user')
class User(Resource):
    def get(self):
        return users

    @api.expect(user)
    def post(self):
        users.append(api.payload)
        return {'result' : 'User added'}, 201 

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

As you can see from the above example we have imported the all the packages and then instantiated flask and flask API. Then we have declared our model, which will be the input and output format of our APIs. Then we have declared a simple list where we are going to store the values.

Next, we have defined the route that we are going to handle and in that route, we have declared a class named User. Inside this class we are going to write all our methods. First, we have created a get method that is going to return the complete list and then we have defined a post method that is going to add value to our dictionary.

Finally we have defined our main function and run our application. Now if you can use the route we have declared(http://127.0.0.1:5000/user) to perform the get and post operation. But for easyness Flask Restplus have integrated Swagger which will document all your API. so just go to http://127.0.0.1:5000 and under default section you will find the get and post request section.

How to add Id to our list

If you only want to add id then you can change the code like below.

from flask import Flask 
from flask_restplus import Api, Resource, fields #pip install flask-restplus
from werkzeug.utils import cached_property #pip install Werkzeug==0.16.1

app = Flask(__name__)
api = Api(app)

user = api.model('User', {'username' : fields.String('Username.')})

users = []

@api.route('/user')
class User(Resource):
    def get(self):
        return users

    @api.expect(user)
    def post(self):
        new_user = api.payload
        new_user['id'] = len(users)+1
        users.append(new_user)
        return {'result' : 'User added'}, 201 

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

As you can see the only changes we have made inside the post method, we have added another field with the user. Now refresh and perform post and get operation, you will see the id as output in get request.

Filtering the get request (Response Marshaling)

As you can see on the get request the ID have been returned, like that in real work there will be number of values we don’t want to send to filter them we can use a decorator name marshal_with like below.

from flask import Flask 
from flask_restplus import Api, Resource, fields #pip install flask-restplus
from werkzeug.utils import cached_property #pip install Werkzeug==0.16.1

app = Flask(__name__)
api = Api(app)

user = api.model('User', {'username' : fields.String('Username.')})

users = []

@api.route('/user')
class User(Resource):
    @api.marshal_with(user)
    def get(self):
        return users

    @api.expect(user)
    def post(self):
        new_user = api.payload
        new_user['id'] = len(users)+1
        users.append(new_user)
        return {'result' : 'User added'}, 201 

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

Adding another value to the model:

Suppose we want to add another value to our model so we can perform like below.

from flask import Flask 
from flask_restplus import Api, Resource, fields #pip install flask-restplus
from werkzeug.utils import cached_property #pip install Werkzeug==0.16.1

app = Flask(__name__)
api = Api(app)

user = api.model('User', {'username' : fields.String('Username.'), 'name' : fields.String('Name.')})

users = []

@api.route('/user')
class User(Resource):
    @api.marshal_with(user)
    def get(self):
        return users

    @api.expect(user)
    def post(self):
        new_user = api.payload
        new_user['id'] = len(users)+1
        users.append(new_user)
        return {'result' : 'User added'}, 201 

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

Envelope output with a key

If we want we can also envelop our output with any key by passing the keyword-argument in marshal_with.

from flask import Flask 
from flask_restplus import Api, Resource, fields #pip install flask-restplus
from werkzeug.utils import cached_property #pip install Werkzeug==0.16.1

app = Flask(__name__)
api = Api(app)

user = api.model('User', {'username' : fields.String('Username.'), 'name' : fields.String('Name.')})

users = []

@api.route('/user')
class User(Resource):
    @api.marshal_with(user, envelope='user_profile')
    def get(self):
        return users

    @api.expect(user)
    def post(self):
        new_user = api.payload
        new_user['id'] = len(users)+1
        users.append(new_user)
        return {'result' : 'User added'}, 201 

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

Here we are enveloping our output with the user_profile.

Working with Swagger UI:

If you dont want to use swagger then you can turn it off while instantiating the API.

api = Api(app, doc=False)

Enable JSON editor with swagger UI

app.config['SWAGGER_UI_JSONEDITOR'] = True

if you want to change to route of the Swagger Ui you can do that by:

from flask import Flask, Blueprint
from flask_restplus import Api, Resource, fields

app = Flask(__name__)
blueprint = Blueprint('api', __name__, url_prefix='/api')
api = Api(blueprint, doc='/documentation') #,doc=False

app.register_blueprint(blueprint)

Integrating Marshmallow with Flask-RestPlus

This is a stand-alone framework for Flask-RestPlus. It can speed up the development process of the API but it has also demerit that you can’t use some Awesome feature of Flask-RestPlus. Below is the same program converted to marshmallow.

from flask import Flask 
from flask_restplus import Api, Resource, fields 
from werkzeug.utils import cached_property 
from marshmallow import Schema, fields as ma_fields, post_load
app = Flask(__name__)
api = Api(app)


class UserDetails(object):
    def __init__(self,username, name):
        self.username = username
        self.name = name
    
    def __repr__(self):
        return 'username is {}. name is {}.'.format(self.username,self.name)


class UserSchema(Schema):
    username = ma_fields.String()
    name = ma_fields.String()

    @post_load
    def create_user(self,data, **kwargs):
        return UserDetails(**data)

user_model = api.model('User', {'username' : fields.String('Username.'), 'name' : fields.String('Name.')})

users = []

@api.route('/user')
class User(Resource):
    # @api.marshal_with(user, envelope='user_profile')
    def get(self):
        schema = UserSchema(many=True)
        return schema.dump(users)

    @api.expect(user_model)
    def post(self):
        schema = UserSchema()
        new_user = schema.load(api.payload)
        # print(new_user)
        # new_user['id'] = len(users)+1
        users.append(new_user)
        return {'result' : 'User added'}, 201 

if __name__ == '__main__':
    app.run(debug=True)
Copy link
Powered by Social Snap