Python Paste Power 6

Posted by ben Tue, 04 Oct 2005 23:52:36 GMT

Mmm, tasty, a headline of P-word’s. Recently Ian Bicking went on a bit of a release spree with a whole bunch of goodness that I’m way too lazy to link to in this paragraph. The ones I’ve been waiting for were all in the line-up: Paste, Paste Script, and Paste Deploy. I blogged about paste and setuptools earlier and hadn’t followed up as I indicated I would partly because I was waiting on their official release.

So, what’s the big deal? Paste and its buddies solve a host of issues that commonly confront Python web developers and web administrators, the front page of Python Paste does a good job of explaining briefly why each group should care. Thus, I’ll move directly onto the fun that comes with using them.

Yes, I think its fun, but that might be just because I have a thing for installing web frameworks…. so I’ll cover using Paste as two groups of users, as a Web Developer, and as a Web Administrator.

Using Paste as a Web Developer

First off, to create a web application we need to setup a directory for the project. Since we want our web application to be Paste-enabled, the template for the web application should be using setuptools. That way when we package up our web application and give/sell it on the Internet, the people (Web Admins) using it will be able to install and run it easily.

So… lets see what framework I should use to whip up this little web application. I’ll run a paster command that lets me see what Paste-enabled web frameworks I have installed that come with new web application directory templates:

% paster create --list-templates
Available templates:
  basic_package:            A basic setuptools-enabled package
  myghty_modulecomponents:  Module Component Template
  myghty_routes:            Routes Template
  myghty_simple:            Simple Template
  paste_deploy:             A web application deployed through paste.deploy
  pylons:                   Pylons application template
  turbogears:               TurboGear application template

Cool, right? Well, maybe its just cause I like having a big toolbelt of web frameworks sitting around. Obviously not a lot of web frameworks have paste templates available yet, but more are adding support and I’ll be rather excited when that list is 20 or more long.

If you go and install the Paste packages, your list won’t be quite as long as mine (insert evil laugh) as I’m running the CVS of Myghty (0.99 release with these templates coming shortly), along with some other stuff I’ve whipped up. Merely installing a web framework package that’s Paste-enabled and has templates available will make it show up in that list.

Another interesting thing to consider here, is that there’s no requirement that only web frameworks are allowed to create directory templates. Maybe a web application you’re working on, is so powerful you want to make it easy for end-users to extend it with their own custom add-ons. You could provide a paster template that creates a plug-in ready directory template for custom themes. There’s a ton of power packed in the various ways you can extend these tools, building on the dynamic discovery stuff in setuptools.

Moving along though, I’ll go ahead and use Turbogears.

% paster create --template=turbogears pygo
Selected and implied templates:
  TurboPaste#turbogears  TurboGear application template

Variables:
  package:  pygo
  project:  pygo
Creating template turbogears
  Creating ./pygo/
  Recursing into +package+
    Creating ./pygo/pygo/
    Copying __init__.py to ./pygo/pygo/__init__.py
    Copying model.py to ./pygo/pygo/model.py
    Recursing into templates
      Creating ./pygo/pygo/templates/
      Copying __init__.py to ./pygo/pygo/templates/__init__.py
  Copying +package+-start.py_tmpl to ./pygo/pygo-start.py
  Copying dev.cfg_tmpl to ./pygo/dev.cfg
  Copying prod.cfg to ./pygo/prod.cfg
  Copying setup.py_tmpl to ./pygo/setup.py
Running /opt/local/bin/python setup.py egg_info

As you can see, it just setup our new project for us, which I called pygo because it was the first name that popped into my head. If you’ve actually used TurboGears, looking at that should have raised some red flags as its missing a bunch of stuff that a TurboGears project needs. This is mainly because the template was created by Ian as a demonstration of how to make a Turbogears-style template. Hopefully an upcoming version of TurboGears will be Paste-enabled so I can create a new project like this (hint hint). :)

Ah well, I’ll just make a basic Myghty project using Routes instead:

% paster create --template=myghty_routes pygo
Selected and implied templates:
  Myghty#myghty_routes  Routes Template

Variables:
  package:  pygo
  project:  pygo
Creating template myghty_routes
  Creating ./pygo/
...Bunch more files...
So that’s all there is to creating new projects with the web framework of your choice (if its Paste-enabled). How do we go and start it up?

~% cd pygo
~/pygo% paster serve server.conf 
Starting server in PID 6090.
In the case of the myghty_routes template, it starts the server on port 5000. A quick look at the server.conf file makes it obvious:

[server:main]
use = egg:PasteScript#wsgiutils
host = 127.0.0.1
port = 5000

[app:main]
use = egg:pygo#paste

