XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.


Scripting Flickr with Python and REST

Scripting Flickr with Python and REST

January 25, 2006

Flickr probably needs no introduction for readers of this column. It's a hugely popular social-network site owned by Yahoo, focusing on sharing of photographs. It embodies most of the the current web buzzwords, including tagging, web feeds, AJAX, and accessibility to scripts. Flickr provides a set of HTTP-based APIs for accessing features both as a publisher and as a viewer of pictures. You get to choose between XML-RPC, REST (simple XML over HTTP), or SOAP, and the available functions cover every corner of the core Flickr service. In this article I'll look at some Python libraries for integrating with Flickr (all code tested with Python 2.4.2).

One thing you'll see across examples is reference to a Flickr API key. Such a key is always required to access Flickr through the official APIs, and if you want to take advantage of any of these scripting capabilities, you'll need to apply for a key from Flickr's API Keys page. Flickr uses a fairly elaborate system of token authentication based on your application key, fully described in the Flickr Authentication API Desktop Applications How-To. If you want to know the nitty-gritty details of an application's handshake with Flickr, do read this resource. A few Flickr libraries will try to abstract you from a lot of that, but for purposes of this article I'll dodge the issue by sticking to actions that are allowed without special user authentication. Be sure to browse the Flickr API home page for documentation of technical details of the Flickr API, as well as links to implementations for just about every popular language out there except for C/C++ and JavaScript.


The pioneer of Python Flickr tools is Michele Campeotto, whose work has been the inspiration for many of the libraries I discuss today. He is firstly known for FlickrUploadr, a program that provides a simple GUI using the GTK toolkit for Linux. The user drags and drops image files onto a simple window area, from which the pictures can be uploaded to a Flickr account. FlickrUploadr is focused more on end users and is not really a reusable library, so I shall not spend any more time discussing it. More to this article's purpose is FlickrClient, Campeotto's library module for Flickr. I installed FlickrClient 0.2 by copying the two Python files in the package to my Python site-packages. One of those packages is xmltramp, Aaron Swartz's simple Pythonic tree API for XML. Listing 1 is a simple example that gets all the public favorite photos for the Flickr user named "uche". The variable FLICKR_API_KEY in this listing and others should be set separately to your own Flickr API key.

Listing 1: Interactive session using FlickrClient to get a list of favorite photo titles

>>> from FlickrClient import FlickrClient
>>> client = FlickrClient(FLICKR_API_KEY)
>>> #Find the user ID of the person named "uche"
>>> person = client.flickr_people_findByUsername(username='uche')
>>> import pprint
>>> pprint.pprint(person.__dict__)
{'_attrs': {u'id': u'21902936@N00', u'nsid': u'21902936@N00'},
 '_dNS': None,
 '_dir': [<username>...</username>],
 '_name': u'user',
 '_prefixes': {}}
>>> userid = person(u'id')
>>> print userid
>>> faves = client.flickr_favorites_getPublicList(user_id=userid)
>>> faves[0]
<photo isfamily="1" title="P1010024" isfriend="1" ispublic="1" server="30"
secret="c68a340791" owner="75062596@N00" id="63291069"></photo>
>>> for fave in faves:
...     print fave(u'title')
In Concert
Fela Anikulapo Kuti
Heaven's Light on Lake Malawi

Flickr documents API requests in a form such as flickr.people.findByUsername. In FlickrClient you replace the dots with underscores and call the resulting method name on the Flickr proxy object (client in listing 1). FlickrClient does some remote method dispatch magic to forward the request to Flickr. The actual Flickr API is not hard-coded into FlickrClient (which is a mere 40 lines of code). You almost always have to pass at least one named parameter to Flickr. You must pass these as keyword arguments (for example, username='uche') for the dispatch magic to work; you can get the parameter name from the Flickr API documentation. If you make any mistakes that confuse FlickrClient you can expect some pretty cryptic error messages, but luckily the API is simple enough that you get the hang of it very quickly. You get back xmltramp nodes representing the Flickr response XML, and it's up to you to access the actual data you need. As in listing 1, I use __dict__ and repr() heavily for introspection of the result values so I can find out where to get the data I need. Some calls return lists, which come back as a container element with multiple children, as is the case for flickr.favorites.getPublicList.

As I mentioned, I use only Flickr calls that do not need user authentication. An example of a method that does is flickr.favorites.getList which gets all favorite photos including private ones. If you want to write code with Flickr user permissions in order to use such functions you have to redirect users to a web page so that they can log in and give your application permission. You then query Flickr again for a resulting authentication token as a result. It's a bit of a tricky process, and later on I cover a FlickrClient-derived tool that tries to do this handshake for you. You might be able to borrow code from there even if you're using FlickrClient.

Pages: 1, 2

Next Pagearrow