Make Authenticated Flickr API Calls and Rotate a Live Image

Flickr is Yahoo!'s popular photo sharing service and it's our most widely used mashup API. In this HOWTO, we show how to make authenticated Flickr API calls and then rotate a retrieved image.

Flickr Authentication

This example shows how to perform the steps necessary to authenticate a Yahoo! Flickr user. Once the user has been authenticated, you have full access to the Flickr API.

Prerequisites

Before you can use the Flickr API, you must obtain an API key and Shared Secret at the following URL:

http://www.flickr.com/services/api/keys/apply

If you lose your key or secret, you can find them here:

http://www.flickr.com/services/api/keys

Before continuing, we recommend that you read this document in order to understand the sign-up flow for the Flickr API:

Another useful reference is the Flickr API spec:

Request A Frob

When registering a non-web application, be sure to choose the Desktop Application radio button for the Authentication Type. We do not want the user automatically redirected to a callback URL with the frob passed in the URL as a GET argument because our desktop application's token request will fail. You should choose Web Application for the Authentication Type if you want the frob argument automatically passed back to the auth handler callback URL for a subsequent call to flickr.auth.getToken.

Request a frob to identify the login session. This call requires a signature. The signature starts with your shared secret and is followed by your API key and the method name. The API key and method name are prepended by the words "api_key" and "method" as shown in the following line.

String methodGetFrob = "flickr.auth.getFrob";
String sig = secret + "api_key" + key + "method" + methodGetFrob;

The API signature must be MD5 encoded and appended to the request. All API calls using an authentication token must be signed. In addition, calls to the flickr.auth.* methods and redirections to the auth page on flickr must also be signed.

String signature = MD5(sig);
String request = "http://api.flickr.com/services/rest/?method=" + methodGetFrob + "&api_key=" + key + "&api_sig=" + signature;
System.out.println("GET frob request: " + request);

Retrieve the XML response to the frob request and get the frob value.

 HttpClient client = new HttpClient();
GetMethod method = new GetMethod(request);
InputStream rstream = null;

// Get the response body
rstream = method.getResponseBodyAsStream();
Document response = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(rstream);
String frob = null; // Check if frob is in the response
NodeList frobResponse = response.getElementsByTagName("frob");
Node frobNode = frobResponse.item(0);
if (frobNode != null) {
frob = frobResponse.item(0).getTextContent();
System.out.println("Successfully retrieved frob: " + frob);
} else {
printFlickrError(response);
...
}

Create a Flickr Login Link

http://www.flickr.com/services/auth/?api_key=[api_key]&perms=[perms]&frob=[frob]&api_sig=[api_sig]

We are using "write" for the perms value because we will be rotating an image.

Generate the authentication signature. Signatures are created using your secret and the other arguments listed in alphabetical order, name then value. In our example, we want to request write permissions.

sig = secret + "api_key" + key + "frob" + frob + "permswrite";
signature = MD5(sig);
request = "http://www.flickr.com/services/auth/?api_key=" + key + "&perms=write&frob=" + frob + "&api_sig=" + signature;

Copy/paste the generated link into your favorite web browser and follow the instructions:

System.out.println("Browse to the following flickr url to authenticate yourself and then press enter.");
System.out.println(request);
BufferedReader infile = new BufferedReader ( new InputStreamReader (System.in) );
String line = infile.readLine();

The auth handler makes a regular API method call to the flickr.auth.getToken method. This method call, like all authenticated calls, requires signing. You sign a method by generating a signature based on the arguments to the call. You create the signature string by joining the shared secret to the list of arguments in alphabetical order.

String methodGetToken = "flickr.auth.getToken";
sig = secret + "api_key" + key + "frob" + frob + "method" + methodGetToken;
signature = MD5(sig);
request = "http://api.flickr.com/services/rest/?method=" + methodGetToken + "&api_key=" + key + "&frob=" + frob + "&api_sig=" + signature;
System.out.println("Token request: " + request);

Retrieve the XML response to the token request and get the token value:

String token = null;
// Check if token is in the response
NodeList tokenResponse = response.getElementsByTagName("token");
Node tokenNode = tokenResponse.item(0);
if (tokenNode != null) {
token = tokenNode.getTextContent();
System.out.println("Successfully retrieved token: " + token);
...
} else {
printFlickrError(response);
...

We have now authenticated with Flickr and obtained an auth token with write privileges.

The source code for this example can be found in the file FlickrAuth.java

Rotate A Live Image with the Flickr API

In the previous section, we authenticated with Flickr and obtained an auth token with write privileges. Now it's time to rotate the image. This example assumes that you have uploaded a photo to your Flickr account.

The photo id can be found in the URL of the photo:

http://flickr.com/photos/xxxxxxx@N03/<use_this_photo_id>/

To rotate an image, we'll use the rotate API call (Flickr API Documentation). The method call should be constructed as follows. Every authenticated call requires both the auth_token and api_sig arguments:

http://api.flickr.com/services/rest/?method=flickr.photos.transform.rotate&api_key=[api_key]&photo_id=[photo_id]&degrees=180&auth_token=[auth_token]&api_sig=[api_sig]
	String methodRotate = "flickr.photos.transform.rotate";
sig = secret + "api_key" + key + "auth_token" + token + "degrees180" + "method" + methodRotate + "photo_id" + photoId;
signature = MD5(sig);

Create the Flickr API request string. The Flickr API documentation specifies that calls to flickr.photos.transform.rotate be made via HTTP POST.

request = "http://api.flickr.com/services/rest/";
HttpClient client = new HttpClient();
PostMethod pmethod = new PostMethod(request);

Now add the POST parameters for the rotate request.

      
  pmethod.addParameter("method", methodRotate);
pmethod.addParameter("photo_id", photoId);
pmethod.addParameter("degrees", "180");
pmethod.addParameter("api_key", key);
pmethod.addParameter("auth_token", token);
pmethod.addParameter("api_sig", signature);

Retrieve the XML response to the rotate request and get the XML response:

statusCode = client.executeMethod(pmethod);
rstream = pmethod.getResponseBodyAsStream();
response = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(rstream);
String photoid = null;
// Check if token is in the response
NodeList rotateResponse = response.getElementsByTagName("photoid");
Node rotateNode = rotateResponse.item(0);
if (rotateNode != null) {
photoid = rotateNode.getTextContent();
System.out.println("Successfully flipped photo " + photoid);
System.out.println("Refresh the photo in your web browser and you will see it has been flipped.");
} else {
printFlickrError(response);
...

The photo has been flipped!

The source code for this example can be found in the file FlickrRotate.java

Error Handling

Here are a few handy lists of error codes that you may encounter in this HOWTO:

Flickr returns error codes in XML. If the Flickr Web Service request fails, an error code and message are returned in the XML:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<rsp stat="fail">
<err code="100" msg="Invalid API Key (Key not found)"/>
</rsp>

The following code demonstrates how to access the error code and message in your application.

public static void printFlickrError(Document response) 
{
NodeList error = response.getElementsByTagName("err");
String code = error.item(0).getAttributes().item(0).getTextContent();
String msg = error.item(0).getAttributes().item(1).getTextContent();
System.out.println("Flickr request failed with error code: " + code); //Flickr request failed with error code 100, Invalid API Key (Key not found)
}

For More Information

For more information on using Java with Yahoo! Web Services APIs, see The Yahoo! Developer Network Java Developer Center.

Yahoo Forum Discussions