By Raushan Raj, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
In this article, we are going to quickly build and deploy a blazing fast REST API in Python web framework using Falcon. While walking through this article you will first learn the basics of Falcon framework, installing it on Alibaba Cloud Elastic Compute Service (ECS), building a Rest API for the app and finally deploying the app on the cloud.
Falcon is a minimalist WSGI library for building speedy web APIs and app backends. 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.
The first thing that comes to your mind is probably "Why should I use Falcon?" Well, Falcon is as powerful as other python's frameworks like a flask, Django, bottle, web.py, and it is fast, extensible, reliable, and encourages RESTful style. As per benchmarks, Falcon is 21 times faster on pypy than flask and Django. Organizations like LinkedIn, Leadpages, Wargaming, and Rackspace are already using it in their applications.
Installing Falcon on Alibaba Elastic Compute Service (ECS) is as simple as installing it in your PC.
You can refer the steps to provisioning your server using this tutorial Setup up Ubuntu Server on Alibaba_Cloud.
"If you want your code to run faster, you should probably just use PyPy.??Guido van Rossum
$ sudo apt-get install python3-dev
$ wget https://bitbucket.org/pypy/pypy/downloads/pypy3-v6.0.0-linux64.tar.bz2
$ tar -xvf pypy3-v6.0.0-linux64.tar.bz2 -C /opt
$ sudo ln -s /opt/pypy3-v6.0.0-linux64/bin/pypy3 /usr/local/bin/pypy3
$ sudo chown -R <youruser>:<yourgroup> pypy3-v6.0.0-linux64/
$ pypy3
Python 3.5.3 (fdd60ed87e94, Apr 24 2018, 06:10:04)
[PyPy 6.0.0 with GCC 6.2.0 20160901] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>> import this
Once pypy3 is installed we have to install python dependencies compatible with pypy3's pip.
$ wget https://bootstrap.pypa.io/get-pip.py
$ pypy3 get-pip.py # pypy3 -m ensurepip
$ sudo apt-get install python3-pip
$ pip3 install virtualenvwrapper
Install virtualenvwrapper.
Append following line to .bashrc or .profile.
export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/Devel
source /usr/local/bin/virtualenvwrapper.sh
It's better to install python dependencies in virtualenv.
$ mkvirtualenv -p /usr/local/bin/pypy3 falconenv
(falconenv):~$ pypy3 -m pip install falcon mongoengine
MongoDB is an open-source document database that provides high performance, high availability, and automatic scaling.
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
$ echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
$ sudo apt-get update
$ sudo apt-get install -y mongodb-org
$ sudo systemctl start mongod
$ sudo systemctl status mongod
# This command will start mongod. Other options are stop | restart | status.
? mongodb.service - High-performance, schema-free document-oriented database
Loaded: loaded (/etc/systemd/system/mongodb.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2016-04-25 14:57:20 EDT; 1min 30s ago
Main PID: 4093 (mongod)
Tasks: 16 (limit: 512)
Memory: 47.1M
CPU: 1.224s
CGroup: /system.slice/mongodb.service
??4093 /usr/bin/mongod --quiet --config /etc/mongod.conf
We are going to create a book project where the user can create a book, update book and fetch book by id from MongoDB.
book_project/book/
has following python files.
models : In models we used mongoengine ORM. Any class that inherits Document class of mongoengine describes the equivalent collection in MongoDB database. We have created a resource Book with the field name, ISBN, and author. Mongoengine will autogenerate unique id for each object of the resource.
from mongoengine import StringField, IntField, Document
class Book(Document):
name = StringField()
isbn = IntField()
author= StringField()
api : Book resource have enpoint methods on_get, on_post. Usage of each method is described in code comments below.
api.py source code is a below.
import falcon, json
from .models import Book
class BookResource(object):
def on_get(self,req,resp,book_id):
'''
:param req: A request object
:param resp: A response object
:param book_id: book_id received in http path to query book object
:return:
'''
book_obj= Book.objects.get(id=book_id)
#Query book collection to get a record with id = book_id
resp.body = json.dumps({'author':book_obj.author,'name':book_obj.name,'isbn':book_obj.isbn})
#It will set response body as a json object of book fields.
resp.status = falcon.HTTP_200
#Finally return 200 response on success
def on_post(self,req,resp):
'''
This method will recevie the book data in request body in order to store it in database
:param req: It contains json of book's author, name and isbn.
:param resp:
:return:
'''
book_data = req.media
#req.media will deserialize json object
book_obj=Book.objects.create(**book_data)
#passing book_data to create method. It will create a database document in book collection.
resp.body = json.dumps({'book_id':str(book_obj.id),'message':'book succesfully created'})
resp.status=falcon.HTTP_200
GET request endpoint to get a book given id : http://<host>:<port>/<book_id>
POST request endpoint to create a book with data : http://<host>:<port>/<book_id>
,
{"author":<author_name>,"name":<book_name>, "isbn":<isbn>}
app: This is the entry point for HTTP requests, It contains routing to resources based on HTTP path and other configurations
import falcon
from mongoengine import connect
from .api import BookResource
connect('bookdb', host='127.0.0.1', port=27017)
app = application = falcon.API()
books = BookResource()
app.add_route('/book/{book_id}', books)
app.add_route('/books/', books)
connect(, host=, port=), this line will automatically create a connection to the mongodb database with given credentials. The connection will be globally use throughout the scope of an app.
app = application = falcon.API(), this line will create application instances that gunicorn (web application server) will autofind and act as an wsgi app.
books = BookResource(), this line will create and instance of the resource.
app.add_route('/book/{book_id}', books) and app.add_route('/books/', books), will route the http path and method to the respective methods of the resource.
Gunicorn
Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy._
In simple terms, gunicorn understands HTTP requests and make it understandable to python applications by converting HTTP bytes to python objects.
Run gunicorn on your ubuntu machine using following commands.
(falconenv):~$ pypy3 -m pip install gunicorn
(falconenv):~/book_project$ gunicorn --reload book.app --bind 127.0.0.1:9000
Nginx
NGINX is open source software for web serving, reverse proxying, caching, load balancing, media streaming, and more. It started out as a web server designed for maximum performance and stability. In addition to its HTTP server capabilities, NGINX can also function as a proxy server for email (IMAP, POP3, and SMTP) and a reverse proxy and load balancer for HTTP, TCP, and UDP servers.
Describing in Simple terms, nginx is a software that receives HTTP request bytes and sends HTTP response bytes to the client. Nginx is responsible to forward HTTP request bytes to python application server(gunicorn).
$ sudo apt-get install nginx
sudo vim falcon_nginx.conf
upstream falcon_gunicorn {
server 127.0.0.1:9000;
}
server {
listen 80;
server_name <ALIBABA ECS instance public ip>;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://falcon_gunicorn;
proxy_redirect off;
proxy_set_header Host $host;
}
}
$ sudo cp falcon_nginx.conf /etc/nginx/sites-enabled/nginx.conf
$ sudo service nginx restart
In order to develop and quickly deploy a REST API, Falcon proves to be one of the best alternatives. We need to install pypy3, falcon, MongoDB, gunicorn, Nginx and other dependencies on Alibaba Cloud's Elastic Compute Service (ECS) Ubuntu Server. API syntax for falcon is totally based on REST architecture and is very easy to develop with proper routing, model structure, and views. Falcon is a scalable solution and can be easily deployed on any WSGI servers like gunicorn, uwsgi, and waitress. Adding Nginx on top of gunicorn server will make microservices scalable, distributed and secure.
How to Develop Web Applications on Alibaba Cloud with Django Framework
2,599 posts | 764 followers
FollowAlibaba Clouder - April 28, 2021
Alex - August 26, 2019
Alibaba Cloud Data Intelligence - December 6, 2023
Farruh - January 12, 2024
Alibaba Clouder - March 22, 2019
Alibaba Clouder - March 18, 2019
2,599 posts | 764 followers
FollowElastic and secure virtual cloud servers to cater all your cloud hosting needs.
Learn MoreAlibaba Cloud Function Compute is a fully-managed event-driven compute service. It allows you to focus on writing and uploading code without the need to manage infrastructure such as servers.
Learn MoreCloud-based and lightweight servers that are easy to set up and manage
Learn MoreMore Posts by Alibaba Clouder
5809870713234921 October 10, 2019 at 1:17 pm
Hi, the example is throwing an error, you may find it in the log file. Please, review the article so it work 100%. Thanks and regards! Keep doing this good work![2019-10-10 14:09:08 0100] [6356] [ERROR] Error handling request /booksTraceback (most recent call last): File "/Users/marti/PycharmProjects/nlpapi/venv/lib/python3.6/site-packages/gunicorn/workers/sync.py", line 135, in handle self.handle_request(listener, req, client, addr) File "/Users/marti/PycharmProjects/nlpapi/venv/lib/python3.6/site-packages/gunicorn/workers/sync.py", line 176, in handle_request respiter = self.wsgi(environ, resp.start_response) File "/Users/marti/PycharmProjects/nlpapi/venv/lib/python3.6/site-packages/falcon/api.py", line 269, in call responder(req, resp, **params)TypeError: on_get() missing 1 required positional argument: 'book_id'