Pragmatism in the real world

Updating Flickr metadata using Python

I usually use my rodeo app to upload photos to Flickr, but for various reasons, I recently uploaded some photos directly via Flickr itself.

One feature of rodeo that I really like is that it sets the date posted to be the same as date taken which means that they are ordered correctly in my photo stream. As this doesn’t automatically, I knocked up a Python script to fix these photos for me.

The key to this is the flickrapi package which makes it easy to integrate with Flickr. Firstly you need an API key, which is obtainable at Flickr Services.

This gives you a key and secret for your app and you can then create the FlickrAPI object:

flickr = flickrapi.FlickrAPI(API_KEY, API_SECRET, format='json')

I also set the format to JSON as the default is XML and no-one wants that in 2023!

Next we need the user to authorise our script to write to their photos in order to update the date. This is OAuth and flickrapi does all the hard work and this is trivial:

flickr.authenticate_via_browser(perms='write')

This opens a new browser window and allows the user to authorise. It then stores the token in a cache in ~/.flickr so that next time, the user doesn’t have re-auth, which makes for a much nicer experience.

We then have to read a given photo’s date taken and set its date posted. This is a two step process. Firstly we get the photo’s info and extract the date taken. This is in Y-m-D format, but as we need it as a unix timestamp for the date_posted property, we convert it. Setting the date is then a simple call to setDates():

# Get date taken from photo
res = flickr.photos.getInfo(photo_id=photo_id)
photo_info = json.loads(res.decode('utf-8'))
date_taken = photo_info['photo']['dates']['taken']
date_taken_unix = int(datetime.strptime(date_taken, '%Y-%m-%d %H:%M:%S').strftime("%s"))

# Set date posted to date taken
flickr.photos.setDates(photo_id=photo_id, date_posted=date_taken_unix)

That’s it. There’s some stuff around argument handling so that we can pass in a list of IDs and that’s about it.

This is the entire script:

sync-flickr-dates.py:

import argparse
import flickrapi
import json
import os

from datetime import datetime

API_KEY = os.getenv('FLICKR_API_KEY')
API_SECRET = os.getenv('FLICKR_API_SECRET')

def set_posted_date(flickr, photo_id):
    # Get date taken
    res = flickr.photos.getInfo(photo_id=photo_id)
    photo_info = json.loads(res.decode('utf-8'))
    date_taken = photo_info['photo']['dates']['taken']
    date_taken_unix = int(datetime.strptime(date_taken, '%Y-%m-%d %H:%M:%S').strftime("%s"))

    # Set date posted to date taken
    flickr.photos.setDates(photo_id=photo_id, date_posted=date_taken_unix)
    print(f'Date posted for photo {photo_id} set to {date_taken}.')


def main():
    # Setup argument parser
    parser = argparse.ArgumentParser(
        description='Set the date uploaded to the same as the date taken for a Flickr photo.')
    parser.add_argument('photo_ids', help='Comma-separated IDs of the photos to adjust date.')
    args = parser.parse_args()

    # Create Flickr API object
    flickr = flickrapi.FlickrAPI(API_KEY, API_SECRET, format='json')
    # Allow user to authorise us to write to their photos
    flickr.authenticate_via_browser(perms='write')

    # Set upload date to created date
    photo_ids = args.photo_ids.split(',')
    for photo_id in photo_ids:
        set_posted_date(flickr, photo_id.strip())


if __name__ == '__main__':
    main()

One thought on “Updating Flickr metadata using Python

  1. Great article! I'm definitely going to try this out. I've been looking for a way to update my Flickr metadata without having to go through the tedious process of manually editing each photo. This looks like a game-changer. Thanks for sharing!

Comments are closed.