That’s really all the Paste you have to worry about as a web developer (though it has even more capabilities you’ll probably want to use). We can see here that its using wsgiutils from PasteScript to run the server. You can easily swap that out for any of the server support that flup offers such Fast CGI, SCGI, or AJP.

At this point, as a web developer, you’d go ahead and create your web application. Especially since the default myghty_routes template is pretty boring if you don’t put anything in it. But for this example, we’ll assume its done and distribute it as a single egg file for people:

~/pygo% python setup.py bdist_egg
running bdist_egg
running egg_info
... whole bunch of stuff here...
~/pygo% ls dist/
pygo-0.0.0-py2.4.egg

That’s it. This is easy, right? You’re ready to go ahead and give your egg to anyone running Python 2.4 now (You could make a source distribution and upload it to Cheese Shop just as easily). So let’s try and totally forget that we’re a web developer, and assume a different role.

Using Paste as a Web Administrator

Ah yes, the joys of setting up web applications you come across. Well, I’ve rarely gotten any joy out of it at least. Let’s take a look at how Paste does make it a lot easier. First, we’ll need to install the insanely useful Pygo webapp that some other thoughtful user created. If this Pygo application was released and uploaded to the Cheese Shop, I could install it like so:

% sudo easy_install Pygo                                  Searching for Pygo
Reading http://www.python.org/pypi/Pygo/
Best match: Pygo 0.0
Downloading http://cheeseshop.python.org/packages/2.4/P/Pygo...
Processing pygo-0.0.0-py2.4.egg
... more stuff happens...
Installed /usr/local/lib/python2.4/site-packages/pygo-0.0.0-py2.4.egg
Processing dependencies for Pygo

Now, since I didn’t actually upload it to Cheese Shop, I’ve faked that screen. But that’s pretty close to how it would’ve looked if I had released pygo and uploaded it to Cheese Shop.

After this one command, as a web administrator, we now have the pygo application installed. There shouldn’t be any need to be installing web applications over and over for every user that wants to run it as the vast majority of web applications get their customization and settings from a database.

What needs to be configured, is the instance of the web application that each user is running. We can set that up for each user inside our Paste configuration file like so:

[server:main]
use = egg:PasteScript#flup_scgi_thread
host = 127.0.0.1
port = 3000

[composit:main]
use = egg:Paste#urlmap
/blog/fred = fredpygo
/blog/janet = janetpygo

[app:fredpygo]
use = egg:pygo
database = mysql:/username@localhost/database

[app:janetpygo]
use = egg:pygo

These configuration files are quite flexible, and allow different instances of a web application to run at different locations. In that case, one of them is running for ‘fred’ at /blog/fred. Each block for an app can have additional arguments that setup the database to use, and other settings that should probably be customized for each user. I threw in an additional database argument for one of them as an example.

Maybe you’re not a web administrator, but a web user comfortable downloading and installing many of the other webapps out there (Typo, MovableType, phpBB, etc.). Setting up your own site, using whatever Paste-enabled Python webapps you want is just as easy. Ideally ISP’s and such would just run the easyinstall command to install whatever the ‘popular’ webapps of the week are, and they can update them easily, keep old versions around if needed, etc.

Making Python Web-Application Distribution/Use Easy

This is pretty powerful stuff, and its quite easy to use. Even if you’re not making a web application with the intent to distribute it to the world, Paste is still going to help you out in a lot of ways.

An ISP or webapp end-user only needs to know how to add your webapp to their config file and installing it is a breeze thanks to setuptools. I think this has an enormous benefit for the Python web community, as it’ll significantly increase the ease of use when it comes to installing and managing web applications. Python web developers will gain some good footing to create Python Web Applications that compete with and surpass PHP webapps, especially if more ISP’s start supporting Paste-enabled applications.

Well, that’s my hope at least as I’m sure the title of this section made clear.

For the Python web framework creators out there, I like writing web applications (with various web frameworks), and I really like how easy Paste makes it to create them, package them up, and use them. Please add Paste support to your web framework, I’ll be happy to help and the Paste mail list is very responsive.

Comments

