A short review of four Python web frameworks

Python web frameworksBy Mike Jackson, Software Architect.

As part of my open call consultancy for LUX-ZEPLIN (LZ), I was asked to review web frameworks for Python, in particular those that could be used with MongoDB, the database management system used by LZ. In this blog post, I survey four frameworks for implementing web applications: Django, TurboGears, Flask and Pyramid.

These four web frameworks were selected from the many available because they each meet LZ’s requirements that they can be deployed under the popular Apache web server, that they support authentication and authorisation, and that they support directly, or via third-party libraries, the use of MongoDB for holding application-specific data. Additionally, the four web frameworks are popular, with a large user communities and each have permissive open source licences. This latter selection criteria follows our guide on Choosing the right open source software for your project which summarises factors to be considered when choosing open source software for use on projects.

The key details of each web framework are as follows:

Framework

Current release

Licence

Apache

Authentication and authorisation

Django

1.11.4

August 2017

BSD 3-clause

Via mod_wsgi

User authentication and authorization based around users, groups and permissions.

TurboGears

2.3.11

July 2017

MIT

Via mod_wsgi

Access control and authorization based around users, groups and permissions.

Flask

0.12.2

May 2017

BSD 3-clause

Via mod_wsgi

Third-party toolkits e.g. Flask-User: user account management toolkit, supporting role-based authorization; Flask-Login: user authentication and session management toolkit.

Pyramid

1.9.1

July 2017

Repoze (BSD-like)

Via mod_wsgi

Optional security system based around users, groups and permissions.

A PyMongo aside

PyMongo (Current release 3.5.1, August 2017, Apache 2 licence) is not a web framework but is included here as it is the recommended driver for using MongoDB from Python. Many MongoDB-related Python components, including those mentioned below, use PyMongo under the hood, so it is a useful toolkit to be aware of and familiar with.

Django

To write a web application using Django, a developer:

  1. Writes models, Python code that describes data and its behaviour.

  2. Uses Django's tooling to automatically create database tables and a database API from these models, and a local database administration interface.

  3. Writes views, Python code that handles HTTP requests and prepares HTTP responses. Views can interact with models and populate templates.

  4. Writes templates, HTML fragments that can be populated with data by views. Django provides its own template language (DTL). Alternatively, the popular Jinja2 templating language can be used.

Django uses relational databases (PostgreSQL, SQLite or MySQL) as a back-end for both its core data (e.g. for administration, authentication and sessions) and for application data. Django uses object-relational mapping, so developers do not need to interact with the database directly using SQL. Instead, developers write code that invokes operations on the Python models and which uses the auto-generated database API, and Django maps these operations into SQL and interacts with the database.

Django can be used to develop web applications for existing relational databases. It provides tooling to auto-generate Python models from the database. If using an existing database, Django still needs to add its own core database tables. For more information, see Integrating Django with a legacy database.

Though Django assumes a relational database back-end, there has been work to allow MongoDB to be used with Django, see Django Packages for a comprehensive list of packages. The drawback of using MongoDB is that, unless a third-party has implemented support for these features, one loses Django's auto-generated administration interface and any features which are reliant on Django's core data. In this situation there are three options:

  • Use a third-party component that implements this support.

  • Implement it in-house.

  • Use a relational database for Django's core data and MongoDB for application data.

mongoengine

mongoengine (Current release 0.14.0, May 2017, MIT licence) seems to be the most prevalent package for using Django with MongoDB. mongoengine is a Python Object-Document Mapper (object-document mapping is the document database equivalent of object-relational mapping). mongoengine supports Django's core authentication and session data. Up to version 0.9 (January 2014), mongoengine included a Django extension, but this has now been split off from the mongoengine repository into a new project, django-mongoengine (no numbered releases, BSD 3-clause licence). While django-mongoengine is under active development, the developers caution that it is an “unstable project” and that they are “targeting to get things working on Django 1.9”.

A slide-set from 2013, Using MongoDB as your primary Django database, gives an overview of mongoengine, and there are a number of third-party blog posts that describe how to use it, for example Using Django and MongoDB to Build a Blog (2014, uses Django 1.5.1) and Using MongoDB with Django (2012, uses Django 1.3 and mongoengine 0.4). It is unclear whether mongoengine and django-mongoengine would work with the current, 1.11, version of Django.

