Disclaimer and Warning: The following is indiluted and unmitigated personally biased advocacy.

Why Grok instead of all the other frameworks out there?  Why not Django or Flask?  Why even Python for that matter?  Why not simply adopt Node.js and have done with it all?  What is it about Grok that prevents you from migrating to an alternative back-end web platform?

As a continuing user (not developer) of the Grok and Zope technology, some of the features have become essential to me, and argue strongly against my adopting alternate frameworks for personal use.  What are they?

  • Right up there in first place has to be the Zope component architecture.  This is an amazing time saver and has many uses outside of the Grok framework.
  • Zope Page Templates or Chamelion for HTML templates.  Being able to write page templates as plain old HTML is an absolute winner for me.
  • ZODB for simple sites.  A built-in database from the get-go is another huge time saver. (certainly not abandoned, and actively developed and maintained)
  • Traversal.  Once one understands how adaptive traversal can be, there can be no other way to structure a site!
  • Simple REST, JSON and XMLRPC (Soap) extensions.
  • Vocabularies - I cannot think of another framework that provides this sort of ease or flexibility for populating dropdown lists or choices.
  • Brevity.  You can do most things with surprisingly little code.
  • Transparent use of SqlAlchemy, with reflected tables lets one maintain table definitions in SQL where they belong, and not in Python code. The Python classes representing these tables are automatically populated at startup- along with table dependencies.  So there is no "database<->code.py synchronisaton" required when a database schema changes, and new fields become new attributes in a class without anything having to be done.  Reflection is seriously the only sane way to work with relational databases.
  • Modularity and code organisation.  My code can be organised as Python modules with no required dependencies. Because of the pluggable component oriented approach, there are no circular dependencies or imports.  This leads to really simple debugging and maintenance.
  • You can add to the above: simple skinning, really easy access control and pluggable authentication, extensibility of existing views and rock solid performance.

 As a mere user of Grok, I am allowed to have an opinion.  If I were a developer of Grok/Zope, I would be required to be super-critical.

So, why not Pyramid?  Does it not check all the boxes above?  Why, yes, I believe it does!

Except that Pyramid is, in the immortal words of it's author, "unopinionated".

Fact is, I like opinions.  Yes, I also like the freedom to choose between ZODB and SQLAlchemy, and perhaps to a lesser extent the freedom to use explicit routing rather than traversal for URL dispatch.  However, I especially like the simplicity of a framework telling me "this is how to do the thing unless you decide different".  Consider the infamous "hello world" example in 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__':
    with Configurator() as config:
        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()

Admittedly, the above is meant to describe exactly what Pyramid is doing to serve up the application, and so serves to explain the process the app server goes through in quite some detail.

It is, however, rather verbose.

Why should I care about the detail?

To build this simple app from scratch, rather than copy/paste from boilerplate code or generating from a scaffold, you need to know quite a lot of detail:

  • You need to know about make_server, Configurator and Response, where to import them from and what they do, how to use them and what functions they provide.
  • You need to know how and where to use config.add_route(), config.add_view() and config.make_wsgi_app().

It's rather easy to imagine all that explicit configuration (view and route specification) getting out of hand for very large applications, but Pyramid has this going for it: You always know precisely what it is doing, and there is no magic.

In this regard, Pyramid is similar to most other Python frameworks.

Compare the Grok equivalent hello world:

import grok

class App(grok.Model, grok.Application):
   ''' This is an application called "app" '''

class Index(grok.View):
   ''' This is the default view for "app" '''

   def render(self, who='Anonymous'):
      return """<p>Hello {}</p>""".format(who)

Let's compare the Grok example to Pyramid:

  • There's a fraction of the code in the Grok example (excluding comments, 5 lines vs. 12).
  • There's an implicit rather than explicit URL (magic).
  • The view is automatically configured (magic).
  • The detail about the server implementation is completely hidden (magic).
  • You need to know to make a class deriving from grok.Application for your model.
  • You need to know to call your default view 'index'.
  • Grok says "thou shalt use a class for a view and a class for thy model".  Grok has an opinion.
  • Need another application? write a new class deriving from grok.Application.  It's a bit less simple with Pyramid.

So essentially, where there is no magic with Pyramid, there is certainly some magic in the Grok example; however, the Grok magic greatly reduces boilerplate and thus the effort needed to produce, maintain and extend the app.  As your project grows, the magic provides many more features and capabilities to make your life as a developer easier.

Grok 4 Noobs

What are the nicest things about Zope & Grok?