2011
Nov
24

Syndication feeds from templates

One of the must-have necessities for any blogging or other web publishing software is the RSS (Really Simple Syndication) feed. RSS, or its younger and sexier sibling Atom, is the file format used by news aggregators, which give you a frequent listing of posts and stories published by your favorite blogs, newspapers, journals, whatever you want, without you having to actually go to their website. Usually the RSS feed is generated by some library of code where you construct your feed as an array of objects or data structures. Here's how you put together an RSS feed with PyRSS2Gen, for instance:

rss = PyRSS2Gen.RSS2(
    title = "Andrew's PyRSS2Gen feed",
    link = "http://www.dalkescientific.com/Python/PyRSS2Gen.html",
    description = "The latest news about PyRSS2Gen, a Python library for generating RSS2 feeds",

    lastBuildDate = datetime.datetime.now(),

    items = [
       PyRSS2Gen.RSSItem(
         title = "PyRSS2Gen-0.0 released",
         link = "http://www.dalkescientific.com/news/030906-PyRSS2Gen.html",
         description = "Dalke Scientific today announced PyRSS2Gen-0.0, a library for generating RSS feeds for Python.  ",
         guid = PyRSS2Gen.Guid("http://www.dalkescientific.com/news/030906-PyRSS2Gen.html"),
         pubDate = datetime.datetime(2003, 9, 6, 21, 31)),
       PyRSS2Gen.RSSItem(
         title = "Thoughts on RSS feeds for bioinformatics",
         link = "http://www.dalkescientific.com/writings/diary/archive/2003/09/06/RSS.html",
         description = "One of the reasons I wrote PyRSS2Gen was to experiment with RSS for data collection in "
                       "bioinformatics.  Last year I came across...",
         guid = PyRSS2Gen.Guid("http://www.dalkescientific.com/writings/diary/archive/2003/09/06/RSS.html"),
         pubDate = datetime.datetime(2003, 9, 6, 21, 49)),
    ])

But here's another solution I like: use a template. After all, the whole point of templating is to separate the way you generate your content from the way you present it. Among other things, this makes it easy to produce multiple views of the same data, since you can reuse the code that generates it and just stick in a different template. And since each RSS feed is supposed to correspond to a web page, half the work the generation code — should be done already. You can just create an outline of an RSS feed in your favorite templating system (just read right off the spec line by line) and pick either the web page template or the RSS template depending on the URL. Look at this Clearsilver example I made:

<?cs each:item = feed.items ?><item>
    <?cs if:item.title ?><title><?cs var:item.title ?></title><?cs /if ?>
    <?cs if:item.link ?><link><?cs var:item.link ?></link><?cs /if ?>
    <?cs if:item.description ?><description><?cs var:item.description ?></description><?cs /if ?>
    <?cs if:item.author ?><author><?cs var:item.author ?></author><?cs /if ?>
    <?cs each:category = item.categories ?>
        <category<?cs if:category.domain ?> domain="<?cs var:category.domain ?>"<?cs /if ?>><?cs var:category ?></category>
    <?cs /each ?>
    <?cs if:item.comments ?><comments><?cs var:item.comments ?></comments><?cs /if ?>
    <?cs if:item.enclosure ?>
        <enclosure url="<?cs var:item.enclosure.url ?>" length="<?cs var:item.enclosure.length ?>" type="<?cs var:item.enclosure.type ?>"/>
    <?cs /if ?>
    <?cs if:item.publication_date ?><pubDate><?cs var:item.publication_date ?></pubDate><?cs /if ?>
    <source url="<?cs var:feed.url ?>"><?cs var:feed.title ?></source>
</item><?cs /each ?>

As a bonus, that actually looks like an RSS feed, so now you have a handy reference for all the different fields you can put in.

2011
Nov
06

Scilab

Based on a tip on Stack Overflow, I just discovered Scilab, a FOSS (free/open source software) equivalent to Matlab. Then I discovered that I had actually only rediscovered it: Scilab was already installed on my computer. Maybe my scientific software collection needs a cleanup.

Anyway, as I mentioned, Scilab aims to do basically what Matlab does. It's an admirable goal, but I'm not such a fan of the program itself, for a couple of reasons: first, at least on Linux, it looks ugly, and more importantly, the GUI seems to lack some of the basic functionality that people tend to expect these days, like scrolling. If you're a fan of xterm then perhaps Scilab is for you, but otherwise it's kind of inconvenient to use. For the rest of us, the need for a Matlab equivalent is pretty well filled by Python with Numpy/Scipy and matplotlib, plus your terminal of choice. Python also has the benefit of being a general-purpose programming language, so once you learn it for numerical computation, you can do all sorts of other cool things with it.

2011
Aug
18

Python Log Viewer

For anyone who develops in Python, Python Log Viewer seems like a simple but incredibly useful tool. As the name suggests, it listens on a socket and displays any log records sent to it using the SocketHandler from the Python logging system. You can use the GUI to filter by log level and/or logger name, and also view full details about the log records.

As a matter of fact, I'm finding this quite useful while I try to figure out how to restore stability to my website. (In other words, sorry about how flaky things have been lately; I'm working on it.)

