This API has been shut down and is no longer available. Migrate to Google Photos Library API to avoid disruptions to your application.

Developer's Guide: Python

Picasa Web Albums allows client applications to view and update albums, photos, and comments in the form of Google Data API feeds. Your client application can use the Picasa Web Albums Data API to create new albums, upload photos, add comments, edit or delete existing albums, photos, and comments, and query for items that match particular criteria.

In addition to providing some background on the capabilities of the Picasa Web Albums Data API, this guide provides examples for interacting with the API using the Python Google Data APIs Client Library. For help setting up the client library, see the Getting Started Guide.

If you're interested in understanding more about the underlying protocol used by the Python client library to interact with the Picasa Web Albums API, please see the protocol guide.


This document is intended for programmers who want to write client applications using the Google Data APIs Python client library that can interact with Picasa Web Albums.

Getting Started

Picasa Web Albums uses Google Accounts for authentication, so if you have a Google account you are all set. Otherwise, you can create a new account.

For help setting up the client library, see the Getting Started Guide. To use the Python client library, you'll need Python 2.2 or higher and the modules for Element Tree (which are included in Python 2.5 and higher). After downloading the client library, you will need to install the gdata and atom packages or copy them to your working directory so that they can be found by the interpreter when the modules are imported.

To run the examples in this document, you'll need the following import statements:

import gdata.geo

The PhotosService class represents a client connection (with authentication) to the Picasa Web Albums web service.


The Python client library can be used to work with either public or private feeds. Public feeds are read-only, but do not require any authentication. Private feeds require that you authenticate to the Picasa Web Albums servers. This can be done via ClientLogin username/password authentication or AuthSub proxy authentication.

Please see the Google Data APIs authentication documentation for more information on AuthSub and ClientLogin.

Single-user "installed" client authentication

To use ClientLogin (also called "Authentication for Installed Applications"), invoke the ProgrammaticLogin method of PhotosService, specifying the ID and password of the user on whose behalf your client is sending the query. For example:

gd_client = = email
gd_client.password = password
gd_client.source = 'exampleCo-exampleApp-1'

Once the ClientLogin token has been received, it will be used to authenticate each request made using this service object.

Note that the service name for the Picasa Web Albums API is "lh2".

For more information about Google's authentication systems, see the Google Account Authentication documentation.

Multiple-user web application client authentication

AuthSub proxy authentication is used by web applications which need to authenticate their users to Google accounts. The operator does not need access to the username and password for the user - only special AuthSub tokens are required.

When the user first visits your application, they have not yet been authenticated. In this case, you need to print some text and and a link directing the user to Google to authenticate your request for access to their photos. The Python Google Data APIs client library provides a function to generate this URL. The code below sets up a link to the AuthSubRequest page.

def GetAuthSubUrl():
  next = ''
  scope = ''
  secure = False
  session = True
  gd_client =
  return gd_client.GenerateAuthSubURL(next, scope, secure, session);

authSubUrl = GetAuthSubUrl();
print '<a href="%s">Login to your Google account</a>' % authSubUrl

Notice the parameters sent to the GenerateAuthSubURL method:

  • next, the URL of the page that Google should redirect the user to after authentication.
  • scope, indicating that the application is requesting access to the Picasa Web Albums feed.
  • secure, indicating that the token returned will not be a secure token.
  • session, indicating this token can be exchanged for a multi-use (session) token.

The URL looks something like this:

The user can then follow the link to Google's site and authenticate to their Google account.

After the user authenticates, they will be redirected back to the next URL. The URL will have a single-use token value appended to it as a query parameter. The URL looks something like this:

Upgrading to a session token

For security, this token is single-use only, so now you need to exchange this single-use token for a session token. This process is described in the AuthSub documentation. The following code snippet shows how to upgrade the token.

gd_client =
gd_client.auth_token = authsub_token

In this snippet, the authsub_token variable contains the value from the token query parameter in the URL. There are several ways to retrieve this value, for example:

import cgi
parameters = cgi.FieldStorage()
authsub_token = parameters['token']

This token value represents a single-use AuthSub token. Since session = True was specified above, this token can be exchanged for an AuthSub session token using the UpgradeToSessionToken method, which calls the AuthSubSessionToken service.

Working with Albums

Albums are the way Picasa Web Albums groups photos into useful sets. These albums can be public or unlisted, and have their own properties such as a geographic location, a description, or a date.

You do not have to authenticate to retrieve data about public albums, but in order to create, update, or delete content you must authenticate using one of the methods discussed in the authentication section.

Request a list of albums

You can retrieve all of a user's albums by using the GetUserFeed method.

If you do not specify a username, the string 'default' will be used and the server will use the username of the user whose credentials were used to create the auth token used in the request.

albums = gd_client.GetUserFeed(user=username)
for album in albums.entry:
  print 'title: %s, number of photos: %s, id: %s' % (album.title.text,
      album.numphotos.text, album.gphoto_id.text)

