Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

codeA guest post by Wayne Witzel III who resides in Florida and is currently working for Slashdot Media as a Senior Software Engineer building backend systems using Python, Pylons, mongodb, and solr. He can be reached at @wwitzel3.

Pyramid, an unopinionated Python web framework, by its very nature, does not attempt to enforce a specific way for laying out and developing your application. That said, there are some idioms you can follow to ensure that as you build your application it stays maintainable and easy to test.

Request Attributes

One thing you will notice when using Pyramid is that the request object is explicitly passed around to where it is needed. This makes it a great place for objects that you commonly use with each request. As of Pyramid 1.4 there is a great Configurator method: add_request_attribute(). This method makes it easy to add custom request object attributes. Here is a simple example of using this method to attach your database session to the request as an attribute.

First we create our engine and setup our metadata bindings:

Now we create a simple callback method and pass it to add_request_attribute. We also pass the string name, which is the desired attribute name. reify=True, which we also pass, ensures that the result of evaluating get_db is cached for the life of the request:

Now anywhere we have access to our request object, which can be views or other request attributes, we also have access to our database session via the request.db attribute.

Creating Components

Creating a component in Pyramid is as easy as defining an includeme callable. This convention is used by Configurator.include(), which supports being called with an actual module or a dotted path.

Again, any standard Python module or file can be made to support being used with a Pyramid Configurator object by defining an includeme callable. For example, it is common to separate the functional areas for your application in to different Python modules. We can then define an includeme method in the __init__.py for the module to setup any special things we might need.

pinto is a very simple blogging application created using Pyramid for the purpose of demonstrating this convention. pinto builds components for each of the different functions of the application. Then it includes each component within the application’s main method to build out the entire set of features. The result is a very clean and simple main method, with things setting up routes or adding custom request attributes living off in their own dedicated modules.

To show you an example of what this looks like, I want to take a look at the post component of the pinto application. post will be tasked with creating the routes and views for the CRUD part of our blogging system.

Here we see the post/__init__.py file.

All we’ve done to make this post component includable is to ensure that the __init__.py file defines the includeme callable that accepts a Configurator object. And inside, we went ahead and called config.include and included another path, pinto.post.routes. So lets examine that package.

pinto.post.routes isn’t a directory this time. post/routes.py is just a plain old Python file that defines an includeme callable. I have been purposefully emphasizing that includeme is just a callable and there is no magic going on here. It really is just that simple.

So here we have defined our routes, and we have our views decorated in another file using view_config. Now the last step involves our application’s main method, since we want to include the post component we just created. Here is what it looks like along side the other components.

Now we have access to the post routes in our application. You will notice a route_prefix that we have not seen before. This handy parameter ensures that any add_route calls that might call the include, are prefixed with the value of route_prefix. In our case this means that the three routes we defined in post.routes will look like this:

This is great because it allows us to create URLs that are intuitive and make sense in the context of the individual component, and later give them meaning in the context of the entire application using a route_prefix.

Benefits of Components

There are a couple benefits to structuring your applications in this fashion. First, following the includeme convention and using this approach to separate the areas of function for your application will provide you with this ability to easily extend and replace pieces of your application without having to perform Shotgun surgery, which is so common when maintaining many applications.

Second, there is a benefit when it comes time to write tests. You are able to bootstrap the individual components of your application, making it much easier to create component tests. This means you can do things like easily making sure that a components routes are available for testing without having to duplicate them in your test.

You can see, by defining our routes inside an includeme callable, we can also easily add them where we need to for testing. We also do not have to worry about updating our add_route calls in our tests, should we need to make changes to routes.

Conclusion

I encourage you to continue on in this space, and to look at the pinto code base as well as the notaliens.com code base. Both are great examples of how to structure Pyramid applications in a way that ensures they are extensible, maintainable, and testable. I also recommend you read the Extending An Existing Pyramid Application section of the Pyramid documentation.

For more details about Python, see the Safari Books Online resources referenced below.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Think Python takes you through the language one step at a time, beginning with basic programming concepts before moving on to functions, recursion, data structures, and object-oriented design. Through exercises in each chapter, you’ll try out programming concepts as you learn them.
Violent Python shows you how to move from a theoretical understanding of offensive computing concepts to a practical implementation. This book demonstrates how to write Python scripts to automate large-scale network attacks, extract metadata, and investigate forensic artifacts. It also shows how to write code to intercept and analyze network traffic using Python, craft and spoof wireless frames to attack wireless and Bluetooth devices, and how to data-mine popular social media websites and evade modern anti-virus.
Hello! Python fully covers the building blocks of Python programming and gives you a gentle introduction to more advanced topics such as object-oriented programming, functional programming, network programming, and program design. New (or nearly new) programmers will learn most of what they need to know to start using Python immediately.

Tags: Components, Configurator, Pyramid, Python, testing, web framework,

2 Responses to “Building Pyramid Applications”

  1. Sascha Gottfried

    Hi Wayne,

    tried your example today. Turns out there is no config.add_request_attribute() function. May be a typo. But docs mentions ‘config.add_request_method()’ Please fix your code.
    Besides that, very good recommendations and well written.

    config.add_request_method(get_db, ‘db’, reify=True)

  2. Wayne Witzel III

    Hi Sascha,

    You are right, must of been some pre-1.4 creeping in to my brain when I wrote it. Nice catch, I will get it updated. Thank you.