How to create REST API using Flask
Tags: rest, api, flask, python
Published: 2018-10-01 14:22:43

---
title: How to create REST API using Flask
published: true
description: Comprehensive How to create REST API using Flask
tags: rest, api, flask, python
---

[Flask](http://flask.pocoo.org/) is a microframework for [python](https://www.python.org/) which can be used for developing web applications. In this article, we will see how to create RESTful APIs in Flask using [Flask-RESTful](https://flask-restful.readthedocs.io/en/latest/).

![Alt text of image](https://blog.apcelent.com/images/rest_api_flask.png)

## 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

```python
sudo pip install virtualenv
```
Then we create a virtual environment named venv and activate it

```python
virtualenv venv
source venv/bin/activate
```

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

```python
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.

```python
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.

```python
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

```python
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

```python
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
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.

```python
{
    "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](https://github.com/codecraf8/rest-api-python-flask). 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](https://blog.apcelent.com/create-rest-api-using-flask.html).