Production deployment of a Python Web Service (Flask / Tornado Application)

Python Flask and Tornado are two of the most popular frameworks in python for developing RESTful services.

Do you know how to develop and deploy a production grade python application. ?

A sample python flask service is given below. This is a sample flask web service. This has only one endpoint (/requestme) at is a GET method. (sample_flask.py). I am not focusing on the coding standards. My goal is to show you the production implementation of a python application.

We can run this program in the command line by executing the following command.

> python sample_flask.py

The service will be up and running in port 9090. You will be able to make requests to the application by using the URL http://ipaddress:9090/requestme.

How many requests will this python web service can handle ? 

10 or 20 or 100 ?? … Any guess ??

Definitely this is not going to handle too many requests. This is good for development trials and experimental purpose. But we cannot deploy something like this in production environment.

How to scale python applications  ?

Refer to the below diagram. The diagram has multiple instances of flask applications with Gunicorn WSGI proxied and load balanced through Nginx web server.

haproxy_python

Production Deployment of Python Flask Application

Sample Nginx configuration that implements the reverse proxy and load balancing is given below. 

This is a sample configuration and this does not have the advanced parameters.

server {
listen 80;
server_name myserverdomain

location / {
proxy_pass http://upstream_backend/requestme;
  }
}

upstream backend {
server gunicornapplication1:8080;
server gunicornapplication2:8080;

}

 

The upstream section routes the requests to the two gunicorn backends and the requests are routed in round robin manner. We can add as many backend servers as we need based on the load.

How to run the python applications with gunicorn ?

First lets install gunicorn

> pip install gunicorn

Now it is simple, run the following command.

> gunicorn -w 4 app:app

Now the our application will run with 4 workers. Each worker is a separate process and will be able to handle requests. The gunicorn will take care of handling the requests between each of the workers.

We can start multiple gunicorn instances like this and keep it behind the nginx. This is the way to scale our python applications.

Hope this helps 🙂 

A simple program to begin with python tornado

Python tornado is a powerful framework for dealing with HTTP requests. It helps us to write responses to HTTP requests in a very simple and elegant way. We can write handlers for responding to the HTTP requests very easily using tornado. This is very simple to learn and use. We can create an excellent application in very few lines of code. Here I am explaining about a simple tornado application. The code is attached below. For running this code, you need tornado to be installed in your machine.

In the beginning of the code, you can see few imports related to tornado. These libraries are required for our tornado application. After that you can see a define function. This define is imported from a library called options in tornado. Using this we can get user defined arguments from commandline. Here we are defining the port in which our tornado application should run. If the user is specifying the port in the command line, it will use that value, else it will use the default value. Here I gave default value as 8888. 

The next part is a class named HelloWorldHandler. This is a class extending the tornado RequestHandler class. This is basically a handler, which means this will handle an HTTP request. This class will be called based on the navigation rules that we define in the tornado. In this class there is only one method called get(). So this handler can handle only get requests. In the get method, we are just printing a text “Someone called me” and writing a response. So whenever this class is called, The text “Someone called me” will be printed in the console and the self.write(“Welcome to Tornado..!!”) will send the this string to the HTTP response.

The next part will run the tornado application. The “tornado.web.Application(handlers=[(r”/”, HelloWorldHandler)])” defines when to invoke the handler. the r”/” is a regex. So if the url comes without any path, the request will be navigated to HelloWorldHandler class. Similar to this we can have a list of regex – handler class pairs. Here we have only one.

Execution.

python HelloTornado.py –port 9090

This will run the application in 9090 port. After this open the web browser and check http://localhost:9090. You will get a message “Welcome to Tornado.!!” on the screen. For every hit, you can see a message “Someone called me” getting printed in the console.

python HelloWorld.py

This will run the application in the default port that we specified. I specified 8888. So open the webbrowser and check http://localhost:8888.

Note: If you are executing the code in a different machine, you should use the ip address of the machine instead of localhost.

Happy Learning … 🙂