DEV Community

Apcelent
Apcelent

Posted on

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.

Alt text of 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
Enter fullscreen mode Exit fullscreen mode

Then we create a virtual environment named venv and activate it

virtualenv venv
source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

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

pip install Flask
pip install flask-restful
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Starting Flask server and send requests

To run flask web server

python api.py
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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.

Hope the article was of help!

The article originally appeared on Apcelent Tech Blog.

Latest comments (1)

Collapse
 
vcavanna profile image
vcavanna

I've been working on implementing this same project: but I can't get it to work on Python 3. Something about the db package being used? These were the notes that I left for my Python 3 version:
1) flask.ext.restful needs to be replaced with flask_restful.
2) You still need to "pip install db"; this package isn't usable in python 3 (it uses prints without parentheses)
3) There's an issue with naming files 'resource.py' like the tutorial asks you to name one file; and in the reference later it's called 'resources.py' (which is what I eventually went with)