Python web frameworks: Django, Flask, Bottle, Pyramid, Tornado, Web2py, Falkon

Python web frameworks: Django, Flask, Bottle, Pyramid, Tornado, Web2py, Falkon

A lot of concepts in programming and information systems are built on the principles of using well-proven and universal solutions. Similarly, developers have the principle of “do not repeat yourself”, which means do the work once and then use this solution repeatedly. 

The frameworks for various programming languages, for example, for web development, work with such principles.

You can argue for a long time about what part of the project for a particular web information system can be successfully repeated based on the framework, but no one will disagree that using the framework makes the task ten times easier.

Many novice developers answer the question of which framework they are using, proudly raising their hand and speaking out loud: our own framework. And in response, experienced developers who have tried all possible solutions and a dozen frameworks will only smile in response. Because writing “your own” framework from scratch in modern conditions is no longer relevant. You just need to decide what tasks you are going to solve with the help of the framework and choose an existing one. Why? Because it is better to learn from the mistakes of others than from your own, as has been proven repeatedly in various fields.

Experienced developers will primarily consider frameworks such as Django, Bootle, and Flask for web development in Python. Let's see why many people like these three frameworks.

History of web frameworks

If you look at the history of web frameworks, developers in all programming languages took a very difficult and thorny path and spent a lot of effort to decide which features of a framework are needed and which architecture will take root best.

Look at the picture below and you will understand how that web frameworks have advanced their path in the development of information systems, even though they had to compete with desktop applications and conquer the market step by step.

Image source

History of web frameworks

Among a huge pile of existing frameworks, those ones based on Python, clearly occupy their rightful spot. In our previous article, we described the new web frameworks in Python.

Usually, a web framework is now built as a “Three-tier organization”. The three components are the client part (web browser), the backend, and the database. But the backend is already being built on the model, view, and controller, which greatly simplifies the organization of the server-side.

Why Python frameworks in web development

You may ask “Why did Python frameworks gain a foothold in web development?” The answer is obvious: because there are Django, Flask, and Bottle.

First, Python, as an interpreted programming language, is almost perfect for backend development. It has high-level data structures and the ability to work with an object-oriented approach. Python code is very clear, compact and resistant to the fantasies of both novice developers and masters of this programming language.

Before the advent of effective Python frameworks for web development in this area, successful steps were taken in Ruby (Ruby-on-Rails) and Java (Spring). This motivated the amateurs and professionals of Python to create the equivalent frameworks for Python, but taking into account its features, mainly quickly and efficiently creating web-based information systems.

Classical web development frameworks

Django

Just as Python was named after the Monty Python show, Django was named after the musician Django Reinhardt (1910 — 1953, French jazz virtuoso guitarist).

Django's architecture is similar to Model-View-Controller (MVC). The controller of the classic MVC model roughly corresponds to the level that Django calls the View, and the presentation logic of the View is implemented in Django by the Template level. Because of this, the layered architecture of Django is often referred to as Model-Template-Presentation (MTP).

As Django positioned like a full-scale Python framework to run the first application you need to make some commands from a terminal. Nice and clear instructions are placed here.

Creating the first view in the project is simple. Don’t forget that Django is based on Model-View-Controller (MVC) and you will need to create a model and controller as well.

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")
Code language: JavaScript (javascript)

There are many ways to create REST API on Django. You can find a lot of tutorials, for instance, this one is very clear and very detailed.

The most valuable features of Django framework are:

  • ORM, transactional database access API
  • built-in administrator interface, with existing translations into many languages
  • regex-based URL manager
  • extensible template system with tags and inheritance
  • caching system
  • internationalization
  • plug-in application architecture that can be installed on any Django sites
  • "Generic views" - controller function templates
  • authorization and authentication, a connection of external authentication modules: LDAP, OpenID, etc.
  • filter system ("middleware") for building additional request handlers, such as filters included in the distribution for caching, compression, normalization of URLs and support for anonymous sessions
  • library for working with forms (inheritance, building forms according to the existing database model)
  • built-in automatic documentation for template tags and data models, accessible through the administrative application

