Pages: << 1 ... 4 5 6 7 8 9 10 11 12 13 14 ... 26 >>


Permalink 03:58:33 am, by fumanchu Email , 552 words   English (US)
Categories: CherryPy

Making a custom CherryPy Request class for Routes

While at PyCon in Dallas this weekend, I got a chance to hear David Creemer talk about how he's using CherryPy (among lots of other tools) to deliver a site that's getting 250,000 hits a day before it's even been officially launched. He mentioned during the "lightning" (5 minute) talk that, of his entire toolkit, CherryPy and SQLObject were two of the tools that "mostly worked, except..." I spoke with him after the talk about his concerns, and the big CherryPy issue was dispatching: he prefers a Routes-style dispatch mechanism, which makes changes to the design easier.

He had previously posted his cherrypy+routes script, which I read but hadn't done anything about. I mentioned to him yesterday that it might be better, when overriding the dispatch mechanism, to do so in a custom Request class, rather than in a single exposed default method on the cherrypy tree. Here's a first crack at what that would look like; I haven't tested it but it's more to get the idea of custom Request classes out there than to be a working patch ;)

import urllib
import cherrypy
from cherrypy import _cphttptools
import routes

mapper = routes.Mapper()
controllers = {}

def redirect( url ):
    raise cherrypy.HTTPRedirect( url )

def mapConnect( name, route, controller, **kwargs ):
    controllers[ name ] = controller
    mapper.connect( name, route, controller=name, **kwargs )

def mapFinalize():
    mapper.create_regs( controllers.keys() )

def URL( name, query = None, doseq = None, **kwargs ):
    uri = routes.url_for( name, **kwargs )

    if not uri:
        return "/UNKNOWN-%s" % name

    if query:
        uri += '?' + urllib.urlencode(query, doseq)

    return uri

