Pyramid Par Deux: Let's program in Python

Let's program man, I'm sick of this command line stuff. I only learned it in Uni because they made me! I like my pretty Mac UI.

Okay okay, I hear you, though I disagree with you because iTerm with Solarized is extremely pretty. Let's open some code. I hope you're using Sublime Text 2. If not, get it. Then come back. Thank me later.

Have a look through your new package. The important stuff will be inside your module directory. Something like:

ll shelves/shelves/
__init__.py
static
templates
tests.py
views.py

This is pretty easy to understand. The __init__.py is a built in Python package tool. It will initialise this package and is in no way unique to Pyramid. It's a python tool. All code you need for ANYTHING within the package should go in there. It's basically the class constructor for an entire package. With a Pyramid app it's also used to write your init code for booting up and running your web server (using WSGI). Here is the default code, which I will explain:

from pyramid.config import Configurator

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    config = Configurator(settings=settings)
    config.add_static_view('static', 'static', cache_max_age=3600)
    config.add_route('home', '/')
    config.scan()
    return config.make_wsgi_app()

We can go through each line as they are all simple enough:

config = Configurator(settings=settings)

Create a Pryamd config object with the settings passed from your paste deploy script (e.g. development.ini) which tell Pyramid a lot of things.

config.add_static_view('static', 'static', cache_max_age=3600)

This is very useful as it quickly creates a static view for a directory and all the static files within. This setup here is for a folder we'll see below which we use to store images, javascript, css, fonts and more inside. This will translate directly to http://yourapp.com/static/ which means you can link to a css file at http://yourapp.com/static/css/styles.css which you would find in your shelves/static/css/ directory… phew. It'll make sense if you play with it!

config.add_route('home', '/')

This method adds a normal routing called home which you attach to a view in a different file (though it doesn't need to be in another file) for all requests at / the standard starting route for all websites. Routing is important and is pretty simple. Might write about it later! If you've used any other routing tools (Rails, or mod_rewrite) you're not far off.

config.scan()
return config.make_wsgi_app()

That last two lines run through all your code looking for decorators and other bits and pieces (like attaching views to a route which we will see later) and then simply launching your WSGI app through Pyramid and have it starting listening for requests.

Then we have static which is the default location for all static files. JS, images, LESS, etc. I generally go in there and remove everything and setup some useful structure.

cd static
rm -rf ./*
mkdir scripts stylesheets images stylesheets/less

Next we have templates which is a director for all templates. By default there is a single TAL based template called mytemplate.pt. I hate TAL for a number of reasons so I automatically delete that and create a MAKO template. It's like TWIG or something like that.

rm mytemplate.pt
touch master.mako

These are template files for use with a template engine. You can read more about them elsewhere but they basically allow you to drop strings from Python into your file. You probably have seen them before. Think Smarty, think Twig, thing ERB. Whatever.

FINALLY. Some actual useful website building Python code. tests.py. Bleh right? This is a simple testing file which you can use to test your web app. This is super useful, this is super important. This we will look at later as it's somewhat pointless to test code you've not written yet. You can run it just to make sure the scaffold worked though!

Views in the views.py file, our first attempt at Pyramid python code.

So here we are… 3 lines? Really?

@view_config(route_name='home', renderer='templates/mytemplate.pt')
def my_view(request):
    return {'project':'shelves'}

This is simple. It creates a view (if you don't understand MVC, go read elsewhere for now. This article is long enough!) for your project. That means we handle an HTTP request (which is passed as the only argument) + return a response. It's a little confusing as there is no response there. It's actually using the @view_config code to build the response for you. This is a little note at the top of a method (this decorators are common Python) which quickly configs the following method. In this case we give the route a name ('home' which links it to the route we saw built in the __init__.py method above!) and a renderer which is simply the filename of the template.

The next two lines are the function definition which returns a dictionary of values which are passed directly to your template giving you access to the data you need to pass the page.

This method is where all your business logic goes. We would write form handling in here, pulling records based on user request, the latest blog posts, etc.

There you have it. A simple introduction for creating basic web request apps using Python and Pyramid. The last missing piece not discussed are the Models of your code, however there are two largely different types that depending on the DB Schema system you want to use (SQLAlchmy or ZODB) so I'll leave that until my next post!