Archives for: July 2007


Permalink 10:03:20 am, by fumanchu Email , 393 words   English (US)
Categories: CherryPy, WSGI

Please don't use wsgiapp

Gordon Tillman has a wiki page up on how to mix Django content into a CherryPy site. It's easy and probably works, but please don't do it anymore.

We're officially going to deprecate the wsgiapp Tool because 1) it doesn't conform to the WSGI spec (and cannot be fixed to do so), and 2) there's a better way to mix content in a CherryPy site: tree.graft.

The tree.graft(app, script_name) method is the proper way to add Django or other WSGI content to an existing CherryPy site. Instead of nesting the two frameworks, we branch instead. To take Gordon's example, instead of:

class DjangoApp(object):
    _cp_config = {
        'tools.wsgiapp.on': True,
        '': AdminMediaHandler(WSGIHandler()),
cherrypy.tree.mount(DjangoApp(), '/')

You should always write this instead:

cherrypy.tree.graft(AdminMediaHandler(WSGIHandler()), '/')

Look, if you nest the one inside the other, CherryPy's going to do an awful lot of HTTP request parsing that is going to be completely redundant, since Django's going to do it again anyway. And this code is not very fast. Your site is going to crawl. That's strike one for nesting.

Strike two is the "always on" nature of nesting as opposed to branching. When you write your request/response cycle like an onion, every component which could possibly play a part in the request has to be called, even if just to reply "I'm not involved in this one". Given the slowness of Python function calls, this is rarely a good thing. If you thought your site was crawling before... This was a major design flaw of CherryPy 2, and is a major reason CherryPy 3 is 3x faster: the old Filters were called all the time, even if you didn't need them; the new Tools are only called when they're applicable.

Strike three against the nested approach is that it's always easier to traverse a tree of siblings than it is to traverse a nested set; programmers, for some reason, like to hide information from you, including how their site components go together. The branched version will be much easier to reason about, statically analyze, and write inspection tools for.

So please, use tree.graft, and stop using the wsgiapp Tool in CherryPy 3. We're going to formally deprecate it soon.


Permalink 11:23:45 am, by fumanchu Email , 405 words   English (US)
Categories: General

May the goodbye be long

I've been working at Amor Ministries for fourteen years. I started as an intern, then "temporary paid staff" for two summers. I spent 9 months working in El Paso, TX as the only full-time staff member living there. Then, in the summer of 1994, I moved back to HQ in San Diego. I worked four more years "in the field", showing groups how to build houses for the poor.

Around 1998, I started nurturing our fledgling computer network, and began writing business-management software for the ministry. I was the entire IT department (with a lot of help from Wendy, my supervisor) until we hired Ryan Gwillim to take over System Administration duties in early 2001. Together, we grew the network as the company grew. I wrote a lot more code, including my own database mediation software and web server, plus web applications, and reporting and analysis tools. For the last year, I've added the title of "Director of IT" to my existing "System Architect" role.

And despite all the good work and good friends, it's time for me to move on. Today is my last day as a full-time employee of Amor Ministries.

I've accepted a position as Software Engineer at, an online marketplace for handmade goods, starting August 1st. Since they let me work from home, I will continue to live in San Diego. This should also allow me to continue to contribute to Amor--we are discussing consulting options for the transitional period while Amor searches for a new Director of IT, System Architect, and Web Application Developer.

Thanks so much to all who have supported me throughout my ministry here at Amor for so long. Your contributions make a huge impact in our world and for the kingdom--an offer of hope to those who have none. Although I've done my best to meet Amor's future IT needs, they need your support now more than ever as they seek to fill not one, but three positions soon.

Thanks to all my friends at Amor, past and present. We know a level of trial and service that most people never experience, and that common bond will keep us close into eternity. Consider it all joy.

A special thanks to Scott and Gayla, for inspiring and supporting so many to do so much. Thanks for your patience and your passion. May your vision carry Amor to do "even greater things than these" far into the future.


Permalink 08:00:30 am, by fumanchu Email , 38 words   English (US)
Categories: IT, Python

URL's are files, again, apparently

It doesn't try to reinvent web files as classes. URLs retain their meaning as file locations.

Best example of Not Getting It I've seen in a while. Somebody needs to re-read Fielding.


Permalink 12:27:50 pm, by fumanchu Email , 241 words   English (US)
Categories: Python, Dejavu, CherryPy

Lines of code

I was asked last week how many lines of code some of my projects are, and didn't have an answer handy. Fortunately, it's easy to write a LOC counter in Python:

"""Calculate LOC (lines of code) for a given package directory."""

import os
import re

def loc(path, pattern="^.*\.py$"):
    """Return the number of lines of code for all files in the given path.

    If the 'pattern' argument is provided, it must be a regular expression
    against which each filename will be matched. By default, all filenames
    ending in ".py" are analyzed.
    lines = 0
    for root, dirs, files in os.walk(path):
        for name in files:
            if re.match(pattern, name):
                f = open(os.path.join(root, name), 'rb')
                for line in f:
                    line = line.strip()
                    if line and not line.startswith("#"):
                        lines += 1
    return lines

I've added the above to my company's public-domain misc package at Here are the results for my high-priority projects (some are proprietary):

>>> from misc import loc
>>> loc.loc(r"C:\Python24\Lib\site-packages\raisersedge")
>>> loc.loc(r"C:\Python24\Lib\site-packages\dejavu")
>>> loc.loc(r"C:\Python24\Lib\site-packages\geniusql")
>>> loc.loc(r"C:\Python24\Lib\site-packages\cherrypy")
>>> loc.loc(r"C:\Python24\Lib\site-packages\endue")
>>> loc.loc(r"C:\Python24\Lib\site-packages\mcontrol")
>>> loc.loc(r"C:\Python24\Lib\site-packages\misc")

~= 61 kloc. Pretty hefty for a single in-house web app stack. :/ But, hey, nobody said integration projects were easy.

July 2007
Sun Mon Tue Wed Thu Fri Sat
 << < Current> >>
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        


The requested Blog doesn't exist any more!

XML Feeds

powered by b2evolution