Build massively scalable RESTFul API with Falcon and PyPy

Namaste everyone. If you build a RESTFul API for some purpose, what technology stack you use in python and why?. I may receive the following answers from you.

1)  I use Flask with Flask-RESTFul

2)  I use (Django + Tastypie) or (Django + REST Framework)

Both options are not suitable for me. Because there is a very good light-weight API framework available in python called Falcon. I always keep my project and REST API loosely coupled. It means my REST API knows little about the Django or Flask project that is being implemented. Creating cloud API’s with low-level web framework than a bulky wrapped one always speeds up my API.

What is Falcon?

As per Falcon website Falcon official website

“Falcon is a minimalist WSGI library for building speedy web APIs and app backends. We like to think of Falcon as the Dieter Rams of web frameworks.”

“When it comes to building HTTP APIs, other frameworks weigh you down with tons of dependencies and unnecessary abstractions. Falcon cuts to the chase with a clean design that embraces HTTP and the REST architectural style.”

If you want to hit bare metal for creating API use Falcon. You can build easy to develop, easy to serve and easy to scale API with Falcon. Just use it for speed.

What is PyPy?

“If you want your code to run faster, you should probably just use PyPy.” — Guido van Rossum

PyPy is a fast, compliant alternative implementation of the Python language

So PyPy is a JIT implementation for your Python code. It is a separate interpreter that can be used as a normal interpreter in a virtual environment to power our projects. In most of the cases, there are no issues with PyPy.

Let’s start building a simple todo REST API

Note: Project source is available at

Falcon and PyPy are our ingredients to build scalable, faster REST API. We start with a virtual environment that runs PyPy with falcon installed using pip. Then we use rethinkDB as the resource provider for our API. Our todo app does three main things.

  1. Create a note (PUT)
  2. Fetch a note by ID (GET)
  3. Fetch all notes (GET)
  4. PUT & DELETE are obvious

Install RethinkDB on Ubuntu14.04 in this way.

$ source /etc/lsb-release && echo "deb $DISTRIB_CODENAME main" | sudo tee /etc/apt/sources.list.d/rethinkdb.list
$ wget -qO- | sudo apt-key add -
$ sudo apt-get update && sudo apt-get install rethinkdb
$ sudo cp /etc/rethinkdb/default.conf.sample /etc/rethinkdb/instances.d/instance1.conf
$ sudo /etc/init.d/rethinkdb restart

Create virtualenv for the project and install required libraries. Download PyPy from this URL .PyPy Download. After downloading, extract files and install pip if required.

$ sudo apt-get install python-pip
$ virtualenv -p pypy-2.6.1-linux64/bin/pypy falconenv
$ source falconenv/bin/activate
$ pip install rethinkdb falcon gunicorn

Now we are ready with our stack. PyPy as python interpreter, Falcon as web framework to build the RESTful API. Gunicorn is a WSGI server that serves our API. Now, let us prepare our rethinkDB database client for fetching and inserting resources. Let me give the filename “”
import os
import rethinkdb as r
from rethinkdb.errors import RqlRuntimeError, RqlDriverError

RDB_HOST = 'localhost'
RDB_PORT = 28015

# Datbase is todo and table is notes
PROJECT_DB = 'todo'

# Set up db connection client
db_connection = r.connect(RDB_HOST,RDB_PORT)

# Function is for cross-checking database and table exists 
def dbSetup():
        print 'Database setup completed.'
    except RqlRuntimeError:
            print 'Table creation completed'
            print 'Table already exists.Nothing to do'


Don’t worry, if you do not know about rethinkDB. Just go to this link and see quickstart. RethinkDB Python. We just prepared a db connection client and created database, table. Now the actual thing comes. Falcon allows us to define a resource class which we can route to a URL. In that resource class we can have four REST methods

  1. on_get
  2. on_post
  3. on_put
  4. on_delete

So we are going to implement first two functions in this article. Create a file called
import falcon
import json

from db_client import *

