Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Tuesday, December 12, 2006

Hybrid Language Applications

I've recently been working on a small side project for my own personal use and have been considering using a mix of languages for the implementation -- specifically Java and Python but also possibly some Ruby. The reason I'm considering this is that there are unique advantages to each language that I'd like to leverage and I feel like I could implement things faster and more easily they were all available to me.

Specifically for the project I'm working on there's a component which needs to be able to parse RSS feeds. There happens to be an amazing python library called feedparser which seems to be by far the best RSS parsing library out there. So I plan to implement a simple program which knows how to retrieve a set of RSS feeds in python in order to take advantage of this library.

What I'm mostly unsure about is how to glue together my little programs. Right now I'm envisioning the python program producing output to standard output in a line based record format (probably CSV). We all know that a line based format is the "right thing to do" because ESR told us so. My big concern is whether or not there is a better way? It seems like with the addition of a Javascript interpreter in Java 6 (not necessarily required, but might make it even easier), JSON might be on the table.

What do others thing? How do you solve this problem?

Wednesday, August 16, 2006

Python Plug-ins

Years ago I was writing an IRC bot in python and had the need to create a plug-in architecture so that I could both abstract specific pieces of functionality away from the core of the bot as well as dynamically load and unload bot behaviors at runtime. At that point in time the ability to do this type of thing was present in python but there wasn't a standardized paradigm for how to do it. Since then things have become a bit more standardized with the addition of standardized import hooks and my code is surely outdated.

There was however one particular aspect of my implementation that proved to be nice I wanted to share -- the ability to reload and reinitialize a plug-in at runtime. This ability was accomplished mostly as a natural side-effect of using the imp standard library module. Here's how my code looked:

class PluginManager:
def __init__(self):
self.plugins = {}

def load_plugin(self, name, config):
from imp import find_module, load_module
fh, fn, desc = find_module(name, ['./plugins'])
self.plugins[name] = load_module(name, fh, fn, desc)

if hasattr(plugin, '__loadplugin__'):
plugin.__loadplugin__(self, config)

def unload_plugin(self, name):
try:
plugin = self.plugins[name]

if hasattr(plugin, '__unloadplugin__'):
plugin.__unloadplugin__(self)

del self.plugins[name]
except KeyError:
raise PluginException("Plugin %s not loaded." % name)

Because I manage the set of loaded plug-ins myself in the plugins member variable I can control the lifetime of a plug-in. This is also coupled with the fact that imp.load_module() always reloads a module, even if it had been previously loaded. Also note the use of the __loadplugin__ and __unloadplugin__ module level methods. If a plug-in module defined either one of these then it would be called during (de)initialization. In essence it's a very simple plug-in protocol that's being defined here.

Hopefully this will be of some use to someone in the future. By the way I don't advocate writing your own IRC bot nowadays. There are plenty of high quality, extensible, already built options out there. My personal favorite is Supybot.

UPDATE: In browsing around I found a library that does something very similar to what I described here, Sprinkles. At first glance it doesn't seem to have equivalents for __loadplugin__ or __unloadplugin__ but they may be hidden in there somewhere.