Large REST APIs often require a large number of requests to get all the necessary data. GraphQL is a query language that makes exchanging related data much easier. Graphene-Django makes it easy to add the appropriate functionality to your Django project. Django's models, forms, authentication, permission policies, and other functionalities can be used to create the GraphQL API.

If we compare Flask vs Django, in some cases, learning the Django framework will take longer than Flask and Bottle. For beginners, developers should try micro-frameworks before seriously taking the road to Django.

Django is a large and monolithic framework. Thanks to this, the community develops hundreds of universal modules and applications. This slows down the development speed of Django itself. The framework must support backward compatibility, so it is developing relatively slowly compared to the new frameworks.

The Django web framework is used in such large and well-known sites like Instagram, Disqus, Mozilla, The Washington Times, Pinterest, YouTube, Google, etc.

Flask

This is a lightweight WSGI web application framework. Lightweight means it is powerful and very efficient, while at the same time this framework has all necessary functionality. Flask was created by Armin Ronacher in 2004.

Flask uses Jinja as a template engine. It allows separating business logic and presentation of web pages.

Also, the Werkzeug WSGI toolkit is used to operate the Web Server Gateway Interface. It helps to build an implementation-agnostic interface between web servers and web applications. 

Flask does not provide a database abstraction layer and form validation. These functions are implemented by extensions. As soon as extensions are updated far more frequently than the core Flask, it gives better support of all necessary features, including object-relational mappers, form validation, upload handling, and various open authentication technologies.

Please take a look at how simple and beautiful a Flask web application can be:

from flask import Flask, escape, request

app = Flask(__name__)

@app.route('/')
def hello():
    name = request.args.get("name", "World")
    return f'Hello, {escape(name)}!'
Code language: JavaScript (javascript)

And then run this simple application like this:

$ env FLASK_APP=hello.py flask run
 * Serving Flask app "hello"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Code language: JavaScript (javascript)

For example, you can see how simple and effective Flask works with API methods and JSON:

@app.route("/me")
def me_api():
    user = get_current_user()
    return {
        "username": user.username,
        "theme": user.theme,
        "image": url_for("user_image", filename=user.image),
    }
Code language: JavaScript (javascript)

If you need to work with JSON, then jsonify works very well:

@app.route("/users")
def users_api():
    users = get_all_users()
    return jsonify([user.to_json() for user in users])
Code language: JavaScript (javascript)

Main features of the Flask framework are:

  • contains development server and debugger
  • integrated support for unit testing
  • RESTful request dispatching
  • uses Jinja2 templating
  • support for secure cookies (client-side sessions)
  • 100% WSGI 1.0 compliant
  • Unicode-based
  • extensive documentation
  • Google App Engine compatibility
  • Extensions available to enhance features desired

A very big advantage in Flask is the presence of an integrated testing system, which greatly improves the stability and quality of web applications.

Flask uses the blueprint’s concept (“blueprint”) to create application components and support common patterns within an application or between applications. Blueprints can both greatly simplify large applications and provide a common mechanism for registering operations from Flask extensions in an application. The Blueprint object works similarly to the Flask application object, but in reality, it is not an application. This is usually just a sketch for building or expanding an application.

One of the drawbacks of the Flask framework is the lack of namespace nesting.  In this case, comparing Tornado vs Flask, we find that Tornado has nesting templates. Please find more information on the subject here.

In confirmation of the popularity and high reliability of the Flask framework, such companies as Pinterest and LinkedIn use it for their web applications.

Web Solutions

Bottle

Bottle is another microframework based on the WSGI concept. The advantage of the Bottle framework is that it has no dependencies other than the Python Standard Library.  This makes this framework highly portable and compact to use on the small computation platforms, including for instance IoT.

Bottle provides very good request dispatching (routes) with URL parameter support, templates, a built-in web server and adapters for many third party WSGI/HTTP-server and template engines.

Here is a simple example of how to use Bottle:

from bottle import route, run, template

@route('/hello/<name>')
def index(name):
    return template('<b>Hello {{name}}</b>!', name=name)

run(host='localhost', port=8080)
Code language: JavaScript (javascript)

Here is an example of how to use HTTP methods in the Bottle framework:

from bottle import get, post, request # or route

