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.
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.
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.
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.
In the world of Ruby programming, Ruby on Rails is the de facto web framework. DePaul University computer science professor Massimo Di Pierro was inspired by Rails to create a web framework in Python that was similarly easy to set up and use. The result is Web2py.
Web2py’s biggest attraction is its built-in development environment. When you set up an instance of Web2py, you’re provided with a web interface, essentially an online Python application editor, where you can configure the app’s components. This typically means creating models, views, and controllers, each described via Python modules or HTML templates. A few example apps come with Web2py out of the box. You can take those apart to see how they work or leverage them as starter templates to create your own apps.
Developers typically deploy Web2py by downloading its source code and building on that. But for less technical users on Windows or MacOS, Web2py’s creators offer versions that are essentially standalone servers. Download, unpack, and run one of these versions, and you’ll have a local web server with a preconfigured copy of Web2py built-in. This is a nice way to get a leg up on creating a Web2py app, which can then be deployed elsewhere as needed.
Web2py’s web interface was built with Bootstrap 4, so it’s easy on the eyes and easy to navigate. The in-browser editor is no substitute for a full-blown IDE, but it’s outfitted with helpful aids like line numbering and Python syntax highlighting (including auto-indentation). Also included is a quick web interface to the Python shell, so you can interact with Web2py from the command line—a nice concession to experts.
The data abstraction system used in Web2py works a little differently from Django’s ORM and other ORMs inspired by it (such as Peewee). Those systems use Python classes to define models, whereas Web2py uses constructor functions like
define_table to instantiate models. The differences are likely to be jarring only if you’re used to the other way; they shouldn’t faze newcomers. You’re not likely to have any trouble with hitching Web2py to a data provider, as it talks to nearly every major database in existence.
Weppy feels like a halfway mark between the minimal simplicity of Flask and the completeness of Django. While developing a Weppy app has the straightforwardness of Flash, Weppy comes with many features found in Django, like data layers and authentication. Thus, Weppy is suited to apps that range from extremely simple to modestly sophisticated.
At first glance, Weppy code looks a great deal like Flask code or Bottle code. Few instructions are needed to get a basic, single-route website up and running. Routes can be described through function decorators (the easy way) or programmatically, and the syntax for doing so hews closely to Flask/Bottle. Templating works about the same, aside from minor variations in syntax.
Weppy contrasts with those smaller frameworks by including some features they incorporate only as plug-ins or add-ons. For instance, neither Flask nor Bottle has a built-in ORM or a data management system. Weppy includes an ORM, albeit one based on the pyDAL project rather than the far more popular SQLAlchemy. Weppy even supports schema migrations, which Django supports as part of its ORM (Django’s migration system is also a great deal more automated). While Weppy has an extension mechanism, the list of officially approved add-ons is tiny, far smaller than the catalog of extensions for Flask.
Lighter-weight frameworks like Weppy are often used to build RESTful APIs, and Weppy comes outfitted with convenience functions for that purpose. Put a
@service decorator on a route, and the data you return is automatically formatted in your choice of JSON or XML.
Weppy includes other features that seem more in line with a larger framework, but are implemented without bulk. Examples include data validation mechanisms, form handling, response caching, and user validation. In all of these cases, Weppy takes a “just enough” approach. The features provided aren’t as complete as you might find in Django and other heavyweight frameworks, but a developer doesn’t need to invest a lot of work in making them useful, and they can always be extended after the fact.
Zope is not for simple RESTful APIs (per Bottle or Flask) or even basic websites with interactivity (à la Django). Rather, Zope is meant to be a full-blown, enterprise-grade application server stack, similar to server offerings for Java. The documentation describes the framework as “most useful for component developers, integrators, and web designers.” One major third-party product, the Plone CMS, uses Zope as its substrate and serves as a major driver of Zope’s continued development.
Zope works by taking requests from the web, matching the parameters of the request against an internal object database (ZODB), and executing that object using the request’s
POST parameters. Whatever comes back from the object is returned to the client. Zope uses this database-object system to simplify tasks like assigning granular object permissions, providing inheritance hierarchies for objects, and handling transactions and rollbacks for database objects.
Templates can be handled using the new and more flexible Zope Page Templates (ZPT) system, or the older and more basic DTML markup system. ZPT uses properties within HTML tags to indicate where to place data, making it easier to design templates using conventional HTML tools. But the ZPT syntax takes some getting used to.
One of the advantages Zope claims for its object-oriented methodology is that every action in the system, no matter what sort of object it acts on, is encapsulated by a transaction. Thus, if you delete a file stored in Zope’s database or make a destructive change to a piece of code, you need only roll back the action that performed it.
The downside of Zope’s approach is that it’s hard to use modern source-control tools like Git on such a codebase, and it means you’re putting the data at the mercy of Zope’s custom database tools. Note that you can connect an external database like MySQL to a Zope application, but that’s strictly for hosting application data, not for replacing the ZODB.
Another downside to Zope, at least in its current form, is no direct support for Python’s async syntax. However, the zc.async package allows you to distribute tasks across machines and synchronize them in a ZODB instance.