class NoteResource:
    def on_get(self, req, resp):
        """Handles GET requests"""
        # Return note for particular ID
        if req.get_param("id"):
            result = {'note': r.db(PROJECT_DB).table(PROJECT_TABLE). get(req.get_param("id")).run(db_connection)}
            note_cursor = r.db(PROJECT_DB).table(PROJECT_TABLE).run(db_connection)
            result = {'notes': [i for i in note_cursor]}
        resp.body = json.dumps(result)

    def on_post(self, req, resp):
         """Handles POST requests"""
             raw_json =
         except Exception as ex:
             raise falcon.HTTPError(falcon.HTTP_400,'Error',ex.message)

             result = json.loads(raw_json, encoding='utf-8')
             sid =  r.db(PROJECT_DB).table(PROJECT_TABLE).insert({'title':result['title'],'body':result['body']}).run(db_connection)
             resp.body = 'Successfully inserted %s'%sid
         except ValueError:
             raise falcon.HTTPError(falcon.HTTP_400,'Invalid JSON','Could not decode the request body. The ''JSON was incorrect.')

api = falcon.API()
api.add_route('/notes', NoteResource())

We can break down the code into following pieces.

  1. We imported falcon and database client
  2. Created a resource class called NoteResource
  3. Created two methods called on_get and on_post on NoteResource.
  4. In on_get method, we are checking for “id” parameter in the request and sending one resource (note) or all resources (notes). req, resp are the request and response objects of falcon respectively.
  5. In on_post method, we are checking for data as a raw JSON. We are decoding that raw JSON to store title and body in the rethinkDB notes table.
  6. We are creating API class of falcon and adding a route for it. ex: ‘/notes’ in our case.

Now in order to serve API, we should start WSGI server because falcon needs an independent server to deliver the API. So launch Gunicorn

$ gunicorn app:api


This will run Gunicorn WSGI server on port 8000. Visit


to view all notes stored.

If notes are empty then add one using POST request to our API.

Screenshot from 2015-09-13 03:13:54

Now add one more note as shown above with different data. Let us say it is { “title” : “At 10:00 AM” , “body” : ” Scrum meeting scheduled”}. Now visit http://localhost:8000/notes once again and you will find this


.Screenshot from 2015-09-13 03:19:37

If we want to fetch an element by id then do it with this. http://localhost:8000/notes?id=d24866be-36f0-4713-81fd-750b1b2b3bd4. Now only one note with given ID will be displayed.

Screenshot from 2015-09-13 03:22:51

This is how falcon enables us to create REST API easily at very low level. There are many additional features available for Falcon. For more details visit Falcon home page. If you want to see the full source code of above demonstration, visit this link.

please do comment if you have any query. Have a good day🙂 .

15 thoughts on “Build massively scalable RESTFul API with Falcon and PyPy

    1. Domen, I too like Pyramid. I worked with it while developing a social network for houses. But due to its documentation it is a nightmare for beginners. I will blog about it for sure.

      1. Most beginners that seek help on IRC in #pyramid, on the Pyramid mailing lists, and Pyramid issue tracker report that the documentation is extremely thorough and helpful. This statement comes from a former beginner to both Python and Pyramid, who now uses the documentation to support newbies and incorporates their feedback to improve the documentation.

        We welcome suggestions to improve the documentation and make it more approachable for all users. If you can explicit about what qualifies the documentation as being a “nightmare for beginners”, then we can begin to address whatever problems you may have with it.

  1. What do I use? For quick hacks on low endpoint count I roll my own with bottle under gevent or flask. I have also used django rest framework and webapp2. I rather like the latter for class based request handlers without as much cruft as django rest framework but then again it doesn’t try to solve as large a problem. I am a fan of minimal tools that can be easily combined to tackle a problem. YMMV as well as what you value.

    1. Hi Samantha, If you are building API on existing framework or data better to use Tastypie or Django REST Framework. But if you are building totally different micro services then do that in frameworks like Falcon or something like Eve ( because these touches the bare metal or optimized to run faster .

  2. I appreciate the post a lot, thanks! One question though, wouldn´t you run into trouble if running gunicorn with multiple threads as the connection you create is not thread safe?

  3. I appreciate the post a lot, thanks! One question though, in your example, wouldn´t you run into trouble if running gunicorn multithreaded since the rethinkdb connection is not thread safe?

  4. Have you tried compiling your Python code with the Pythran compiler? I have been unable to find third party benchmarks comparing PyPy and Pythran but Pythran claims a 20 fold performance improvement as well in some tests. It seems to me that distributing .exe files should be easier than Python virtual environments in PyPy if Pythran was just as fast.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s