TurboGears

To write a web application using TurboGears, a developer:

  1. Writes models, Python code that describes data and its behaviour.

  2. Uses TurboGears tooling to automatically create database tables.

  3. Writes controllers, Python code that handles HTTP requests and prepares HTTP responses. Controllers can interact with models and populate views.

  4. Writes views, HTML fragments that can be populated with data by controllers. TurboGears provides its own Kajiki template language.

TurboGears can use either a relational database or MongoDB (see Using MongoDB) as a back-end. Interaction with relational databases is via the Python object-relational mapper, sqlalchemy (Current release 1.2.0b2, July 2017, MIT licence). Interaction with MongoDB is via the Python Ming object-document mapper (Current release 0.55, December 2016, MIT licence), inspired by sqlalchemy and built upon PyMongo.

There does not seem to be documentation for using an existing relational or MongoDB database with TurboGears. However, one could manually write models that are consistent with the underlying database, rather than use TurboGears to auto-generate these.

Flask

Flask is a lightweight web framework, giving developers far more choice as to what technologies to use to implement the various components of a web application. However, developers must do more work in terms of choosing and integrating these components.

To write a web application using Flask, a developer:

  1. Writes Python code that handles HTTP requests and prepares HTTP responses. This code can interact with databases and populate templates with data.

  2. Writes templates, HTML fragments that can be populated with data. Flask supports the popular Jinja2 templating language.

PyMongo can be used to interact with MongoDB. A short example is given in the blog post A basic web app using Flask and MongoDB (2013).

There are toolkits available to make it easier to use MongoDB with Flask:

Product

Current release

Licence

Comments

MongoKit

0.9.11

February 2014

BSD 3-clause

A Python Object-Document Mapper for MongoDB built on PyMongo.

One of Flask's deployment patterns is to use MongoKit in Flask.

Flask-PyMongo

0.5.0

May 2017

BSD 2-clause

A wrapper for PyMongo to allow Flask to configure and connect to MongoDB and to provide access to MongoDB within Flask's HTTP request handlers.

Flask-MongoEngine

0.9.3

May 2017

MIT

A Flask extension that integrates Flask with mongoengine (Current release 0.14.0, May 2017, MIT licence) Python Object-Document Mapper to interact with MongoDB.

Pyramid

Like Flask, Pyramid is a lightweight web framework. To write a web application using Pyramid, a developer:

  1. Writes Python code that handles HTTP requests and prepares HTTP responses. This code can interact with databases and populate templates with data.

  2. Writes templates, HTML fragments that can be populated with data. Pyramid supports the Chameleon, Jinja2, and Mako templating languages.

MongoDB and Pyramid in the Pyramid Community Cookbook describes how to provide access to MongoDB within Pyramid's HTTP request handlers

MongoKit, mentioned within the context of Flask above, can also be used from within Pyramid.

If it was me...

If I was to have to make a choice, I'd would initially look at both TurboGears (as it comes with built-in MongoDB support) and Flask (as it is more lightweight, allowing for more experimentation with various options for integration with MongoDB).

I would spend a couple of days on each to assess how easy the frameworks are to install, configure, deploy under Apache, and use. I would also assess the quality of their documentation and supporting resources. I would look at the ease which which I could rapidly prototype a web form that:

  • Accesses and renders MongoDB data.

  • Accesses MongoDB data, performs some calculations and renders the results.

  • Updates MongoDB data.

From these experiences, I would then select the web framework I would want to proceed with to use as a basis for my web application.

Further reading and resources

Full Stack Python provides an introduction to Python Web frameworks for developing web applications, including the above 4 frameworks.

For a more detailed comparison of Django, Flask and Pyramid, looking at building a simple application using each of these frameworks, see Ryan Brown's Django vs Flask vs Pyramid: Choosing a Python Web Framework (2016).

A comprehensive list of web frameworks is maintained on the Python wiki, Web Frameworks for Python (last updated August 2017).

Posted by r.silva on 27 November 2017 - 9:00am