Extract Photos Using the Flickr API

In this article, we’ll learn how to use the Flickr REST API.

The process to deal with a REST API in AIMMS is very similar, however you can find details of the differences in AIMMS Documentation: HTTP Client Library. Here, we use a concrete example of this process to supplement the documentation.

Use case

This use case is inspired by an idratherbewriting tutorial.

Flickr is an image and video hosting social network with a database of millions of photos. Our mission will be to extract the photos from a Flickr gallery.

Prerequisites

Before you begin, make sure you have done the following:

Example project

You can download the example project for this tutorial from the link below:

Required information

Information about the URL format where we can address our request and the authentication system to use can be found in Flickr API documentation, specifically the sections labeled URLs, Overview and User Authentication.

Note

According to Flickr’s documentation, the main authentication system used for this API is a complex OAuth protocol, but some methods can still be used with a simple API key. We’ll use the API key method here.

The request format is specified as a URL endpoint followed by these parameters:

  • method (REQUIRED) - specify the calling method
  • api_key (REQUIRED) - specify your API Key
  • format (optional) - specify a response format

The arguments, responses, and error codes for each method are listed on the method’s spec page, found on the Flickr API index page.

To download an image using a GET request, we need a photo URL.

To access a photo, we need the following:

  • the farm_id (optional - the server will provide it if you don’t)
  • the server_id
  • id
  • secret

The URL format is specified in the Flickr documentation:

https://farm{farm-id}.staticflickr.com/{server_id}/{id}_{secret}.jpg

To get this information about particular photos, we can use the method flickr.galleries.getPhotos to return the information required for creating the individual photo URLs.

First, we need the id of the gallery. We’ll use the flickr.urls.lookupGallery to get that.

Gathering required information

The process to gather the required information can be summarized as follows:

  1. Create a request to obtain the gallery id using flickr.urls.lookupGallery
  2. Create a request to obtain gallery photos using flickr.galleries.getPhotos
  3. Construct the photos URLs and do a GET request to obtain the files.

Getting photo information

We now want to create another procedure to get all the id information we need about the gallery photos. For that, we’ll use the flickr.galleries.getPhotos method from the Flickr API. The code for this procedure is as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
SP_responseFile:="Output2.xml";
SP_APIkey:= "Your_api_key";
SP_MethodName:="flickr.galleries.getPhotos";
SP_requestparameters:= {
    'method' : SP_MethodName,
    'api_key' : SP_APIkey,
    'gallery_id' : SP_GalleryID
};

web::query_format(SP_requestparameters,SP_formattedparameters);
SP_URL:="https://www.flickr.com/services/rest/?"+SP_formattedparameters;
web::request_create(SP_requestId);
web::request_setMethod(SP_requestId,"GET");
web::request_setURL(SP_requestId,SP_URL);
web::request_setResponseBody(SP_requestId,'File',SP_responseFile);
web::request_invoke(SP_requestId,P_responsecode);
READXML("Output2.xml","NAME_OF_YOUR_XSD.axm");

Set the HTTP request

../../_images/GetPhotos.png

This request takes the parameters api_key and gallery_id, and we want from the answer the farm ID, the server ID, the ID and the secret for each photo in the gallery. But before extracting these, we need to get the XML file containing this information from an HTTP request.

The process is almost the same as in the last request, the only thing changing here is the DATA of the set S_requestparam and the method used:

You need to create these objects:

../../_images/getphotosObjects.png
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Set S_requestparam {
    Index: I_rp;
    Definition: {
        DATA{api_key,method,gallery_id};
    }
    }
StringParameter SP_requestId {

}
StringParameter SP_requestparameters {
    IndexDomain: I_rp;
}
Parameter P_responsecode {

}
StringParameter SP_APIkey {
}
StringParameter SP_MethodName{

}
StringParameter SP_URL {

}
StringParameter SP_responsefile{

}
StringParameter SP_formattedparameters {

}