@get('/login') # or @route('/login')
def login():
    return '''
        <form action="/login" method="post">
            Username: <input name="username" type="text" />
            Password: <input name="password" type="password" />
            <input value="Login" type="submit" />
        </form>
    '''

@post('/login') # or @route('/login', method='POST')
def do_login():
    username = request.forms.get('username')
    password = request.forms.get('password')
    if check_login(username, password):
        return "<p>Your login information was correct.</p>"
    else:
        return "<p>Login failed.</p>"
Code language: HTML, XML (xml)

The advantage of Python and Bottle is that almost anybody familiar with programming can read and understand this code. This is very valuable and effective for learning and using this framework in small projects and on the corporate level as well.

There are a number of valuable features of the Bottle framework:

  • single file which runs with both Python 2.5+ and 3.x
  • can run as a standalone web server or be used behind ("mounted on") any web server which supports WSGI and support for paste, fapws3, bjoern, gae, cherrypy or any other WSGI capable HTTP server
  • built-in template engine called SimpleTemplate Engine
  • support for JSON client data (for REST and JavaScript clients)
  • plugins for popular databases and key/value stores and other features
  • routing: Requests to function-call mapping with support for clean and dynamic URLs
  • fast and pythonic built-in template engine and support for mako, jinja2 and cheetah templates
  • utilities: Convenient access to form data, file uploads, cookies, headers, and other HTTP-related metadata

According to Jetbrains, the Bottle framework is in  5th for place popularity and has a 4% share of Python web frameworks. It is great for prototyping, personal web applications, and rapid development.

Pyramid

Pyramid is an open-source Python web framework. Its main goal is to build web applications with minimum complexity.

Pyramid is designed to work well with both small and large applications. Pyramid’s features include the capability to build single-file applications,  use all-embracing templating and asset specifications, flexible authentication and authorization. It has great testing, support, and comprehensive data documentation. Pyramid provides function decorators, predicates and renderers.

The creation of Pyramid was influenced by frameworks such as Zope, Pylons, and Django. Pyramid code was developed in the repoze.bfg project and the name changed as a result of the merger of the BFG and Pylons projects.

Here is one of the most popular code example on Pyramid:

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response

def hello_world(request):
   return Response('Hello %(name)s!' % request.matchdict)

if __name__ == '__main__':
   config = Configurator()
   config.add_route('hello', '/hello/{name}')
   config.add_view(hello_world, route_name='hello')
   app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 8080, app)
   server.serve_forever()
Code language: JavaScript (javascript)

The main advantages of Pyramid are:

  • the ability to write an application in one file
  • decorator based configuration
  • toolbar for debugging applications directly in the browser
  • views based on both classes and functions
  • configuring asset files, that is, project files that are not Python source files
  • extensible, interchangeable templates (template)
  • event system
  • built-in internationalization (i18n)
  • HTTP caching
  • built-in session support
  • species for exceptions
  • view predicates and multiple views for a route
  • transaction management, including when working with multiple databases at once
  • flexible, extensible authentication and authorization
  • the possibility of traversal of the resource tree
  • 100% code coverage with tests

If you want to see a comparison between Pyramid vs Flask, please follow this link. Also, it’s a good idea to compare Pyramid vs Django, and for that scenario, we recommend that you follow this link.

Tornado

Tornado is an extensible, non-blocking web server and framework written in Python. It was created for use in the FriendFeed project, which Facebook acquired in 2009, after which the source code for Tornado was open. Tornado was created to provide high performance and is one of the web servers that can withstand the problem of ten thousand connections. The web server that runs FriendFeed is a relatively simple, non-blocking web server written in Python. If we compare Python Tornado vs Flask, they are pretty much the same and are all easy to learn.

The code on Tornado is quite simple and easy to read and understand:

import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

if __name__ == "__main__":
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    application.listen(8888)
    tornado.ioloop.IOLoop.current().start()