class RoutesRequest(_cphttptools.Request):

    def main(self, path=None):
        """Obtain and set cherrypy.response.body from a page handler."""
        if path is None:
            path = self.object_path

        page_handler = self.mapPathToObject(path)

        virtual_path = path.split("/")
        # Decode any leftover %2F in the virtual_path atoms.
        virtual_path = [x.replace("%2F", "/") for x in virtual_path if x]

        kwargs = self.params.copy()
        kwargs.update( cherrypy.request.mapper_dict )

            body = page_handler(*virtual_path, **kwargs)
        except Exception, x:
            x.args = x.args + (page_handler,)
        cherrypy.response.body = body

    def mapPathToObject(self, objectpath):
        """For path, return the corresponding exposed callable (or raise NotFound).

        path should be a "relative" URL path, like "/app/a/b/c". Leading and
        trailing slashes are ignored.

        # tell routes to use the cherrypy threadlocal object
        config = routes.request_config()
        if hasattr(config, 'using_request_local'):
            config.request_local = lambda: self
            config = routes.request_config()

        # hook up the routes variables for this request
        config.mapper = mapper = self.headerMap['Host']
        config.protocol = self.scheme
        config.redirect = redirect
        config.mapper_dict = mapper.match( objectpath )

        if config.mapper_dict:
            c = config.mapper_dict.pop( 'controller', None )
            if c:
                controller = controllers[c]

                # we have a controller, now emulate cherrypy's index/default/callable semantics:
                action = config.mapper_dict.pop( 'action', 'index' )

                meth = getattr( controller, action, None )
                if not meth:
                    meth = getattr( controller, 'default', None )

                if not meth and callable( controller ) and action == 'index' :
                    meth = controller

                if meth and getattr( meth, 'exposed', False ):
                    return meth

        raise cherrypy.NotFound( objectpath )

# 'authui' is a module with login/logout functions

mapConnect( name = 'home', route = '', controller = home )
mapConnect( name = 'auth', route = 'auth/:action', controller = authui,
            requirements = dict( action='(login|logout)' ) )

cherrypy.server.request_class = RoutesRequest

Look, Ma, no root!


Permalink 12:30:17 am, by admin Email , 256 words   English (US)
Categories: Dejavu

Dejavu 1.4.0 (Python ORM) release

Dejavu 1.4.0

I'm extremely pleased to announce the release of Dejavu 1.4.0, a pure-Python Object-Relational Mapping library. Dejavu allows you to create, query, and manage persistent data using your existing knowledge of Python programming.


  • Data queries are expressed using pure Python; no SQL, no operator hacks, and no need to wrap code in strings.
  • Data may be transparently stored in PostgreSQL, MySQL, SQLite, Access, or SQL Server databases, as well as in flat files (using shelve), and caching proxies. You can create and combine custom storage systems for your own integration and performance needs.
  • Easy associations between Unit classes.
  • Full thread-safety for reliable use in web applications and other concurrent environments.
  • Views, sorting, cross-tabs, and other analysis tools.
  • Unit Collections, plus Engines and Rules to form powerful end-user query and reporting interfaces.

What's new in 1.4

  • Full LEFT, RIGHT, and INNER JOIN support (okay, one operator hack here).
  • Optimized and introspectable To-One and To-Many associations.
  • Arbitrary names for Unit.ID's (primary keys).
  • Support for multiple ID's (primary keys).
  • A new Schema class and other upgrade-management tools.
  • Default values for UnitProperties.
  • New logging hooks to help debug SQL and other storage issues.
  • Fixes to support Python 2.4 bytecode and other changes.
  • Inheritance support (all subclasses are recalled).
  • Vastly-improved test suite.
  • New recur module included, with a threaded Worker class.
  • Better support for update triggers.

Dejavu is in the Public Domain, and you may use it anywhere with no obligation whatsoever.

User documentation and a full Trac site are available at:


Permalink 09:49:38 am, by admin Email , 49 words   English (US)
Categories: General

Taking Responsibility

Seth Godin writes:

Is "I accept responsibility" the new "Your call is very important to us"? Probably.

Is that because some people have to be told by a marketing guru that taking responsibility is worth the effort? Probably. Shame, that.


Permalink 01:11:34 pm, by admin Email , 1711 words   English (US)
Categories: General

Concept pioneering

This past week, our Team Leader Team has met twice to talk about Coaching (with a capital "C", which means it's a Platonic ideal, or academic discipline, or a system, or maybe a product). What is it? How do we do it? What does it look like at Amor Ministries? It's a new concept for most of us, and even for those who have some experience with Coaching, we're having to work at it, trying to collaboratively map the "Coaching at Amor" space.

During the conversation, the topic flowed over into Performance Reviews (paraphrased):

A: What are we saying? If part of Coaching is "building relationship", 
   how do we avoid crossing over the line from Coaching to counseling?
B: We stick to talking about "performance".
A: But then we won't be addressing our company's values. One of our
   values is that work will be fun. If I'm only being talked to
   about my "performance", I'm given license to be grumpy every
   day as long as I get my tasks done.
B: That's why our Performance Reviews have 3 components: company
   values, core competencies, and meeting your goals (what most
   companies call "performance").
C: I know that's what mattered in my last job: bottom line--did you
   get those tasks done?
A: But again, if I can only talk about "performance", I'm not
   addressing the other two components.
B: Sure you are. They're all "performance".

Did you catch it? We just obliterated a concept—maybe two. Nuked, taken off the map. If you don't immediately see how, let me tell you another story:

Big Sur

Map of Pine Ridge Trail

Last year, I wanted to go backpacking in the Los Padres National Forest, just south of Monterey, CA. I hadn't ever been there, and was interested to see what coastal backpacking was like (it was great!). But before you can hike the trail, you have to choose the trail, and the Ventana Wilderness has several. We chose the "Big Sur" trailhead on the West side, but I was just as interested in the "China Camp" trailhead from the East. Both of them provide access to the "Pine Ridge Trail"; they are its endpoints, about 15 miles apart.

But imagine for a moment that Bill is the first English speaker on the Pine Ridge Trail. He only knows about the "Big Sur" trailhead, and as he walks (or creates) the trail, what does he call it? Taking the path of least resistance, he probably calls it the "Big Sur Trail". From his point of view, it's only got one endpoint, so there's very little difference between "Big Sur" (the trail) and "Big Sur" (the camp at the head of that trail).

Now, imagine a second person, Chris, starting at China Camp. She's going to call her journey the "China Camp Trail". After they each thoroughly walk and map the territory, they meet by chance in the middle. Will they decide on a common name for the trail? Perhaps, perhaps not. But if they do, what will it be?

What happens if Bill "wins", resulting in the common name being the "Big Sur Trail"? There are many repurcussions of this decision, but the one I want to focus on is this: the name "Big Sur" does not mean what it did before their meeting. Reread that until it sinks in. Oh, in Bill's personal world, it seems nothing has changed, but Christine doesn't see it that way—the name "Big Sur" is brand-new to her. But there's an important third party we haven't thought about yet, and that is "everyone else". Now that they've decided on names, chances are that those who follow in their footsteps will use the same names, and those names will confuse them. Here's how:

Confusious say...

Those people who follow Bill will have no problems. They can use the term, "Big Sur" as he did, to mean "the trail that starts at my trailhead"; that is, "Big Sur" refers to the trail and the trailhead at the same time—they are not divisable.

Those people who follow Christine have no problem, because "Big Sur" means the trail, and "China Camp" means "my trailhead". They never use the term "Big Sur" to talk about the opposite trailhead, because they never use it.

But those people who follow both of them, who are equally familiar (or unfamiliar) with both camps, have a problem. When I talk to Bill and Christine about "Big Sur", they mean different things:

Me:    So, I'm planning to hike Big Sur this weekend.
Bill:  Great! Make sure you get a good picture of the ocean.
Me:    Oh, I won't have time. I'm only going for one day.
Chris: Makes sense. You might get a good picture of the South
       Ventana Cone, though.
Bill:  Huh? The cone's at least two days of hiking.
Chris: Huh? It's only a day from China Camp.
Bill:  Oh, I thought you meant "Big Sur".
Chris: Huh? That's what we're talking about. "Big Sur".
Me:    Huh? I'm lost, and I haven't even left yet.

Of course, a real example scenario would be much longer. It might take several days for one of the participants to realize that we aren't all using the term "Big Sur" the same way. Explaining to (and even convincing) the others that this is so is a lot of work. It's so much work that it usually doesn't occur; if I'm the one with the epiphany, then I've solved the problem "for me" and can go on my hike, shaking my head at how silly Bill and Christine are with their parochial uses of the term "Big Sur". Obviously, the term means "the trail" or "the trailhead", but never both. Bill always means both, and Christine always means "the trail".


Fortunately for us, the powers-that-be called the actual trail, "Pine Ridge". They used a name that is different from the name of either trailhead (but there is a camp in the middle of the trail called "Pine Ridge", on a ridge called "Pine Ridge"). So Bill and Christine and I can all talk about it safely now, without saying, "Huh?" every other sentence.

But our fictitious example happens just as often in reverse. In our "Big Sur" example, the name of the part was inflated to also be the name of the whole. Often, we can find the name of the whole coming first, and then being subverted to mean one of the parts. Take the word "politics" for example. Its "original meaning" can be localized around the phrase "the profession of governing". But to hear the word as many people use it today, it can mean "giving up something in order to gain something else", or it can mean, "all talk and no action":

Joe: We sure needed a liberal judge.
Sue: Yes; but in the end, it was "just politics". Good thing,
     too, or we might have ended up with a conservative.
Joe: Huh? We did end up with a conservative judge. It was
     "just politics".
Sue: Huh? No we didn't. It was a political decision.
Me:  Huh? Isn't it all politics?

The meaning of the term "politics" has therefore been changed, from "governance" to a technique or facet of governance. This is no less of a problem than our "Big Sur" example.

Back to performance

Let's wrap up and return to our first conversation. What concept did we nuke and how? If you recall, speaker B said, in effect, that they were defining the word "performance" to mean "the whole": all 3 parts of the Performance Review. This differed drastically from person A's definition: that "performance" only meant one part, and even if Person A could be swayed, Person C had a lot of history backing up the use of the word "performance" to mean only the one part.

If person B somehow convinced them all to use the term "performance" to mean the whole, then we have a new problem: what do we call the part that we used to call "performance"? If we continue to call it "performance", then we've landed in Big Sur country. One name refers to both the part and the whole, and persons A, B, and C will struggle mightily to be understood in every future conversation about performance. Those who follow person B may never know what "performance" used to mean, and may never be introduced to that concept; simply by re-using just one word to mean something larger, we've potentially wiped out the old, smaller meaning—nuked it. If our people are really on the ball, they might notice this and choose to call the part by a new name, maybe "accomplishment of goals" or "completion of tasks", to distinguish it from the "performance" whole, and let it live on.

Big sigh.

But that's not good enough. Although we may be exploring this space for the first time, we're not true pioneers. Someone else has been here before, has already staked their claim to these ideas and terms, and has told everyone else and sold lots of maps and travel guides using these names. Consider: if we redefine "performance" to include corporate values and core competencies, we have now introduced a perpetual translation step. Whenever we bring in a Coaching expert, we will all become confused when they use the word "performance" differently than we do (this happened to us recently when we brought in a process-management expert—total communicative disconnect in both directions). When we hire a new employee, we will say, "I care about your performance" and they will hear, "I don't care about you, just outcomes".

Given the large body of literature on "performance" and the widespread common meaning, we would do ourselves a great disservice to redefine "performance" at Amor to mean something larger than its commonly-accepted meaning. Thankfully, our conversation turned elsewhere immediately, and person B used the word "performance" from that point on as we had always used it. I don't think anyone is going to start using "performance" in the broader sense.

But I was sweating bullets, there, for a little while. Let's hope the question, "what does Coaching 'look like' at Amor?" does not reach a similar point.


Permalink 11:10:35 pm, by fumanchu Email , 213 words   English (US)
Categories: Python, General, Dejavu, CherryPy

We're hiring, by the way

The job posting is pretty tame: we need a Python web developer. But I thought I'd add my personal point-of-view, and say that we really mean "developer" and not just "coder". You'd be responsible for producing working web apps, but that involves a lot of design work and architectural decision-making.

You would also be expected to contribute to the CherryPy HTTP framework and to Dejavu (my Python ORM), since I'm a core dev on both those projects and use them heavily already. In other words, if you have or want exposure to the full stack of modern web development challenges, this is the job for you. You'll be a full member of an IT team of 3 serving an energetic staff of 50.

You'll also get something that's hard to find in most programming jobs: warm fuzzies. We build homes for the poor in Mexico, simultaneously "building" the church in Mexico, the U.S., Canada, and elsewhere. We are not on the cutting-edge of world missions--we are defining that edge. If you've been thinking about "doing more for Jesus", but would rather write code than dig ditches in Uganda, give us a call (619-662-1200 ext 11).


Permalink 01:11:49 pm, by fumanchu Email , 289 words   English (US)
Categories: General

Where does the time go?

You may have noticed I haven't been blogging much. It's due to a combination of factors, and those of you who support me financially deserve at least a quick writeup of those:

  1. My position at work has changed dramatically in the last 3 months. I used to have a wonderful person between me and the Chief Operating Officer—now I answer directly to him, which means I have to do all of the things that Wendy used to do for me. Unfortunately, it seems "all of the things" amounts to another 10-15 hours of meetings every week.
  2. There wasn't any room in my schedule to begin with. Monday and Friday nights I'm supposed to work out with Ryan (the other half of my IT Team), Tuesday night is Praise Band practice, Wednesday is spent with the High School group at church, Thursday night is College group, Saturday afternoon sees me at a High School Bible study, and Sunday includes High School Sunday School (that may change to College/Young Singles this Summer).
  3. I've been working on CherryPy and Dejavu quite a bit, but I don't even have time to document that as I should. I need to release Dejavu 1.4, but I don't have the time to do it right. So blogging is taking a back seat to work I'm not even doing.
  4. I'm finally putting a real shower in my apartment after 10 years of using a tub and a metal hose, stapled to the wall. It's been a week and I'm about half done.

So, I have to apologize for being more of a doer than a communicator. I'd write more, but it's time for Bible study. :/


Permalink 12:28:14 pm, by fumanchu Email , 427 words   English (US)
Categories: General

Provocative questions on prayer

Dave Warnock points us to Ten Provocative Positions on Prayer by "Kim", to which I can only answer, "huh?" Perhaps they were provocative in Barth's day; I find them stale and purposefully vague [1]. Number 6 was the sole exception.

Here are some questions on prayer that I find provocative:

  1. Does anyone in the Bible ever pray silently? If not, are we sure God can hear us if we pray silently? [2] Perhaps God created flesh as a barrier between our thoughts and his thoughts. If he cannot hear us, what would that do to the Church in the West (especially the USA, with its focus on the "personal walk")? What would it do to your "walk"?
  2. If you believe God has decided everything in advance, why does the Bible state that God sometimes changed his mind when people prayed?
  3. Do you believe God hears you as readily as he heard the patriarchs? You are not Moses--should you model your prayer after his?
  4. Do you pray with your eyes closed? Why? Is it fear of ridicule? Guilt? Tradition? Try praying in a group with your eyes open and see if your answer changes.
  5. If God already knows what you need, are your words important? Would meditation have the same effect? Or is speech fundamental to thought and our recognition of the Other?
  6. Do you pray too often? Has the "spiritual discipline" robbed your prayer of its meaning? Would your spontaneous prayer be better if you didn't pray corporately and ritualistically so often?
  7. Have you made your life so comfortable that you no longer have anything to pray about? Do you care about anyone else enough to pray for them?
  8. When Jesus was asked "how we should pray", his example was short and to the point. Are your prayers short and to the point? Why or why not?
  9. Are your prayers different from "normal" speech (in any way other than inserting "Jesus" or "Father God" instead of "uhhhh...")? Should they be? How and why?
  10. Do you pray to a Person or to an impersonal Force? Does he answer you as to a son or daughter, or a servant, or not at all personally?

[1] Okay, okay, I find most theological writings stale and purposefully vague.

[2] I recently spoke with a friend who went to the Ukraine and met with a deaf Christian community. They believed they could not pray to God since they could not vocalize, only sign (my friend's group took the time to teach them otherwise).


Permalink 10:34:47 pm, by fumanchu Email , 54 words   English (US)
Categories: IT

There's no definition without culture

Adam Green recently wrote about "Web 2.0":

If it takes an essay or more than 5 or 6 bullet points to explain something, it is poorly defined.

I'll disagree with a counter-statement:

If it takes less than 5 or 6 bullet points to explain something, it's because the audience already knows what it is.


Permalink 08:49:20 pm, by fumanchu Email , 258 words   English (US)
Categories: IT

Win98 to the rescue

My, that was fun. Four hours of restoring a corrupted SAM on my mother's XP laptop—she has 46k dialup. :/ Here's the error message on boot:

lsass.exe - System Error "Security Accounts Manager initialization failed because of the following error: The handle is invalid. Error Status: 0xc0000008. Please click OK to shutdown the system and reboot into Safe Mode, check the event log for more detailed information."

The final resolution process:

  • On another computer, obtain NTFS4DOS, install it on a floppy, then burn the floppy contents onto a CD.
  • Boot the laptop from a Win98 CD. When prompted, choose "Run the computer with CD-ROM support."
  • Stay on the command line, pull out the Win98 CD, and insert the NTFS4DOS CD. Run NTFS4DOS.EXE.
  • NTFS4DOS loads, then waits for you to type "Yes" or "No" to the question, "Are you using this on a private computer?" Boring nagware, but a useful moment for us to swap CD's again—put the Win98 CD back in, so COMMAND.COM can be found on it.
  • Answer "Yes" to the nagware prompt.
  • Follow the instructions from Microsoft (method 2, step 3) to replace your corrupt or missing SAM with the one from windows\repair:

    copy c:\windows\system32\config\sam c:\windows\tmp\sam.bak
    delete c:\windows\system32\config\sam
    copy c:\windows\repair\sam c:\windows\system32\config\sam

Of course I considered Knoppix, but have you ever tried to download a 750MB ISO over dialup?


Permalink 11:34:47 am, by fumanchu Email , 106 words   English (US)
Categories: IT

Open source needs more pop quizzes

Glyph recently wrote:

I have also made no attempt to be fair, and I don't want to do this again any time soon, so if your favorite operating system got trashed here, don't bother to tell me that I'm not being fair. Think of it as a pop quiz!

Open source projects need more pop quizzes. There's a reason why you don't let developers run usability tests—it's far too easy to jump in with justification for why your product didn't work "just this once".

I'm just writing this to remember the "pop quiz" meme. Made me smirk. :)

<< 1 ... 4 5 6 7 8 9 10 11 12 13 14 ... 26 >>

September 2020
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
    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      


The requested Blog doesn't exist any more!

XML Feeds