Then execute this code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
SP_responseFile:="Output2.xml";
SP_APIkey:= "Your_api_key";
SP_MethodName:="flickr.galleries.getPhotos";
SP_requestparameters:= {
    'method' : SP_MethodName,
    'api_key' : SP_APIkey,
    'gallery_id' : SP_GalleryID
};

web::query_format(SP_requestparameters,SP_formattedparameters);
SP_URL:="https://www.flickr.com/services/rest/?"+SP_formattedparameters;
web::request_create(SP_requestId);
web::request_setMethod(SP_requestId,"GET");
web::request_setURL(SP_requestId,SP_URL);
web::request_setResponseBody(SP_requestId,'File',SP_responseFile);
web::request_invoke(SP_requestId,P_responsecode);

You should now have access to the XML answer file in the direction SP_responseFile, and you can generate your second XSD file or download it.

Extracting data

Before extracting the data from the XML file using the AIMMS XML schema mapping tool, you need to create objects to contain this information:

../../_images/GetidsObjects.png
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 Set S_Photos {
    Index: I_p;
}
StringParameter SP_farm(I_p) {
    IndexDomain: I_p;
}
StringParameter SP_server(I_p) {
    IndexDomain: I_p;
}
StringParameter SP_id(I_p) {
    IndexDomain: I_p;
}
StringParameter SP_secret(I_p) {
    IndexDomain: I_p;
}

Using the XML mapping tool, you then need to make the following mapping:

  • rsp/photos/photo/title binds-to S_Photos.
  • rsp/photos/photo/id maps-to SP_Id.
  • rsp/photos/photo/farm maps-to SP_farm.
  • rsp/photos/photo/server maps-to SP_server.
  • rsp/photos/photo/secret maps-to SP_secret.

Then execute:

READXML("Output2.xml","NAME_OF_YOUR_XSD.axm");

You should now have a set S_Photos containing photo titles of the gallery and having for parameters the id, farm id, server id and secret of a photo.

Getting the photos

We know from the Flickr API Documentation: URLs the format a photo URL must have. This URL is different from the one displayed on your browser when you select the photo. This isn’t the URL of the page where we can find the photo but the URL of the photo itself.

https://farm{farm-id}.staticflickr.com/{server_id}/{id}_{secret}.jpg

Now we’ll set a GET request to the URL corresponding to each photo contained in the gallery, to obtain the photos. For that, we need some new objects:

../../_images/photoObjects.png
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
StringParameter SP_requestId {

}
Parameter P_responsecode {

}
StringParameter SP_URL {

}
StringParameter SP_responsefile{

}

The code of this procedure is as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
for p in S_Photos Do
    !set direction for the photos
    SP_OutputFile:="MainProject/WebUI/resources//images/"+SP_id(I_p)+".jpg";
    !create URLs
    SP_URL:="https://farm"+SP_farmId(p)+".staticflickr.com/"+SP_serverId(p)+"/"+SP_Id(p)+"_"+SP_secretId(p)+".jpg";
    !send request
    web::request_create(SP_requestId);
    web::request_setMethod(SP_requestId,"GET");
    web::request_setURL(SP_requestId,SP_URL);
    web::request_setResponseBody(SP_requestId,'File',SP_OutputFile);
    web::request_invoke(SP_requestId,P_responsecode);
endfor;

The choice to set the names of photo files using the SP_id(I_p) parameter is arbitrary. The result is that every file name is the ID of the concerned photo in Flickr. (If you chose to use title of photos, for example, unsupported special characters may be included.)

The choice of the destination MainProject/WebUI/resources//images/ refers to the use of WebUI image widget.

Congratulations, we finally reached our goal!

Now we can use the photos in AIMMS:

../../_images/final.png

Further information

The Flickr API also allows you to search for photos using tags with the flickr.photos.search method .

It will then send you back a list of photos identified by those tags with all the IDs you need to recreate their URL. And by mapping the data into AIMMS and making a GET request to the newly created URLs, you can get the photos. You will find the related code in the example project.

Note

Please note that you can only specify 20 tags at the same time, and the answer will contain only one page of results (max 500 photos).

References

Last Updated: October, 2019