In my previous post, I gave an example of how to authenticate a user against the Flickr API using their new OAuth authentication scheme.
I am going to expand on that post a bit, and show you how to download all the images for a given photo using the flickr.photos.getSizes API call.
If you followed my previous post, you should have a “token” file in your directory that contains the “oauth_token” and “oauth_token_secret” in it. You should also have an “apikeys” file that contains your application “api_key” and “secret”. We will need some code to read these files to get the keys and secrets.
classAPIKeys(object):"""Base class to read the APIKeys from file"""def__init__(self,filename='apikeys'):try:fp=open(filename)exceptIOErrorase:ife.errno==errno.EACCESS:print"file does not exists"# Not a permission error.raiseelse:withfp:self.apikey=fp.readline().rstrip('\n')self.apisecret=fp.readline()fp.close()classTokenKeys(object):"""Base class to read the Access Tokens"""def__init__(self,filename='token'):try:fp=open(filename)exceptIOErrorase:ife.errno==errno.EACCESS:print"file does not exists"# Not a permission error.raiseelse:withfp:self.token=fp.readline().rstrip('\n')self.secret=fp.readline()fp.close()
The next task at hand was coming up with a base class that can encapsulate all the work needed in order to make subsequent Flickr API calls once you have your api key and token. I named this class “FlickrApiMethod” and it sets up all the data needed to make Flickr API requests. It has a “makeCall” method that will make the REST call, load the returned JSON content and return True if the call was successful, or False if it was not. I plan on expanding on this a bit to support all the different response formats that Flickr supports, but for now it just supports JSON. This class also has an no implementation “getParameters” method that allows subclasses to fill out additional parameters that are needed for a specialized API call.
classFlickrApiMethod(object):"""Base class for Flickr API calls"""def__init__(self,nojsoncallback=True,format='json',parameters=None):apifile=APIKeys()tokenfile=TokenKeys()self.consumer=oauth.Consumer(key=apifile.apikey,secret=apifile.apisecret)self.token=oauth.Token(tokenfile.token,tokenfile.secret)ifnojsoncallback:self.nojsoncallback=1else:self.nojsoncallback=0ifnotparameters:parameters={}self.url="http://api.flickr.com/services/rest"defaults={'format':format,'nojsoncallback':self.nojsoncallback,'oauth_timestamp':str(int(time.time())),'oauth_nonce':oauth.generate_nonce(),'signature_method':"HMAC-SHA1",'oauth_token':self.token.key,'oauth_consumer_key':self.consumer.key,}defaults.update(parameters)self.parameters=defaultsdefmakeCall(self):self.parameters.update(self.getParameters())req=oauth.Request(method="GET",url=self.url,parameters=self.parameters)req['oauth_signature']=oauth.SignatureMethod_HMAC_SHA1().sign(req,self.consumer,self.token)h=httplib2.Http(".cache")resp,content=h.request(req.to_url(),"GET")self.content=contentself.json=json.loads(content)ifself.json["stat"]=="ok":returnTrueelse:returnFalsedefgetParameters(self):raiseNotImplementedError
Next, I will write a class, that given a unique “photo_id” it will call the flickr.photos.getSizes method and write out the files for all the sizes available.
Finally, a little bit of code to use these classes:
1234567891011
print"Please enter a photo id:",photoId=raw_input()print"Fetching Photo"photoSizes=FlickrPhotosGetSizes(photo_id=photoId)if(photoSizes.makeCall()):print"API Call Success! Writing Photos to Disk"photoSizes.writePhotos()else:print"API Call Failed"
If all went well, you should now have files in your directory for all the different sizes of the photo you specified.
Feel free to email me with any questions or comments. The git repo for this is located here.