Del.icio.us API Interface

Monday, July 17, 2006

I finally figured out how to parse the Del.icio.us API using Python and Django. The solution is quite flexible aside from the fact that the Del.icio.us API is still under development.

I started by studying FlickrClient which is a great interface for Python. The Flickr API is very verbose and this is a simple approach that scales to future Flickr upgrades. The power behind this script is the following method:

def __getattr__(self, method):
  def method(_self=self, _method=method, **params):
    _method = _method.replace("_", ".")
    url = "http://flickr.com/services/rest/" + "?method=%s&%s&api_key=%s" % (_method, urlencode(params), YOUR_API_KEY)
    ...

This basically generates the proper URL string to be passed to Flickr. With this bit of simplicity you can literally call any API method. All thats left is parsing the return XML value which is done by XMLTramp. This will parse any XML data into a useful object that you can iterate through in a Django template.

rsp = xmltramp.load(url)

I’ve retooled this approach a bit to work with Del.ici.ous. The biggest difference is instead of using an API Key you have to validate with Https. I created a method to handle this using urllib2:

def _secureConnect(self, url):
  auth_handler = urllib2.HTTPBasicAuthHandler()
  auth_handler.add_password('del.icio.us API', 'https://api.del.icio.us', USERNAME, PASSWORD)
  opener = urllib2.build_opener(auth_handler)
  urllib2.install_opener(opener)
  return urllib2.urlopen(url).read()

The other big difference is all the data in the return XML resides in attributes of a single node. (In my opinion this is crap but such is life.) We must create a new object because Django templates don’t seem to like how XMLTramp accesses node attributes.

for child in rsp:
  posts.append({'description':child('description'), 'href':child('href'), 'extended':child('extended'), 'hash':child('hash'), 'time':child('time'), 'tag':child('tag')})
  return posts

I’m sure if I become better versed with urllib2 and Python I could make this simpler. For now it works which was the intended goal. Here is the code. Word of caution! It’s good practice to save these results to a local database thereby minimizing the API requests. Del.icio.us in particular will throttle back your requests when it notices an increase in API traffic. My next post will address this.