
Scripting Flickr with Python and REST
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.
FlickrClient
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
21902936@N00
>>> 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')
...
P1010024
Ãfrica...
AFRICAN DREAM
Goro
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 |