The following are the modules of this framework:

  • web is the web framework on which FriendFeed is built. The web contains most of the important Tornado features
  • escape - XHTML, JSON, and URL encoding / decoding methods
  • database - A simple wrapper around MySQLdb to simplify the use of MySQL DBMS
  • template - a template language based on Python syntax
  • httpclient - non-blocking HTTP client for working with web and httpserver modules
  • auth - implementation of authentication and authorization schemes from third developers (Google OpenID / OAuth, Facebook Platform, Yahoo BBAuth, FriendFeed OpenID / OAuth, Twitter OAuth)
  • locale - support for localization / internationalization
  • options - command line parser and argument parser optimized for use in a server environment
  • httpserver is a very simple HTTP server, on the basis of which the web module is built
  • iostream - a simple wrapper around non-blocking sockets to provide common read and write patterns
  • ioloop - main I / O loop
  • s3server is a web server that implements most of the Amazon S3 interface with local file storage

Web2py

Web2py is an open-source web application development framework written in the Python programming language. Web2py allows web developers to create dynamic sites using Python. Web2py aims to reduce the routine of web development processes, such as writing web forms from scratch, although a developer can develop a form from scratch if necessary.

Web2py was originally invented as a training tool with a focus on usability and ease of implementation, as it lacks project configuration files. The web2py architecture was developed under the influence of the Ruby on Rails (RoR) and Django frameworks. Like these frameworks, web2py is aimed at rapid development, proclaims agreement over configuration and follows the Model-View-Controller (MVC) design pattern.

The code for Web2py is very simple; for example, you need literally two lines to return JSON:

def makejson():
        return response.json(['foo', {'bar': ('baz', None, 1.0, 2)}])
Code language: CSS (css)

The most valuable features of Web2py framework are:

  • HTTP requests, HTTP responses, cookies, Sessions
  • support for multiple protocols [3] HTML / XML, REST, Atom and RSS, RTF and CSV, JSON, JSON-RPC and XML-RPC, AMF-RPC (Flash / Flex), and SOAP
  • CRUD API
  • many authentication mechanisms and access control by roles
  • Database Abstraction Layer dynamically generating SQL queries and supporting many compatible database engines
  • RAM, HDD, and memcached-based caching for scalability
  • support for internationalization
  • jQuery for Ajax and UI effects
  • automatic error logging with context

Falkon

As mentioned in documentation “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.”

The code for Falcon is very simple, for example:

class QuoteResource:

    def on_get(self, req, resp):
        """Handles GET requests"""
        quote = {
            'quote': (
                "I've always been more interested in "
                "the future than in the past."
            ),
            'author': 'Grace Hopper'
        }

        resp.media = quote

api = falcon.API()
api.add_route('/quote', QuoteResource())

Falcon gives users a very good list of features:

  • routes based on URI templates RFC
  • REST-inspired mapping of URIs to resources
  • global, resource, and method hooks
  • idiomatic HTTP error responses
  • full Unicode support
  • intuitive request and response objects
  • works great with async libraries like gevent
  • the minimal attack surface for writing secure APIs
  • 100% code coverage with a comprehensive test suite
  • no dependencies on other Python packages
  • supports Python 3.5+
  • compatible with PyPy

Cloud support of Python frameworks

Many cloud systems now support web development frameworks, including Python. This allows cloud providers to attract more customers, and the clients themselves to improve and speed up the web application on the corresponding framework.

For instance, Python frameworks are supported on the following cloud platforms:

  • Amazon Web Services (AWS)
  • Azure (Microsoft)
  • Google Cloud Platform
  • Hetzner
  • DigitalOcean
  • Heroku

And with the invention of the containerization system (the most popular of them is Docker), the question of placing a web application in the cloud has become universal and not tied to a particular cloud provider. This makes it possible, if necessary, to relocate your project to another cloud, scale it if necessary, and serve the project at the DevOps level. 

These systems based on Docker have already become the de facto standard, and major cloud service providers are willing to provide containerization services.

Conclusion

Hundreds of thousands of projects are written in Python frameworks, the three main of which are Django, Flask, and Bottle. These frameworks have been around a while, remain relevant and will evolve in the future. 

Competitive new frameworks are of course crowding the programming market in Python, but the old guard will not easily give up its position. And once again I want to repeat, there are no wrong projects, you just need to choose the appropriate framework to solve your problem. 

The developers and project managers in Svitla Systems have many Python frameworks, as well as front-end development, backend development, and full-stack capabilities. We have done more than one hundred projects in this area and we will choose and implement the optimal solution for you.