5 big and powerful Python web frameworks

When you build a back end for a website or service, even one that seems modest at first glance, you may quickly find it’s anything but. Even a “simple” site turns out to be a hive of complexity. User management, data design, form submissions, security,—implementing all of that by hand gets tedious.

For those big web projects, when you know you will need everything plus the kitchen sink, it’s best to turn to a framework that comes with batteries (and chargers) included. Here are five heavyweight web frameworks for Python that come with all you need to build robust web applications and then some.

[ Also on InfoWorld: 8 great little Python web frameworks ]

CubicWeb

CubicWeb is billed as “a semantic web application framework that favors reuse and object-oriented design.” It’s an intriguing system—as noted by Rick Grehan when he reviewed it for InfoWorld back in 2011—that emphasizes the use of abstractions and reusable building blocks of code called “cubes.” In fact, CubicWeb might be too abstract or idiosyncratic for some developers, and its development speed and feature set lag other frameworks.

Cubes are software components that feature a schema (data model), entities (programming logic), and views. By assembling multiple cubes, each performing its own task, you can compose software applications by reusing your own code and the code of others.

At its core, CubicWeb provides basic scaffolding used by every web app: a “repository” for data connections and storage; a “web engine” for basic HTTP request/response and CRUD actions; and a schema for modeling data. All of this is described in Python class definitions.

To set up and manage instances of CubicWeb, you work with a command-line tool similar to the one used for Django. A built-in templating system lets you programmatically generate HTML output. You can also use a cube that provides tools for web UIs, such as that for the Bootstrap HTML framework.

Although CubicWeb supports Python 3 (since version 3.23), it does not appear to use Python 3’s native async functionality. A roundabout way to include async would be to use the cubicweb.pyramid module to use the Pyramid framework as the web server, and draw on a fork of Pyramid that uses async constructions. It’s also possible to perform tasks asynchronously with the cubicweb-worker cube. But anything more straightforward seems out of reach for now.

To fetch or manipulate persistent data in a CubicWeb app, you use Relation Query Language (RQL), which employs vaguely SQL-like syntax but is patterned after the W3C’s SparQL. CubicWeb’s justification for this is, again, abstraction: RQL provides a highly decoupled route to interrelate various data sources.

Because CubicWeb has a lot of dependencies, it’s best to use pip install to fetch them all. You may also have to perform a certain amount of manual tweaking on the local environment. This is in contrast to other frameworks where running pip install or dropping the framework’s code into a subfolder of another project is all that’s required. Or you could use a Docker container to get things running.

CubicWeb refers to its lengthy documentation as “the book.” The authors of the book have taken the time to explain CubicWeb’s unusual approach, demonstrate how to build some basic applications, include API references, and in general go out of their way to be specific.

CubicWeb remains under active, if slow, development. Plans for CubicWeb 4.0 have been mulled since 2012, but no timeline has yet been offered for delivering it.

Django

In the decade and change since Django first appeared, it has become one of Python’s most widely deployed frameworks for creating web applications. Django comes with most every battery you might need, making it more suitable for building big applications than small ones.

[ Also on InfoWorld: 7 sweet Python IDEs you might have missed ]

Django spent many years sitting at version 1.x. When Django 2.0 arrived in late 2017, it dropped compatibility with Python 2 in favor of Python 3.4 and up. Django 3.0, released in December 2019, requires Python 3.6 or better, and adds support for the new asynchronous ASGI standard for Python web applications.

A key part of Django’s appeal is deployment speed. Because Django includes so many pieces you need for developing the average web application, you can get moving quickly. Routing, URL parsing, database connectivity including an ORM (object-relational mapper), form validation, attack protections, and templating are all built-in.

You’ll find building blocks for most common web application scenarios. User management, for instance, is found on most websites, so Django offers it as a standard element. Instead of having to create your own system for tracking user accounts, sessions, passwords, log-ins/log-outs, admin permissions, and so on, Django provides those features natively. They can be used as-is or extended to encompass new use cases with minimal work.

Django has sane and safe defaults that help shield your web application from attack. When you place a variable in a page template, such as a string with HTML or JavaScript, the contents are not rendered literally unless you explicitly designate the instance of the variable as safe. This by itself eliminates many common cross-site scripting issues. If you want to perform form validation, you can use everything from simple CSRF protection to full-blown field-by-field validation mechanisms that return detailed error feedback.

A feature set as rich and broad as Django’s wouldn’t be much good without robust documentation to go with it. The Django documentation drills into every aspect of the framework from multiple angles. Working with Python 3 or other flavors of the language, doing security right, implementing common web application components (like sessions or pagination), generating sitemaps—they’re all covered. The APIs for each layer of the application—model, view, and template—are described in detail as well.

With great power, however, comes great complexity. Django applications have a reputation for being top-heavy, fraught with many moving parts. Even a simple Django app requires a fair amount of configuration to get running. If your goal is to do little more than set up a couple of simple REST endpoints, Django is almost certainly overkill.

Django also has its quirks. For instance, page templates cannot use callables. Example: You can pass {{user.name}} as a component in a template, but not {{user.getname()}}. It’s one of the ways Django ensures templates don’t inadvertently shoot you in the foot, but those constraints can be jarring if you’re not prepared for them. While there are workarounds, they tend to take a toll on performance.

As of version 3.0, Django has added support for asynchronous views. Unfortunately, there isn’t yet support for async in other parts of the Django stack, like the ORM. But you can deploy Django using ASGI to take full advantage of async views.