How to create REST API using Flask

Flask is a microframework for python which can be used for developing web applications. In this article, we will see how to create RESTful APIs in Flask using Flask-RESTful.

image

Installation

Before setting up the project, we create a virutal environment to keep our installation of python packages isolated from other projects.

To set up a virtual environment, we install virtualenv

sudo pip install virtualenv

Then we create a virtual environment named venv and activate it

virtualenv venv
source venv/bin/activate

After that we install Flask and Flast-RESTful in these virtual environments

pip install Flask
pip install flask-restful

Models

We create a note model with note title, description, created_at date, created_by and priority fields with id as primary key. We will use SQLite as the database for this application.

from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime

DB_URI = 'sqlite:///./main.db'
Base = declarative_base()

class Note(Base):
    __tablename__ = 'notes'

    id = Column(Integer, primary_key=True)
    title = Column(String(80))
    description = Column(String(80))
    create_at = Column(String(80))
    create_by = Column(String(80))
    priority = Column(Integer)

if __name__ == "__main__":
    from sqlalchemy import create_engine

    engine = create_engine(DB_URI)
    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)

Resources

Resources are building blocks of Flask-RESTful. Resource class is used to map HTTP methods to objects. We create a resource.py file where we first define NoteResource class

from models import Note
from db import session
from datetime import datetime
from flask.ext.restful import reqparse
from flask.ext.restful import abort
from flask.ext.restful import Resource
from flask.ext.restful import fields
from flask.ext.restful import marshal_with

note_fields = {
    'id': fields.Integer,
    'title': fields.String,
    'description': fields.String,
    'create_at': fields.String,
    'create_by': fields.String,
    'priority': fields.Integer
}

parser = reqparse.RequestParser()
parser.add_argument('title')
parser.add_argument('description')
parser.add_argument('create_at')
parser.add_argument('create_by')
parser.add_argument('priority')


class NoteResource(Resource):
    @marshal_with(note_fields)
    def get(self, id):
        note = session.query(Note).filter(Note.id == id).first()
        if not note:
            abort(404, message="Note {} doesn't exist".format(id))
        return note

    def delete(self, id):
        note = session.query(Note).filter(Note.id == id).first()
        if not note:
            abort(404, message="Note {} doesn't exist".format(id))
        session.delete(note)
        session.commit()
        return {}, 204

    @marshal_with(note_fields)
    def put(self, id):
        parsed_args = parser.parse_args()
        note = session.query(Note).filter(Note.id == id).first()
        note.title = parsed_args['title']
        note.description = parsed_args['description']
        note.create_at = parsed_args['create_at']
        note.create_by = parsed_args['create_by']
        note.priority = parsed_args['priority']
        session.add(note)
        session.commit()
        return note, 201

reqparse is Flaks-RESTful request parsing interface used for providing access to variables of flask.request objects.

marshall_with decorator takes data objects from API and applies field filtering.

We add one more resource for all Note elements

class NoteListResource(Resource):
    @marshal_with(note_fields)
    def get(self):
        notes = session.query(Note).all()
        return notes

    @marshal_with(note_fields)
    def post(self):
        parsed_args = parser.parse_args()
        note = Note(title=parsed_args['title'], description=parsed_args['description'],
                    create_at=parsed_args['create_at'], create_by=parsed_args['create_by'],
                    priority=parsed_args['priority'] )
        session.add(note)
        session.commit()
        return note, 201

We create another file api.py to add these resources to our API

from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
from models import Note
from resources import *

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

## Setup the API resource routing

api.add_resource(NoteListResource, '/notes/', endpoint='notes')
api.add_resource(NoteResource, '/notes/<string:id>', endpoint='note')


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

Starting Flask server and send requests

To run flask web server

python api.py

API can be tested using curl or browser addons like Postman for chrome and httprequester for Firefox.
To get a list of all notes, send a GET request to following URL

http://127.0.0.1:5000/notes/

To add a new note, send a POST request to the same url with data in following format in body part of the request.

  {
    "create_at": "2017-08-17 00:00", 
    "create_by": "v", 
    "description": "sample notes from api", 
    "priority": 1, 
    "title": "sample note from api"
}

Implemenation and codebase for above example is available here. To set up the project, clone the repository, install requirements in virtual environment and start the server.

Comments