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.

Note: For my other tech articles on JS and Software Development visit my web log: https://medium.com/dev-bits

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 https://github.com/narenaryan/Falcon-REST-API-Pattern

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.

Create a note (PUT) Fetch a note by ID (GET) Fetch all notes (GET) PUT & DELETE are obvious

Install RethinkDB on Ubuntu14.04 in this way.

$ source /etc/lsb-release && echo "deb http://download.rethinkdb.com/apt $DISTRIB_CODENAME main" | sudo tee /etc/apt/sources.list.d/rethinkdb.list $ wget -qO- http://download.rethinkdb.com/apt/pubkey.gpg | 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 “db_client.py”

#db_client.py 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' PROJECT_TABLE = 'notes' # Set up db connection client db_connection = r.connect(RDB_HOST,RDB_PORT) # Function is for cross-checking database and table exists def dbSetup(): try: r.db_create(PROJECT_DB).run(db_connection) print 'Database setup completed.' except RqlRuntimeError: try: r.db(PROJECT_DB).table_create(PROJECT_TABLE).run(db_connection) print 'Table creation completed' except: print 'Table already exists.Nothing to do' dbSetup()

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

on_get on_post on_put on_delete

So we are going to implement first two functions in this article. Create a file called app.py.

#app.py 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)} else: 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""" try: raw_json = req.stream.read() except Exception as ex: raise falcon.HTTPError(falcon.HTTP_400,'Error',ex.message) try: 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.

We imported falcon and database client Created a resource class called NoteResource Created two methods called on_get and on_post on NoteResource. 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. 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. 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

http://localhost:8000/notes

to view all notes stored.

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

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

.

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.

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.

https://github.com/narenaryan/Falcon-REST-API-Pattern

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