2010
Aug
07

More Python voodoo: optional-argument decorators

I've just been doing something that probably should never be done in Python (again), and I figured it might be useful to record this little snippet for posterity. Many Python programmers are probably familiar with decorators, which modify functions by wrapping them with other functions. For example, if you want to print 'entering' and 'exiting' to trace when a function's execution begins and ends, you could do that with a decorator:

def trace(func):
    def wrapper(*args, **kwargs):
        print 'entering'
        func(*args, **kwargs)
        print 'exiting'
    return wrapper

@trace
def f(a,b):
     print 'in f: ' + str(a) + ',' + str(b)

Note that in practice there are better ways to do this, but it's just an example.

Anyway, it's also possible to customize the behavior of decorator itself by providing arguments, for instance if you wanted to print different strings instead of 'entering' and 'exiting'. But in that case, your "decorator" function is actually a wrapper that creates the real decorator and returns it:

def trace(enter_string, exit_string):
    def _trace(func):
        def wrapper(*args, **kwargs):
            print enter_string
            func(*args, **kwargs)
            print exit_string
        return wrapper
    return _trace

@trace('calling f', 'returning')
def f(a,b):
     print 'in f: ' + str(a) + ',' + str(b)

OK, so far so good. Slightly mind-bending, but that's Python for you.

Now, what if you want both ways to work? What if you want a decorator that can be used with or without arguments, as either

@trace
def f(a,b):
     print 'in f: ' + str(a) + ',' + str(b)

or

@trace('calling f', 'returning')
def f(a,b):
     print 'in f: ' + str(a) + ',' + str(b)

Well, in the former case the decorator will be called with one argument, the function to be decorated. You can identify this case in an if statement and treat it separately. Like so:

def trace(*args):
    def _trace(func):
        def wrapper(*args, **kwargs):
            print enter_string
            func(*args, **kwargs)
            print exit_string
        return wrapper
    if len(args) == 1 and callable(args[0]):
        # No arguments, this is the decorator
        # Set default values for the arguments
        enter_string = 'entering'
        exit_string = 'exiting'
        return _trace(args[0])
    else:
        # This is just returning the decorator
        enter_string, exit_string = args
        return _trace

In this example, _trace is the "real" decorator, the thing that gets called to wrap f. The top-level function trace either stores its arguments and returns the decorator itself (if it has arguments), or calls the decorator to do its job and returns the result (if there are no arguments provided, other than the function to be wrapped of course). Obviously, this won't work if you have a decorator that needs to take one argument (not the function it's wrapping) which is itself a callable function — in that case you're on your own.

In fact — if you're not confused yet — you can even make a decorator that turns your decorator functions into optional-argument decorators. A meta-decorator, I guess. Here's one way to do it:

def opt_arguments(func):
    def meta_wrapper(*args, **kwargs):
        if len(args) == 1 and callable(args[0]):
            # No arguments, this is the decorator
            # Set default values for the arguments
            return func(args[0])
        else:
            def meta_func(inner_func):
                return func(inner_func, *args, **kwargs)
            return meta_func
    return meta_wrapper

You can use this to decorate a decorator function which has one required argument and default values for all other arguments:

@opt_arguments
def trace(func, enter_string='entering', exit_string='exiting'):
    def wrapper(*args, **kwargs):
        print enter_string
        func(*args, **kwargs)
        print exit_string
    return wrapper

@trace
def f(a,b):
    print 'in f(%s,%s)' % (a,b)

@trace('call g', 'return g')
def g(a,b):
    print 'in g(%s,%s)' % (a,b)

By the way, I haven't tried this when the decorator is a class or callable object instead of a function, but I think it should work.

2009
Jul
27

More Python voodoo: combination class/instance methods

Here's a neat tidbit from my website code: Let's say you're writing a class, and you want it to have some methods that can be called as either class or instance methods. Of course, you can do it by writing a class method:

class F(object):
    @classmethod
    def foo(cls, a, b, c):
        print a, b, c

F.foo(1, 2, 3)
F().foo(1, 2, 3)

But what if you want a pattern like the following instead, where the method, when called on an instance, can use the instance's attributes?

F.foo(1, 2, 3)
F(1, 2, 3).foo()

You can do this with a descriptor. Descriptors allow you to customize the way attributes are accessed (and set); you can define precisely what you want F.foo or F().foo to do. This is kind of like the __getattribute__ method, but more general because you can use descriptors for class attributes as well.

class FooDescriptor(object):
    def __init__(self, method_name):
        super(FooDescriptor, self).__init__()
        self.method_name = method_name

    def __get__(self, instance, owner):
        if instance is None:
            # As a class attribute
            def foo(cls, a, b, c):
                print a, b, c
        else:
            # As an instance attribute
            def foo(self):
                print self.a, self.b, self.c
        return foo

The downside of this procedure is that you have to write two different definitions of the method, although that's generally only a minor inconvenience. If you're using this technique for a long method, it's not hard to split out most of the code into a common function that gets called from both the class method and instance method versions.