The above code retrieves all of the user's albums and prints out a list of them. It also prints the number of photos inside of each album, and the album's unique identifier.

The unique identifier is important, as it allows you to identify the album in future requests.

Add an album

Albums can also be created using the API. If you want to create a new album for the authenticated user, then you can use the following:

album = gd_client.InsertAlbum(title='New album', summary='This is an album')

This code will create a new album named "New album" with the description of "This is an album."

Modify the properties of an album

Once an album entry is retrieved, it can be easily modified using the Put method.

album.title.text = 'new album title';
updated_album = gd_client.Put(album, album.GetEditLink().href,

Delete an album

Retrieved entries can also be deleted using the Delete method.


Working with Photos

When uploading, modifying, or removing photos, you will have to authenticate using one of the methods discussed in the Authentication section.

Request a list of photos

There are different ways to retrieve photos. The most common is to get a list of all of the photos in an album, but you can also retrieve recent photos from a user, or search photos from the public albums of other users.

List photos in album

This is the basic query to retrieve all of the photos belonging to username in the albumname album. The title of each photo is then printed out to the console.

You may use the string 'default' for the username instead of a user's email address. When 'default' is used, the server will use the username of the user who is authenticated in the request. This code assumes that 'album' is an entry that represents an album, as shown previously.

photos = gd_client.GetFeed(
    '/data/feed/api/user/%s/albumid/%s?kind=photo' % (
        username, album.gphoto_id.text))
for photo in photos.entry:
  print 'Photo title:', photo.title.text

List photos recently uploaded

It is also possible to retrieve the photos associated with a user, but without specifying any particular album. The following example retrieves the last 10 photos uploaded by username and prints their titles.

photos = gd_client.GetUserFeed(kind='photo', limit='10')
for photo in photos.entry:
  print 'Recently added photo title:', photo.title.text

List photos by community search

With the API, you can search photos uploaded by other users, as long as they are in a public album. The following code retrieves 10 photos matching a search for 'puppy' and prints out their titles.

photos = gd_client.SearchCommunityPhotos('puppy', limit='10')
for photo in photos.entry:
  print 'Community photo title:', photo.title.text

Accessing photo information

In previous examples, only the title of a photo was printed out. However, there is a lot of different data that can be retrieved about a photo such as Exif information, thumbnail URLs, the ID of the album it is a part of, and more.

print 'AlbumID:', photo.albumid.text
print 'PhotoID:', photo.gphoto_id.text
if photo.exif.make and photo.exif.model:
  camera = '%s %s' % (photo.exif.make.text, photo.exif.model.text)
  camera = 'unknown'
print 'Camera:', camera
print 'Content URL:', photo.content.src
print 'First Thumbnail:',[0].url

The above example prints out different pieces of information from a PhotoEntry. The thumbnail and image URLs are taken from the MediaRSS elements inside of the entry. The camera data, if available, is found inside of the Exif namespace.

Post a new photo

You can upload a photo to Picasa Web Albums using the InsertPhotoSimple method of the PhotosService object. The following demonstrates an example with a few assumptions: username is the name of the user who owns the album and that we have authenticated as (you can also use 'default'), album is an album object that represents the album to upload the photo to, filename is the path to the file on the local disk, gd_client is an authenticated PhotosService object, and 'image/jpeg' is the valid MIME type of the file to be uploaded.

album_url = '/data/feed/api/user/%s/albumid/%s' % (username, album.gphoto_id.text)
photo = gd_client.InsertPhotoSimple(album_url, 'New Photo', 
    'Uploaded using the API', filename, content_type='image/jpeg')

Notice that you did not specify tags or any other sort of meta-data about the photo when it was uploaded. To do this, you can either use InsertPhoto and pass in a PhotoEntry or you can add the meta-data after the photo has been created by update the entry you received back from the server, which leads into the Update a photo section. A call to InsertPhoto might look something like this:

photo = gd_client.InsertPhoto(album_url, new_entry, filename, 

For an example of how metadata can be added to the new_entry, see the next section describing how to Update a photo.

If you want to post a photo, but don't want the hassle of requiring the user of your app to choose an album, you can post the photo to the 'Drop Box.' This special album will automatically be created the first time it is used to store a photo. To post to the 'Drop Box,' use an albumid value of 'default'. In the Python client library, your code would look like:

photo = gd_client.InsertPhotoSimple(
    '/data/feed/api/user/default/albumid/default', 'New Photo', 
    'Uploaded using the API', filename, content_type='image/jpeg')

Update a photo

Usually, you want to set up some meta-data when you are uploading photos. This example will give the photo a title, a caption, some tags, and geographic location. Notice that we are adding three tags (foo, bar, and baz) all at the same time using the <media:keywords> element.

photo.title.text = 'edited title'
photo.summary.text = 'edited summary'
if not =
if not = = 'foo, bar, baz'
if not photo.geo:
  photo.geo = gdata.geo.Where()
if not photo.geo.Point:
  photo.geo.Point = gdata.geo.Point()
photo.geo.Point.pos = gdata.geo.Pos(text='%s %s' % ('45', '-45'))
updated_entry = gd_client.UpdatePhotoMetadata(entry)

Delete a photo

Deleting a photo is done by using the Delete method.


Working with Tags

Tags are a convenient way to label and organize your photos. By associating photos with descriptive strings, it makes searching through large quantities of photos easier.

Retrieving a list of tags

Your program can retrieve a list of tags that are used by a user, in a particular album, or that are associated with a particular photo.

List tags by user

The following code will print out all of the tags that username has used in photos in their albums.

The string 'default' can be used in place of a real username, in which case the server will use the username of the user credentials used to authenticate the request.

tags = gd_client.GetFeed('/data/feed/api/user/%s?kind=tag' % username)
for tag in tags.entry:
  print 'Tag', tag.title.text

List tags by album

The following code will print out all of the tags that username has tagged photos with in the album album.

tags = gd_client.GetFeed('/data/feed/api/user/%s/albumid/%s?kind=tag' % (username, album.gphoto_id.text))
for tag in tags.entry:
  print 'Tag', tag.title.text

List tags by photo

The following code will print out all of the tags that username has tagged the photo photo with in the album album. See the Accessing photo information section for information on obtaining a reference to a photo.

tags = gd_client.GetFeed('/data/feed/api/user/%s/albumid/%s/photoid/%s?kind=tag' % (username, album.gphoto_id.text, photo.gphoto_id.text))
for entry in feed.entry:
  print 'Tag', entry.title.text

Note that this same information is available inside of the <media:keywords> element of the photo itself in a comma separated format.

Search photos using tags

The following code uses the tag parameter to search for all photos belonging to username that are tagged with both "foo" and "bar".

photos = gd_client.GetTaggedPhotos('foo,bar', user=username)
for photo in photos.entry:
  print 'Title of tagged photo:', photo.title.text

Note you could search for photos in a particular album by using GetFeed with a URL that looks like this: '/data/feed/api/user/%s/albumid/%s?kind=photo&tag=%s' % (username, album.gphoto_id.text, tag.lower()).

Adding a tag to a photo

The following code adds the tag "foo" to the photo, in the album which is owned by username.

url = '/data/feed/api/user/%s/albumid/%s/photoid/%s' % (username, album.gphoto_id.text, photo.gphoto_id.text)
tag = gd_client.InsertTag(url, 'foo')

Note that this can also be done in bulk as described in the Update a photo section using the <media:keywords> element.

Deleting a tag from a photo

Deleting a tag is done by using the Delete method.


Working with Comments

Comments are short text snippets attached to photos by Picasa Web Albums users.

Retrieving a list of comments

The following example prints out the 10 most recent comments on a username's photos.

The string 'default' can be used in place of a real username, in which case the server will use the username of the user credentials used to authenticate the request.

comments = gd_client.GetFeed('/data/feed/api/user/%s?kind=comment&max-results=10' % username)
for comment in comments.entry:
  print 'Comment', comment.content.text

List comments by photo

You can also retrieve all of the comments associated with a particular photo. The following example prints out all of the comments on the photo identified by photo, inside of the album album, owned by the username user.

comments = gd_client.GetFeed(
    '/data/feed/api/user/%s/albumid/%s/photoid/%s?kind=comment&max-results=10' % (
        username, album.gphoto_id.text, photo.gphoto_id.text))
for comment in comments.entry:
  print 'Comment', comment.content.text

Add comments to a photo

The following code adds the comment "great photo!" to the photo identified by photo in the album owned by username.

url = '/data/feed/api/user/%s/albumid/%s/photoid/%s' % (username, album.gphoto_id.text, photo.gphoto_id.text)
comment = gd_client.InsertComment(url, 'great photo!')

Delete a comment from a photo

Deleting a comment is done by using the Delete method.



This complete example code demonstrates retrieving all the albums for the currently authenticated user, iterating through the photos in each album, displaying the photo's title, and any associated tags and comments.


import gdata.geo

gd_client = = '=change='     # Set your Picasaweb e-mail address...
gd_client.password = '=change='  # ... and password
gd_client.source = 'api-sample-google-com'

albums = gd_client.GetUserFeed()
for album in albums.entry:
  print 'Album: %s (%s)' % (album.title.text, album.numphotos.text)

  photos = gd_client.GetFeed('/data/feed/api/user/default/albumid/%s?kind=photo' % (album.gphoto_id.text))
  for photo in photos.entry:
    print '  Photo:', photo.title.text

    tags = gd_client.GetFeed('/data/feed/api/user/default/albumid/%s/photoid/%s?kind=tag' % (album.gphoto_id.text, photo.gphoto_id.text))
    for tag in tags.entry:
      print '    Tag:', tag.title.text

    comments = gd_client.GetFeed('/data/feed/api/user/default/albumid/%s/photoid/%s?kind=comment' % (album.gphoto_id.text, photo.gphoto_id.text))
    for comment in comments.entry:
      print '    Comment:', comment.content.text


Back to top