Troubles with the Flickr API

As a business person, I am blown away by how bad Flickrs docs are for developers. With Yahoo struggling so much, why would they put so little effort into the one property they have that’s pretty popular? I am working on a image processing app. When my users are done, I figured they might want to post the results to Facebook or Flickr.

In my social circles, posting photos to Facebook seems much more popular; so much more, that I was not sure I should bother with Flickr. But, the Flickr docs seemed good. The API seemed straight forward. How hard could it be??? Famous last words. If I had it to do over again, I would not bother with Flickr. If I remember, once my app is running for a while, I will do a post on the Facebook/Flickr relative usage.

First I tried some of the Python packages others have posted. I had troubles with all of them. Then I found this post on Matt Kelsey’s blog. It was a great help. It got me thru the oauth process. But I wanted to post images. Matt did not show how to do this. Seems like he did the heavy lifting. A quick look at the docs and I should be on my way.

The docs have a page about how to upload. Looked pretty straight forward. Except what format should the parameter “photo” be in? It just says “The file to upload”. With the Facebook API, that’s the URL to an image. Not with Flickr. What else could it be?

If you read those docs very carefully, you see that uploading is done via a POST. What it is really looking for is a multi-part form. Luckily, this is really easy to do with the Python Requests package. Here is a snippet:’

import oauth2 as oauth
import time
import requests

token = oauth.Token(oauth_token, oauth_token_secret)
photo_url = 'http://api.flickr.com/services/upload'
consumer = oauth.Consumer(key=FLICKR_API_KEY, secret=FLICKR_API_SECRET)
data = {
    'oauth_consumer_key': consumer.key,
    'oauth_nonce': oauth.generate_nonce(),
    'oauth_signature_method':"HMAC-SHA1",
    'oauth_timestamp': str(int(time.time())),
    'oauth_token': token.key,
    'oauth_version': '1.0',
}
req = oauth.Request(method="POST", url=photo_url, parameters=data, is_form_encoded=True)
signature = oauth.SignatureMethod_HMAC_SHA1().sign(req, consumer, token)
req['oauth_signature'] = signature

data = {}
files = {'photo': ('test.jpg',open('/path/to/my/photo/test.jpg', 'rb'))}
r = requests.post(photo_url, data=req, files=files)
print 'Status ',r.status_code
print 'text ', r.text

Of course, if a user is going to upload several images, you don’t want the user to have authorized each time. The Flickr REST API has a method called: “flickr.auth.oauth.checkToken“. After figuring out how to upload a photo, I thought this would be easy. Wrong again.

The docs look easy enough. There is even this cool tool for exploring the API. And if you use the docs, you will waste several more hours of your life.  Do not use the docs! The problem is that Fickr has changed their API to use oauth. But their docs are a strange hybrid of the old and the new.  As of May 2013, the secret is revealed on this page in the section “Calling the Flickr API with OAuth”.

Summary: write ALL your requests based on the page: http://www.flickr.com/services/api/auth.oauth.html. Only look at the other docs as a rough guide to the services.

Advertisements

6 thoughts on “Troubles with the Flickr API

  1. hey 🙂

    i can’t see if this script ever worked??
    what is the r = requests.post(photo_url, data=req, files=files) for? especially the requests – this is not defined
    how do you use it? + httplib2 is not defined but i couldn’t find a call to httplib2 with requests.post

    cheers
    ToM

  2. Hi,

    Sorry, but I have moved on from that project so I cannot remember all the details. The point of the blog post was to show how to include the image in the POST to the Flikr API (this line: files = {‘photo’: (‘test.jpg’,open(‘/path/to/my/photo/test.jpg’, ‘rb’))} ).

    You are right that httplib2 is not used in this snippet. The snippet is also missing this import (I just edited the blog post to add it):

    import requests

    For more info on requests, see: http://docs.python-requests.org/en/latest/

    The r = requests.post(photo_url, data=req, files=files) is making an HTTP POST to the Flickr API.

    Take a look at the blog post: http://mkelsey.com/2011/07/03/Flickr-oAuth-Python-Example/ As I recall, most of my code came from there.

  3. I forgot to mention that the “requests_oauthlib” module is a good helper for this kind of api. have a look at the (GOOD) doc, examples are provided for both oauth1 & 2.

  4. And if you want a flickr-specific code that works out of the box, try the “python-flickr” module by michaelhelmick@github. It’s simple and efficient …until flickr changes again without notice of course.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s