flickrapi

A Node.js, and client-side, implementation of the Flickr API (for use with an API key, server-side oauth enabled)

npm install flickrapi
4 downloads in the last day
57 downloads in the last week
289 downloads in the last month

A Node.js, and client-side, implementation of the Flickr API

With oauth authentication for Flickr API keys if you're using it server-side (authenticated calls from the browser are too insecure to support for the moment, and will throw an error).

You also get API route proxying so you can call the Flickr methods through your own server and get Flickr responses back for free. Super handy.

How to use the client-side library

Script-load the browser/flickrapi.dev.js library during development work, and use the browser/flickrapi.js library in production.

You can access Flickr by creating an API instance as:

var flickr = new Flickr({
  api_key: "1234ABCD1234ABCD1234ABCD1234ABCD"
});

and then simply querying Flickr using the API as described over at http://www.flickr.com/services/api - for instance, to search for all photographs that text-match the terms "red panda", you would call:

flickr.photos.search({
  text: "red+panda"
}, function(err, result) {
  if(err) { throw new Error(err); }
  // do something with result
}

All calls are asynchronous, and the callback handling function always has two arguments. The first, if an error occurs, is the error generated by Flickr; the second, if the call succeeds, is the result sent back from Flickr, as plain JavaScript object.

Accessing an API proxy instead

Note that using a client-side library that requires your private credentials to be revealed is insanely insecure, bordering on plain stupid, so what you really want to do is have a middleman that the browser can call, and will take care of asking Flickr for the data inside an authenticated request and then sending the data back to the browser without even needing to expose any private credentials.

You want to use a proxy.

Good news: the flickrapi module will let you set one up for free (see further down for instructions on how to do this), so to make use of the proxied API, you can supply the Flickr construction with an endpoint property instead:

var flickr = new Flickr({
  endpoint: "http//localhost:3000/services/rest/"
});

Using a custom endpoint means that the library expects the endpoint to take care of all authentication, so if you use a custom endpoint there is no need to also supply your api key value. Even if you do, it'll get ignored.

how to use this package with Node.js

Access to the full API using authenticate

The initial require in your code is simply require("flickrapi") after making sure you added flickrapi to your package.json, either manually or by running npm install flickrapi --save for the project you're using it in.

Once available, you can authenticate with flickr, which will result in a callback that gives you the actual API object:

var Flickr = require("flickrapi"),
    flickrOptions = {
      api_key: "API key that you get from Flickr",
      secret: "API key secret that you get from Flickr"
    };
Flickr.authenticate(flickrOptions, function(error, flickr) {
  // we can now use "flickr" as our API object
});

calling API functions is then a matter of calling the functions as they are listed on http://www.flickr.com/services/api, so if you wish to get all your own photos, you would call:

flickr.photos.search({
  user_id: flickr.options.user_id,
  page: 1,
  per_page: 500
}, function(err, result) {
  // result is Flickr's response
});

All results are in JSON format. For obvious reasons.

Access to the full API using tokenOnly

There is also a function for creating Flickr API instances that can only call public API functions (or will only get public results for functions that may potentially access private results, too).

This does not require any oauth negotiation during setup:

var Flickr = require("flickrapi"),
    flickrOptions = {
      api_key: "API key that you get from Flickr",
      secret: "API key secret that you get from Flickr"
    };
Flickr.tokenOnly(flickrOptions, function(error, flickr) {
  // we can now use "flickr" as our API object,
  // but we can only call public methods and access public data
});

Results will also be in JSON format (naturally).

flickr.options

In addition to the standard Flickr functions, the flickr object also has an options property, which looks like this:

{
  api_key: "your API key",
  secret: "your API key secret",
  user_id: "your user id, based on your first-time authorisation",
  access_token: "the preauthorised Flickr access token",
  access_token_secret: "its corresponding secret",
  oauth_timestamp: "the timestamp for the last flickr API call",
  oauth_nonce: "the cryptographic nonce that request used",
  afterDownsync: <optional, you can bind an arg-less callback function here>
  permissions: <optional, default value is 'read', see "on first run" below>
}

Downloading all your Flickr stuffs

You can use this module to very easily download all your Flickr stuffs:

var Flickr = require("flickrapi"),
    flickrOptions = { ... };
Flickr.authenticate(flickrOptions, flickrapi.downsync());

That's all you need to run. This will generate a data directory with your images in ./data/images (in several sizes), and the information architecture (metadata, sets, collections, etc) in ./data/ia.

If you want this in a different directory, you can pass the dir as an argument to the downsync function:

var Flickr = require("flickrapi"),
    flickrOptions = { ... };
Flickr.authenticate(flickrOptions, flickrapi.downsync("userdata/me"));

This will now create a ./data for the flickr API information, but\ also a ./userdata/me/ directory that contains the images and ia dirs with your personal data.

FlickrMirror, available at https://github.com/Pomax/flickrmirror, bolts a UI on top of the FlickrAPI module to give you an instant frontend for your photographs and Flickr information about them.

One-step downsyncing

If you just want to immediately downsync all your data, simply use the test.js application with the --downsync runtime argument. Simply add your Flickr API key information to the .env file and then run

> node test --downsync

Done. Authenticate, and then just wait for it to finish. You now have a mirror of all your Flickr data.

Syncing with Flickr in your code

Syncing is a mostly a matter or running the downsync function again. This will update anything that was updated or added on Flickr, but will not delete anything from your local mirror that was deleted from Flickr unless specifically told to do so, by passing a second argument (internally known as the "removeDeleted" flag in the code) to the downsync function call:

var Flickr = require("flickrapi"),
    flickrOptions = { ... };
Flickr.authenticate(flickrOptions, flickrapi.downsync("userdata/me", true));

If true, this will delete local files that were removed on Flickr (e.g. photos that you didn't like anymore, etc). If false, or omitted, no pruning of the local mirror will be performed.

Using all your Flickr stuffs in an app

If you downloaded all your Flickr stuffs, you can use these in your own node apps by "dry loading" Flickr:

var Flickr = require("flickrapi"),
    flickrData = Flickr.loadLocally();

This will give you an object with the following structure:

{
  photos: [photo objects],
  photo_keys: [photo.id array, sorted on publish date],
  photosets: [set objects],
  photoset_keys: [set.id array, sorted on creation date],
  collections: [collection objects],
  collection_keys: [collection.id array, sorted on title],
}

Not sure what these objects look like? head over to your ./data/ia directory and just open a .json file in your favourite text editor.

On first run

Fetching the API

On first run, the package will fetch all known methods from Flickr, and cache them for future use. This can take a bit, as there are a fair number of methods, but is inconsequential on subsequent package loading.

Authenticating with Flickr

On first run, the authentication function will notice that there are no access_token and access_token_secret values set, and will negotiate these with Flickr using their oauth API, based on the permissions you request for your API key.

By default, the only permissions are "read" permissions, but you can override this by adding a permissions property to the options object:

  • permissions: "read" will give the app read-only access (default)
  • permissions: "write" will give it read + write access
  • permissions: "delete" will give it read, write and delete access

Running the app will show output such as the following block:

$> node app
{ oauth_callback_confirmed: 'true',
  oauth_token: '...',
  oauth_token_secret: '...' }
prompt: oauth_verifier: []

Once the app reaches this point it will open a browser, allowing you to consent to the app accessing your most private of private parts. On Flickr, at least. If you agree to authorize it, you will get an authorisation code that you need to pass so that the flickrapi can negotiate access tokens with Flickr. Doing so continues the program:

$> node app
{ oauth_callback_confirmed: 'true',
  oauth_token: '...',
  oauth_token_secret: '...' }
prompt: oauth_verifier: 123-456-789

Add the following variables to your environment:

export FLICKR_USER_ID="12345678%40N12"
export FLICKR_ACCESS_TOKEN="72157634942121673-3e02b190b9720d7d"
export FLICKR_ACCESS_TOKEN_SECRET="99c038c9fc77673e"

Add these variables to your environment, or put them in an .env file for use with process.env or the habitat package or the like, or put them straight into your source code to use the flickrapi:

var FlickrOptions = {
      api_key: "your API key",
      secret: "your API key secret",
      user_ud: "...",
      access_token: "...",
      access_token_secret: "..."
    }

The flickrapi package will now be able to authenticate with Flickr without constantly needing to ask you for permission to access data.

Using your own oauth callback endpoint

By default the oauth callback is set to "out-of-band". You can see this in the .env file as the FLICK_CALLBACK="oob" parameter, but if this is omitted the code falls back to oob automatically. For automated processes, or if you don't want your uers to have to type anything in a console, you can override this by setting your own oauth callback endpoint URL.

Using a custom callback endpoint, the oauth procedure will contact the indicated endpoint with the authentication information, rather than requiring your users to manually copy/paste the authentication values.

Note your users will still need to authenticate the app from a browser.

To use a custom endpoint, add the URL to the options as the callback property:

var options = ...;
options.callback: "http://.../...";
Flickr.authenticate(options, function(error, flickr) {
  ...
}

Adding an export FLICKR_CALLBACK="http://..." to your environment will automatically take care of this. The callback URL handler will at its minimum need to implement the following middleware function:

function(req, res) {
  res.write("");
  options.exchange(req.query);
}

However, having the response tell the user that authorisation was received and that they can safely close this window/tab is generally a good idea.

If you wish to call the exchange function manually, the object expected by options.exchange looks like this:

{
  oauth_token: "...",
  oauth_verifier: "..."
}

Custom authentication: browserless, noAPI, and silent

There are a number of special options that can also be set to effect different authentication procedures. Calling the authenticate function with an options object means the following options can also be passed:

options = {
  ...
  nobrowser: true, // console.logs the auth URL instead of opening a browser for it.
  noAPI: true,     // only performs authentication, without building the Flickr API.
  silent: true ,   // doesn't do an information console print after successful auth.
  ...
}

If using noAPI, the authentication credentials can be extracted from the options object inside the callback function that you pass along. The options.access_token and options.access_token_secret will contain the result of the authentication procedure.

Flickr API proxying for connect/express apps

If your app is a connect or express app, you get Flickr API proxying for free. Simply set it up and then call your own API route in the same way you would call the Flickr API, minus the security credentials, since the servers side Flickr api object already has those baked in.

As an example, the test.js script for node-flickrapi uses the following code to set up the local API route:

var express = require("express");
Flickr.authenticate(FlickrOptions, function(error, flickr) {
  var app = express();
  app.configure(function() {
    [...]
    flickr.proxy(app, "/service/rest");
  });
  [...]
});

All calls use the POST verb. To test the local API route, a simple cURL will do:

curl -X POST -H "Content-Type: application/json"
             -d '{"method":"flickr.photos.search", "text":"red+pandas"}'
             http://127.0.0.1:3000/service/rest/

Note that there is no user authentication baked in, so if you want to make sure only "logged in users" get to use that local API route, you'll need to pass an authentication middleware function as third argument to flickr.proxy:

function authenticator(req, res, next) {
  // assuming your session management uses req.session:
  if(req.session.authenticated) {
    return next();
  }
  next({status:403, message: "not authorised to call API methods"});
}

flickr.proxy(app, "/service/rest/", authenticator);

(Re)compiling the client-side library

You can run the node compile command to (re)generate a flickrapi.js client-side library, saved to the browser directory. This generates a sparse library that will let you call all public methods (but currently not any method that requires read-private, write, or delete permissions), but will not tell you what's wrong when errors occur.

If you need this information, node compile dev will generate a flickrapi.dev.js library that has all the information needed for developing work; simply use this during development and use the flickrapi.js library in production.

Note that no min version is generated; For development there is no sense in using one, and the savings on the production version are too small to matter (it's only 10kb smaller). If your server can serve content gzipped, the minification will have no effect on the gzipped size anyway (using gzip, the plain library is ~4.5kb, with the dev version being ~30kb).

Software that uses FlickrAPI

The most obvious application that uses this package is FlickrMirror, available at https://github.com/Pomax/flickrmirror, which mirrors your Flickr data and acts as alternative frontend for your photographs (and sets and collections) using a default styling based on the old Flickr look, but as open source so you can change the look and feel however you like.

npm loves you