Leave a comment

  1. Avatar
    Kevin Dangoor about 13 hours later:

    Hi Ben,

    tg-admin quickstart

    (the 0.8 version of the command) is a bit less typing than

    paster create—template=turbogears

    :)

    I do think it likely that Paste and TurboGears will come together at some point. There are a couple of integration issues, but the #1 problem that I see is between Paste and CherryPy. The Paste’s URL mapping scheme and CherryPy’s are not immediately compatible, from what I’ve seen… I’m sure they can be hooked up, but some changes need to happen first.

    Kevin

  2. Avatar
    Ben Bangert about 15 hours later:

    Kevin,

    Yea, I know I could’ve typed that, I just wanted it to work from paster. ;)

    It really depends on what level of integration you’re referring to. You can easily make a paste template for TurboGears without any changes, but the problem you’re referring to will occur in certain deployment configurations.

    Because someone distributing a Paste-enabled application doesn’t know if a URL prefix is going to hit them, it could make it tricky in their webapp to setup URL’s.

    This was exactly the issue I addressed in Routes by creating a ‘prefix’ setting, so that the webapp can be easily configured to run under any URL prefix and all the URL’s inside the webapp will still work properly.

  3. Avatar
    Kevin Dangoor about 16 hours later:

    TurboGears 0.8 does have a URL class to take the prefix into account, so URL generation is not the problem with app composition.

    The larger CherryPy/Paste Deploy issues that come to mind are:

    • You currently set the entry point for a CherryPy site by setting cherrypy.root, and you join things together through standard Python constructs. That works fine for CherryPy-based sites, but either Paste or CherryPy would need to grow some knowledge about things that Paste wants to attach beneath the root.
    • CherryPy has its own config system that defines filters for various paths on the site. That needs to be reconciled with Paste’s config system

    I’d imagine there are others in the CherryPy community who have thought about this more than I have. These are just the things I’ve thought of as reading Ian’s examples for Paste.

  4. Avatar
    Ian Bicking about 18 hours later:

    A couple things:

    paster create can apply multiple templates, so it is at least in theory possible that you could recombine templates to put together your preferred stack. Templates can also require each other, and all my templates require basic_package, so a certain amount of work is done for you. paster create also has some subversion hooks, can be applied on top of an existing project, and no doubt other features in the future. So I think it offers something more than the other project creation scripts (which all of Subway, Turbogears, and Django have). For instance, at my work we have an internal template that extends the webkit template with our own standards—something that can’t practically be integrated into a single tool.

    CherryPy does have a problem that it can’t support multiple WSGI applications in the same process. I really hope they fix that sometime soon—I opened a ticket on it only a couple days after the WSGI support was initially announced. I don’t think modifying your source to put together disparate applications makes sense, so requiring that you enter the CherryPy URL resolution system at the very top of your application is not a very good way to build a website. Which is only to say that fixing this is good for CherryPy in general, to keep the application encapsulated.

    Right now the minimal way to combine Paste and CherryPy configuration is by simply having one Paste configuration value (maybe “config”) that points to a CherryPy configuration file. This is probably the right first step, regardless of any further work. But it might be possible to combine the two configuration files completely—Paste (deploy) only pays attention to specific sections (based on the app:, filter:, etc section prefix), and will faithfully ignore everything else. That might already be compatible with CherryPy’s configuration files.

    For URL prefix issues, I try to be very conscientious about keeping the distinction of SCRIPT_NAME and PATH_INFO - if CherryPy parses only the PATH_INFO URL (which represents the section of the URL that has not yet been consumed), then it should be safe. Since CherryPy is generally connected to through HTTP proxies - where there’s no SCRIPT_NAME/PATH_INFO distinction—I don’t know how well CherryPy does at this. However, things like custom CP-location-root headers and whatnot are essentially workarounds for this, so I think CherryPy could already benefit from a well-defined distinction here (and WSGI defines the distinction specifically).

  5. Avatar
    Ian Bicking about 18 hours later:

    Also, one more note on paster—you only have to pass in that—template=foo option to the create command, because once a project is started paster will know what plugins apply to the project. Of course, before you’ve started a project there’s no way to know that. Anyway, it’s no more verbose than tg-admin or any other tool after that first invocation.

  6. Avatar
    mike bayer 1 day later:

    just a note, Myghty 0.99 is released, including those three Paste templates.

    I consider the three templates to be three “levels” of application:

    “simple” is just an absolute minimal setup that shows the most commonly used and basic HTML::Masonlike features of Myghty, namely an autohandler and a few components to pull in a standard set of design elements for a set of templates.

    “modulecomponents” then moves it up a notch and adds a controller.py to illustrate a basic and open-ended MVC framework, using PathModule resolution which is a simple path-object-method traversal scheme very similar to mod_python Publisher handling. An alternative resolution for this model is the more specific ModuleComponents resolver that maps regexps directly to specific functions and methods.

    “routes” then goes out and uses Ben’s new Routes resolution to show a more specific kind of MVC framework that builds a more “ROR-esque” style of app, controllers built off of a common base class with more integration with it’s specific style of resolution.

    I think each style is appropriate for different developer preferences, as well as the requirements of the application being built. A beginning developer might like option #1 for its simplicity; the rest of the world might like #3, for the same reasons Rails is so popular. My own choice is #2 as I am a fan of starting sparse and “building into” the specific architectural paradigms that most elegantly apply for the application being built.

    Also the default listen port for all the templates, including the Routes one, is 8000. Enjoy !