Python frameworks can be divided into a few areas as Python is a very diverse language and can be used in various fields. Each of these fields has its own frameworks, some of which are more popular than others. One of the most popular fields Python is applied in is web development, which we will focus on today.
The presented frameworks can be broken down into three categories: full stack frameworks, which offer a lot of out of the box features for the server and client side; microframeworks, which offer server-side support (sometimes, they can be extended to the client side) and allow for creating a web application just by using a single Python file; and, finally, asynchronous frameworks, which handle requests asynchronously.
Django is one of the most popular Python frameworks. It offers a lot of out-of-the-box functionalities like Admin Panel or Generic Views and Forms. Django’s main characteristics are:
one managing script (“manage.py”) that can be used for performing most of the framework specific actions (like starting the development server, creating an admin user, collecting static files etc.),
synchronous request processing,
MTV (model-template-view) architecture pattern (which is variation of the model-view-controller pattern),
custom object-relational mapping (ORM) for communicating with the database,
usage of functions and classes for view context creation and action handling,
Django is strict and forces its own coding style on the developer – a lot of meta programming,
very good, extensive documentation with examples,
custom HTML templates rendering engine,
custom URL routing system,
compliance with the WSGI standard,
support for static files - URL routing as well as detection and collection,
a large number of external modules, e.g. Django REST Framework, Django CMS, Django Channels (websockets).
Django is a good fit for bigger projects, where extensive backend and frontend support is required or in cases where time plays a crucial role, as Django offers a large number of ready components. Coding in Django mostly relies on customizing generic parts of code. The developer must follow a set of rules that come with given element. For projects where a lot of code flexibility is desired, Django might not be the best choice.
Web2py focuses on security, development speed and ease of use. It offers a lot of features out of the box: a web server, database, admin panel, wiki or grid widgets. Framework main characteristics are:
synchronous request processing,
custom Database Abstraction Layer (DAL) that acts as ORM,
forces an MVC structure,
functions and classes can be used for creating Controllers,
strict “There should be only one way of doing things” philosophy,
rich documentation with a lot of examples,
custom HTML engine that allows Python code to be used in the templates,
custom routing - URL function that generates internal paths for the actions and static files,
support for the WSGI standard, but it’s possible to use CGI (Common Gateway Interface), FastCGI, GAE (Google App Engine) or other,
offers static file routing and streaming during development,
has built-in REST services but requires the Tornado framework for Web Socket usage.
Web2py was highly inspired by Ruby on Rails and Django frameworks and takes what’s the best from both of them. It can be a good choice for programmers who want to migrate from Ruby or for ones that are bored with Django but are looking for another big and feature-rich framework. It offers an “admin” app, which acts as a web-based IDE for application development and management (e.g. app creations, code editor). It is also supported by PyCharm. In general, Web2Py doesn’t lack any functionalities that Django has. These two frameworks can be used to fulfil the same tasks. Web2Py is younger, and it has a smaller community than Django, so it might be a little harder to find help in case of trouble.
TurboGears connects a lot of external services to create one functional framework:
synchronous request processing,
model-view-controller (MVC) pattern,
uses SQLAlchemy ORM,
allows for the usage of functions and class view context generation,
it offers some ready-for-use generic classes (very interesting APIController for REST API creation),
documentation is a little bit chaotic but it might be a matter of getting used to it,
uses the Kajiki template language,
custom URL routing/dispatch methods,
compliant with the WSGI standard,
supports static files path configurations
can be extended with additional modules, e.g. Circus and Chaussette for Web Sockets support.
The framework is not as popular as it’s two predecessors but nonetheless it’s worth checking out.
It’s one of the most popular Python microframeworks, it’s reliable and fast. It is said that it was created as a joke. The main characteristics of the framework are:
synchronous request support,
doesn’t force any project architecture, but has some recommendations (package, module, blueprints),
it doesn’t offer ORM, but SQLAlchemy or other can be used,
supports functions as well as some Django-like generic class views (starting from Flask 0.7),
loose coding style, it doesn’t force any solutions, most decisions are left to the developer’s discretion,
good documentation with examples,
it’s possible to use Jinja2 HTML Template engine,
Werkzeug routing system,
compliant with the WSGI standard,
supports basic static file routing,
can be extended with some additional third-party modules, e.g. Flask-RESTful for REST API creation or flask-socketio for Web Sockets Support.
This framework will do the trick in small and medium projects. It has some third-party modules that are ready to be used as well as good native solutions. Flask should prove itself in jobs where complicated custom features are required but Django seems too big for the task. On the other hand, setting Flask for a bigger project from the beginning can be tricky as there is no “official” way of doing so.
Pyramid starts with a minimal installation that can be extended when needed. It’s worth noting that it’s a part of the Pylons project, which integrates web-related technologies. These are some of Pyramid’s most important characteristics:
offers synchronous request processing,
views contexts can be defined with functions as well as classes,
there is no specific ORM but SQLAlchemy is recommended,
doesn’t force any coding style or project architecture – TIMTOWTDI,
offers good documentation with tutorials and examples,
no specific HTML template engine is delivered but Chameleon is recommended,
an interesting custom routing system allows multiple views to match one URL,
it’s WSGI compliant,
extensive static files support – files serving, URL routing for static files,
This framework might be a good choice in cases when you don’t want to spend time learning custom frameworks solutions (like ORM) but still need an extensive tool for building software, as Pyramid supports usage of many well-known stand-alone solutions. It has good scaling capabilities – advertises itself as a framework that can “start small and finish big”.
Allows creation of web application in the same way as object-oriented Python project. It has no full-stack functionalities and doesn’t force any specific solutions – the developer can decide how to solve problems that occur during development. CherryPy’s features are:
offers synchronous request support,
doesn’t force any project structure or architecture,
doesn’t deliver any ORM, but SQLAlchemy or SQLObject can be used,
doesn’t deliver any HTML template engine,
has a loose coding style,
offers decent documentation,
is compliant with WSGI,
has good support for static files – allows for serving files or whole file directories,
allows the creation of REST APIs with built-in tools only,
facilitates the use of Web Sockets via the ws4py module.
The main advantage of CherryPy is that it comes with a production-ready WSGI server, which removes the necessity of setting up an external server during deployment. The main drawback of this framework is that it isn’t very popular, hence it has a smaller number of external modules and a less vibrant community.
It’s yet another microframework that advertises itself as fast and simple. It’s worth noting that BottlePy is delivered as a single module with no additional dependencies. The features:
implements synchronous request handling,
offers custom HTML engine but other engines such as Mako, Jinja2 or Cheetah could be used,
doesn’t deliver ORM but it’s possible to use external solutions, e.g. SQLAlchemy or Macaron,
doesn’t force any project architecture,
offers sufficient documentation,
has a custom routing system but Werkzeug routing system can be used (via bottle-werkzeug),
implements WSGI standard,
offers basic static file routing,
offers greenlets (with gevent) as asynchronous request handling solution,
it’s possible to create REST API without external modules – supports JSON client data.
Due to its small size (just one file) and no external dependencies (Python standard library only) required, it can be a good choice for beginners who want to start learning web development. It might also do a good job with very small sites or disposable tests. BottlePy won’t be the best choice for medium-sized or bigger projects, as it would require some work to get to the point where heavier frameworks start.
It’s an extensive async Python framework. It offers a server with middleware, signals, graceful shutdowns and many more:
asynchronous request handling, client and server websockets,
it’s possible to use GINO async ORM,
supports function and class-based views,
sufficient documentation but a little hard to navigate,
it’s possible to use pure SQLAlchemy but GINO as an async wrapper is recommended,
supports Postgres, MySQL, Redis async drivers,
no out-of-the-box template engine but Jinja2 or Mako could be applied,
custom routing system,
no WSGI support,
supports routing for static files,
As it offers a lot of features out of the box (e.g. support for client and server sides, websockets, middleware, signals), Aiohttp might be used with medium-sized projects (or even with bigger ones).
Sanic is a very flask-like framework: it’s small, liberal, and leaves a lot of space for the developer. Its main defining feature is its speed. Here are some other characteristics:
support for async request handler,
doesn’t offer any database interfaces but GINO async ORM can be installed,
offers function and class as the source of view context,
coding style is rather loose, very similar to Flask,
documentation delivered with “readthedocs”,
Jinja2 HTML template engine can be used,
custom made routing system,
is not WSGI compliant by default but a third-party module (sanic-dispatcher) can be installed to support it,
has basic static file routing,
can be extended with additional modules, e.g. Sanic CRUD for REST API creation.
It should be a good decision to choose Sanic when you’ve already had some experience with Flask, as these two frameworks have a lot in common. Sanic offers default configuration handling, while in aiohttp mentioned before, the user needs to do it on their own. It has some interesting third-party modules such as a request rate limiter or a GraphQL integration.
Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed (a social aggregation site). Thanks to that, it offers a built-in integration with social services such as Google, Facebook, and Twitter. The integration with other frameworks and libraries is also possible: Twisted, asyncio or even WSGI applications. Tornado’s features:
offers a lot of generic classes that can be used for creating the application, e.g. Router, or SocketHandler for websockets,
custom HTML template engine,
clear and easy-to-read documentation,
functions and classes can be used for defining actions and handling requests,
custom routing handling – offers generic classes than can be used for route creation,
it supports WSGI, but it’s not recommended – the user should use Tornado’s own interfaces instead,
out-of-the-box websockets support, authentication (e.g. via Google), and security features (like cookie signing or XSRF protection),
no additional tools are needed for REST API creation.
The framework should work well in cases where there are a lot of incoming connections that can be handled quickly or in real-time solutions, e.g. chats. Tornado tries to solve the c10k problem so high processing speed is a priority. Another advantage of Tornado is its native support for social services. This framework won’t be a good choice for creating standard CRUD sites or big business applications, as it wasn’t designed to be used that way. For bigger projects, it can be integrated with WSGI applications as a part of their bigger structure and take care of tasks that require high handling speeds.
The web frameworks presented above are merely a small chunk of a bigger and broader family of Python frameworks. Each solution has its strong and weak points and, as with everything else, there is no perfect match that will solve every given task. The most important questions that one has to answer when choosing the framework are dictated by problems that need to be solved. If extensive support on the server and browser side is required, then a full-stack framework might be a good choice. For smaller projects or where the flexibility in writing code is a priority, a microframework can be the way to go. In cases where request processing speed plays an important role or a project will have to deal with long response times, asynchronous framework should do the trick.