Jesper Noehr

Pythonista, RESTafarian, Binary Poet & Proud Bucketeer

Python tricks: functools.partial and wraps

with 2 comments

Since Python 2.5, Python has had the ‘functools’ module for doing various higher order functions.

For example:

from functools import partial

def adder(first, second):
	return first + second

adder10 = partial(adder, 10)

print adder10(32) # -> 42

Partial evaluation, eh? That’s kinda cool.

On to ‘wraps’ which is the one I’ve found most practical use for. I like decorators, and I use them where applicable. What I don’t like about decorators is that when you get a backtrace, it’ll actually show up as *that* function, and not the function you decorated.

‘wraps’ to the rescue:

from functools import wraps

def some_decorator(f):
	def wrap(*args, **kwargs):
		return f(*args, **kwargs)
	return wraps(f)(wrap)

@some_decorator
def some_function():
	...

Now the function name, docstring, signature, etc. will be that of ‘f’, no longer ‘wrap’! Immensely useful.

Written by jespern

January 25th, 2009 at 7:23 pm

Posted in python

Piston and Oberon

with 2 comments

I just wanted to do a quick write-up on a couple of things, because:

  1. I wanted to announce two upcoming projects of mine, and
  2. Getting a new post out there

Piston

Piston’s a django-app I’m writing for Bitbucket. It serves as sort of a “mini-framework” on top of Django for creating RESTful APIs. Well, actually it doesn’t tie you to be RESTful at all, as its url mapping facility hooks directly into Django.

A while back, jacobian wrote an article, “REST worst practices”, outlining some of the things a good implementation would need. I’m happy to say that Piston’s elegantly waltzing its way through the list, checking off his points one by one.

We don’t tie a resource to a model (although you easily can), we have plug-able authentication (with new handlers being a breeze to add), configurable output formats (in form of “emitters”, a simple dict-to-x facility, comes with emitters for JSON, YAML and XML), proper use of HTTP (status codes, headers) and CRUD semantics, and best of all, it ties right in to your Django application.

Anyway, I wrote it for Bitbucket, but it definitely merits an open source release and its own project. It’s behind closed doors right now, but nearing completion. Once we feel it’s good to release, we’ll do a release together with David Larlet, the author of Semantic Django (who else?)

Oberon

Oberon’s also something we use on Bitbucket. It’s a queue-based “application platform” based on Twisted. Vague, huh?

No, we use it for the service integration facility of Bitbucket. Oberon itself is just a daemon, serving as a message-passing facility between the client and what I call “brokers”. A broker is a piece of Python code that must satisfy two things:

  1. It must contain a class that subclasses “BaseBroker”, and
  2. That class must have a “handle” method receiving a single argument, “payload”

What this allows you to do is pretty nifty. You can load up a few of these brokers, and then using the client API, you can send messages to Oberon, and it’ll take it from there.

For example, we have a couple of brokers, like Twitter, which extracts the information it wants from the payload and uses a Twitter client library to post messages. There’s a Basecamp broker, and the most popular one thus far is the “Issue” broker, which parses commit messages and acts on them. Stuff like “great, all done, fixes #42″ will close up issue 42, and “hm, needs more work, references #37″ will add a comment to issue 37.

Best of all, and my favorite feature is ‘oberonc’, the command line client. It’s pretty basic but it has useful commands like ’stats’, ‘brokers’ and best of all: ‘reload’ — yep, that’s right, you can reload brokers on the fly without disrupting service. It works really well too, due to the way we’ve designed the application. It also means you can load up new brokers that have never been loaded before, so it makes it really interesting to upgrade running systems.

None is this stuff is tied into Bitbucket, so it has a vast variety of uses. It runs on top of ‘twistd’ as well so it should be pretty stable and scalable (it uses stuff like epoll.)

Anyway, Oberon’s also getting its own open source release, together with all the brokers we’ve written for the service integration we’re using on the live system. Those should serve as good examples.

I’ll post about both here, when they’re out.

Written by jespern

January 23rd, 2009 at 10:51 am

Posted in django, python

Conditional middleware execution in Django

without comments

On BitBucket, we need to handle streaming data through Django. This lowers the memory footprint of the application and makes execution faster.

The problem with this is that several stock middleware in Django “look” at the content before sending it. This is a problem for streaming content, since you’d generally use a generator, and you can’t consume it until the very last minute.

The middleware in Django that does this is ConditionalGetMiddleware which attempts to create an ‘ETag’ header, and CommonMiddleware, which attemps to create a ‘Content-Length’ header.

Here’s an easy way of not executing certain middleware in such cases:

def wsgi_compat_middleware_factory(klass):
    class compatwrapper(klass):
        def process_response(self, req, resp):
            if not whatever_condition:
                return klass.process_response(self, req, resp)
            return resp
    return compatwrapper

This is a “factory”, returning a class that can you use instead of the normal middleware. On BitBucket, the condition is ‘if not req.is_mercurial():’. Replace with whatever makes sense for you.

You use it by doing something like this:

from django.middleware.http import ConditionalGetMiddleware
from django.middleware.common import CommonMiddleware

StreamingConditionalGetMiddleware = wsgi_compat_middleware_factory(ConditionalGetMiddleware)
StreamingCommonMiddleware = wsgi_compat_middleware_factory(CommonMiddleware)

Now you have two new classes – Just install those in place of the stock middleware, and viola.

Written by jespern

January 20th, 2009 at 8:32 am

Posted in django, python

Consumer Psychology

with one comment

A few days ago on reddit, there was a link to a book outline called “Predictably Irrational.” I’ve been reading through the entire thing, and there are some real gems in there — many which I’m sure you can apply to a vast variety of business and consumers.

Check it out – Predictably Irrational

Some examples:

Simonsohn and Loewenstein found that people who move to a new city remain anchored to the prices they paid in their previous city. People who move from Lubbock to Pittsburgh squeeze their families into smaller houses to pay the same amount. People who move from LA to Pittsburgh don’t save money, they just move into mansions.

and:

“If companies want to benefit from the advantages of social norms, they need to do a better job of cultivating those norms….It’s remarkable how much work companies (particularly start-ups) can get out of people when social norms (such as the excitement of building something together) are stronger than market norms (such as salaries stepping up with each promotion). If corporations started thinking in terms of social norms, they would realize that these norms build loyalty and–more important–make people want to extend themselves to the degree that corporations need today: to be flexible, concerned, and willing to pitch in.  That’s what a social relationship delivers.”

Written by jespern

December 31st, 2008 at 12:02 pm

What this blog will be about

with 3 comments

Right, so I’ve decided not to import my old blog entries, with the danger of some linking from other sites going wrong. Since I wrote my own blog software for the last attempt, and it doesn’t have any kind of export functionality + I don’t have time to write it, I’m just going to leave it at that.What will this blog be about? Well, hopefully it will have news about Bitbucket, DVCS in general, Python, maybe some scaling — stuff like that. I’m going away for Xmas vacation on Monday, and will be away for 2 weeks, so until then I won’t have anything on here.Stay tuned.

Written by jespern

December 18th, 2008 at 4:39 pm

Posted in Uncategorized