darkness

Monday, 23 April 2007

A Pylons/Genshi skeleton from scratch

darkness @ 15:33:27

There are a billion other sites that tell you how to do this. Still, I hope this page will at least be useful to me in the future when I want to quickly make a “web application” with Pylons.

I use virtual-python.py to make a private Python installation. This way I don’t have to worry about touching system files, mucking up libraries other applications need, etc.

~ $ cd tmp
tmp $ wget --quiet http://peak.telecommunity.com/dist/virtual-python.py
tmp $ mkdir myapp
tmp $ cd myapp
myapp $ python ../virtual-python.py --prefix=$PWD/py
Creating /home/darkness/tmp/myapp/py/lib/python2.4
Creating /home/darkness/tmp/myapp/py/lib/python2.4/site-packages
Creating /home/darkness/tmp/myapp/py/include/python2.4
Creating /home/darkness/tmp/myapp/py/bin
Copying /usr/bin/python to /home/darkness/tmp/myapp/py/bin
You're now ready to download ez_setup.py, and run
/home/darkness/tmp/myapp/py/bin/python ez_setup.py

Install all the basics. easy_install is noisy, and Pylons pulls in a bunch of stuff, so I’ve trimmed the output considerably. (Also, I used ez_setup -U setuptools below because I’ve got the Fedora package python-setuptools installed, but it’s not the latest version (I think). You may or may not need -U; I don’t know if -U causes errors if the package isn’t already installed.)

myapp $ wget --quiet http://peak.telecommunity.com/dist/ez_setup.py
myapp $ py/bin/python ez_setup.py -U setuptools
Installed /home/darkness/tmp/myapp/py/lib/python2.4/site-packages/setuptools-0.6c5-py2.4.egg
myapp $ py/bin/easy_install Pylons Genshi Buffet
Installed /home/darkness/tmp/myapp/py/lib/python2.4/site-packages/Pylons-0.9.5-py2.4.egg
[ Omitted a bunch of packages installed for Pylons: Mako, nose,
  decorator, simplejson, FormEncode, Myghty, PasteScript, PasteDeploy,
  Paste, Beaker, WebHelpers, Routes, MyghtyUtils ]
Installed /home/darkness/tmp/myapp/py/lib/python2.4/site-packages/Genshi-0.4-py2.4.egg
Installed /home/darkness/tmp/myapp/py/lib/python2.4/site-packages/Buffet-1.0-py2.4.egg

Now I create my application.

myapp $ py/bin/paster create -t pylons myapp
Selected and implied templates:
  Pylons#pylons  Pylons application template

Variables:
  egg:      myapp
  package:  myapp
  project:  myapp
Creating template pylons
Creating directory ./myapp
[ ... whole bunch of stuff happens to install the template ... ]
myapp $ cd myapp

Note the directory structure is weird:

  • ~/tmp/myapp is where I made my virtual Python.
  • ~/tmp/myapp/myapp is the directory paster created. It is now basically the root of your project: it contains the configuration files, setup.py, ez_setup, and…
  • ~/tmp/myapp/myapp/myapp is your new web application as a Python package named myapp.

Now I want to set Genshi as the default template engine. http://docs.pythonweb.org/display/pylonscookbook/Genshi+templates has a good recipe for this (and more): edit myapp/config/middleware and add template_engine='genshi' to the config.init_app(...) call. (Remember myapp here refers to ~/tmp/myapp/myapp/myapp! Think myapp.config.middleware if it helps.)

To test this, I recommend a small modification to controllers/template.py. Make it read something like:

myapp $ cat myapp/controllers/template.py
from myapp.lib.base import *

class TemplateController(BaseController):
def view(self, url):
    """
    [omitted long docstring]
    """
    if g.pylons_config.app_conf.get("debug", True):
            return render_response(url)
    else:
            abort(404)

WARNING! This will happily try to display any template based on the path given in the HTTP request, if there is no better match (i.e., a controller)! It assumes debug is on if it’s not set! This seems to be the default behavior in Pylons in general (see development.ini which requires you to uncomment debug when you put an application into production). Feel free to change True to False and set debug = true in development.ini instead.

To see what I mean when I say it will “happy try to display any template,” lets make a Genshi template and view it. Your templates directory needs to be a Python package for Genshi to use it, hence the __init__.py.

myapp $ touch myapp/templates/__init__.py
myapp $ cat > myapp/templates/test.html
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:py="http://genshi.edgewall.org/">
    <head>
        <title>This is a test</title>
    </head>
    <body>
        <p>
            This is a test: ${7 * 6} should be 42.
        </p>
    </body>
</html>
^D

We’ll start Pylons with the development.ini configuration file, and in auto-reload mode. This is how I use it most of the time when I’m hacking on a Pylons application. (I’m going to symlink the virtual Python root (py) into ~/tmp/myapp/myapp since ~/tmp/myapp isn’t real useful now. If I weren’t so lazy I’d just change ~/tmp/myapp/myapp to be ~/tmp/myapp.)

myapp $ ln -s ../py .
myapp $ py/bin/paster serve --reload development.ini
Starting subprocess with file monitor
Starting server in PID 29673.
serving on 0.0.0.0:5000 view at http://127.0.0.1:5000
# Elsewhere...
~ $ lynx --dump http://localhost:5000/test

   This is a test: 42 should be 42.

Note that, because of my changes to myapp.controllers.template, Pylons happily served up the template named test. So if you use the above changes to the template controller, be very careful who gets to hit the Pylons server when debug is not False.

Powered by WordPress