log in

Understanding Pyramid's root factory

Luke Breuer
2013-12-18 18:52 UTC

The glossary states:
The “root factory” of a Pyramid application is called on every request sent to the application. The root factory returns the traversal root of an application. It is conventionally named get_root. An application may supply a root factory to Pyramid during the construction of a Configurator. If a root factory is not supplied, the application uses a default root object. Use of the default root object is useful in application which use URL dispatch for all URL-to-view code mappings.

The traversal documentation indicates that the following is a useful default version of Root:
class Root(object):
    def __init__(self, request):

config = Configurator(root_factory=Root)

This, clearly, does nothing. Basic applications which use URL Dispatch might not need anything more.
In Understanding the Pyramid web framework, traversal is introduced. Traversal requires a root object, produced by a root factory. This root factory can come from two places:
  1. a call to Configurator, as indicated above
  2. pyramid.config.Configurator.add_route factory parameter

Here's the actual sequence:
  1. match an existing route, if one exists
  2. choose the route's factory, defaulting to the root_factory passed to the Configurator constructor
  3. attempt view lookup
  4. if view lookup fails, activate traversal on the factory found in 2.
Recall our very simple wiki rendering 'view':
def render_wiki_page(request):
    return "Welcome to page %s." % request.matchdict['title']

Let's say I want to require users to login to edit wiki pages. I would need to add permissions, like this:
@view_config(route_name='wiki_route', permission='edit')
def edit_wiki_page(request):
    return "Welcome to page %s." % request.matchdict['title']

The permission argument to the view_config decorator is a group permission; the groups get defined by our root_factory, or the factory returned from URL Dispatch (see 2., above).
class Root(object):
    __acl__ = [
        (Allow, 'g:editor', 'edit'),

    def __init__(self, request):
        self.request = request

At this point, head over to Understanding Pyramid authentication and authorization scheme.