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.
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:
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.
Hope the article was of help!
The article originally appeared on Apcelent Tech Blog.
Top comments (1)
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)