Hackviking He killed Chuck Norris, he ruled dancing so he took up a new hobby…


Google Picasa API Python: Developers Guide

Before you ask... Yes I struggled with the title of this post, but give me a break it's 4:30 am here! ūüôā

I'm currently developing in python for Google App Engine and are using the Picasa API. I found this great guide from Google with exampels: https://developers.google.com/picasa-web/docs/1.0/developers_guide_python It's far from complete but the examples pushes me in the right direction and then some testing, trial and error gives me a chance to learn even more! So i thought I would share one of the things that got me in to trouble this morning.

I was trying to add a new album to the feed and got this error:

(404, 'Not Found', 'Unknown user.')

Even though the user is authenticated via oauth. But then i realized that this was the same issue I head before, the users e-mail isn't in the mix. I needed it for layout purposes before, to display profiles and so on, you can read about that here: Python: Get user info after oauth All the request I have done before, getting feeds of albums, pictures and so on, has been uri input from me in the code. This function just looks like this:

gd_client.InsertAlbum(title='Test', summary='a test album')

Where the gd_client is an instance of gdata.photos.service.PhotosService() with the oauth token all-ready specified using the code example from the official Google guide and spiced with the functions from my previous mentioned post. But still it doesn't work! So I realized that even though it is authorized it has no idea who the user is trying to insert the new album. According to the feed documentation you should do a post like this:

POST https://picasaweb.google.com/data/feed/api/user/userID

<entry xmlns='http://www.w3.org/2005/Atom'
<title type='text'>Trip To Italy</title>
<summary type='text'>This was the recent trip I took to Italy.</summary>
<media:keywords>italy, vacation</media:keywords>
<category scheme='http://schemas.google.com/g/2005#kind'

So here is what stuff goes wrong. Looking what the gd_client is actually doing is posting to https://picasaweb.google.com/data/feed/api/user/. There is a really simple soloution for this, if we return to the oauth example from the guide:

gd_client = gdata.photos.service.PhotosService()
gd_client.auth_token = authsub_token

This is a cut out where you get the "use once" token back and upgrade it to a session token. Here you can do two things to make the gd_client work with the oauth user as a default all the time, either:

gd_client = gdata.photos.service.PhotoService(email='default')


gd_client.email = 'default'

Then it all will work just fine!


Python: Get user info after oauth

Building webapps with Google APIs are pretty straight forward for the most part. Specially when using the Google API Client Libraries! But if you want to accomplish something that are outside of all the nice tutorials that Google supply us with it get's trickier! Being a C# programmer for many years I have noticed that there is loads of examples, tutorials and how-to write ups on the web for any and (almost) all problems I might run into. With the Google APIs and Google App Engine, not as much. I don't know why it should be pretty many people in that community willing to share?


I'm currently developing a web application running on Google App Engine that uses the Picasa Web API. User get's redirected to the oauth site to approve access and I get a token back, easy enough! Getting lists of albums, pictures and movies is easy but getting user info? I'm fairly new to both python and Google App Engine so I browsed around for a long while without finding any solution to what I wanted to do! So before going to bed, defeated, I published a question on stackoverflow: http://stackoverflow.com/questions/19473250/how-to-get-user-email-after-oauth-with-google-api-python-client

Usually you get pretty quick answers from your peers but this time, nothing! Again... I'm I the only one doing stuff like this? Doubt it!
So I needed to solve the issue my self, getting dirty!

Break it down...

So my problem was that I wanted the users profile information like email, name and so on. I started by reading the protocol definition for the Picasa Web API, found here: https://developers.google.com/picasa-web/docs/2.0/reference Soon I realized that what I needed wasn't even sent back to me. So I needed to request the information!

After some Googleing for the issue I found a couple of suggestions that I should use Google Contacts API and get the author field from my own contacts, not a pretty solution!

Went over to the OAuth 2.0 Playground to check out what feeds would help me get the user info. In the list on the playground I didn't find much! Some of the other services provided the information with there feeds but I wanted something that just replied the information that I wanted. So I went to the source, Google APIs Explorer. I found a couple of scopes that would fit my needs:

  • https://www.googleapis.com/auth/userinfo.email
  • https://www.googleapis.com/auth/userinfo.profile

Checking out the scopes

So over to the Oauth playground and tried them out to see what info I could get out of them.

Scope: https://www.googleapis.com/auth/userinfo.email

Request URL: https://www.googleapis.com/userinfo/v2/me


"id": "113303504361682404626",
"email": "puh.kallsbo@gmail.com",
"verified_email": true

More or less exactly what I was looking for, needed the e-mail to get the gravatar. But why stop here let's see what else is available...

Scope: https://www.googleapis.com/auth/userinfo.profile

Request URL: https://www.googleapis.com/userinfo/v2/me


"id": "113303504361682404626",
"name": "Kristofer Källsbo",
"given_name": "Kristofer",
"family_name": "Källsbo",
"link": "https://profiles.google.com/puh.kallsbo",
"picture": "https://lh3.googleusercontent.com/-n6hDipRgm5k/AAAAAAAAAAI/AAAAAAAAVYY/XZd9zlnMmGk/photo.jpg",
"gender": "male",
"locale": "en"

So this more or less gave me all the user info but not the e-mail. So combining this with the one above would be a good idea!

Getting down to business (python)

So now I knew where to find the information. But how do a I access it as well as the Picasa Web API? So if we start from this exampel: https://developers.google.com/picasa-web/docs/1.0/developers_guide_python?csw=1#AuthSub

def GetAuthSubUrl():
next = 'http://www.example.com/welcome.pyc'
scope = 'https://picasaweb.google.com/data/'
secure = False
session = True
gd_client = gdata.photos.service.PhotosService()
return gd_client.GenerateAuthSubURL(next, scope, secure, session);
authSubUrl = GetAuthSubUrl();
print '&lt;a href="%s"&gt;Login to your Google account&lt;/a&gt;' % authSubUrl

So we need to add an additional scope for the user to authorize. Instead of passing a string as the scope variable we can pass a list of strings like this:

scope = ['https://picasaweb.google.com/data/', 'https://www.googleapis.com/auth/userinfo.email']

That will generate a token that is valid for both scopes! Following the example about the Picasa Web API we go ahead and retrieve a list of the users albums, but then what?

#Setup a basic gdata client
userClient = gdata.client.GDClient()
#Create a gauth sub token object from the session token we allready have in the gd_client
oauthToken = gdata.gauth.AuthSubToken(gd_client.GetAuthSubToken())
#Get the request, this userinfo is in json
response = userClient.request('GET','https://www.googleapis.com/userinfo/v2/me', oauthToken)
#Parse the webresponse
jobj = json.loads(response.read())
self.response.write('Your email is: {0}'.format(jobj['email']))

We start a gdata client and use that to retrieve the json. Line by line we actually doing the following:

userClient = gdata.client.GDClient() - Just creating an instanse of the Gdata client.

oauthToken = gdata.gauth.AuthSubToken(gd_client.GetAuthSubToken()) - Retrieving the OAuth token all ready used in the gd_client for the Picasa Web Albums. To be able to use it in the Gdata client we have to pass it as an object of type AuthSubToken or similar.

response = userClient.request('GET','https://www.googleapis.com/userinfo/v2/me', oauthToken) - Will return a standard python httplib HTTPResponse with the data returned from the server.

jobj = json.loads(response.read()) - The .read() function returns the body of the HTTPResponse object that we then can parse into a json object.

self.response.write('Your email is: {0}'.format(jobj['email'])) - Finally we have the users e-mail to do what we need to display profile info and so on...


Not all the documentation is great when it comes to Google APIs and Google App Engine. I have been programming sense the age of 8 so I usually find my way through it but I realize that this isn't a beginners language or field. On the other hand all the technical info is there like protocol specifications and stuff like that. Then there is some great tools to try the API out like OAuth playground. I hope this helps someone and a complete demo project for Google App Engine is available on Google Code, link below.



Picasa Web Downloader Source

Had a few downloads of the Picasa Web Downloader that I put up yesterday. Also had a few request of the source code, people seem to be nervous about putting there login information into an application that isn't open source.

So now it is open source available at: https://code.google.com/p/picasa-web-downloader/
Compiled and readu to run:


Picasa Web Downloader

I store all my memories on Picasa! Even spent a lot of time to scan all old pictures and upload them. Trusting a provider to keep your data safe from data loss is something that doesn't make me sleep well at night. Even though I trust the guys at Google to take care of the data I want a backup. Before I used Backupify.com but they don't provide this service anymore. The Picasa application it self is really bad! Maybe if your an old iTunes user you can figure out how it works? All kidding aside... It actually didn't manage to download all my pictures and got some strange errors. So I looked around the internet for a third party application for downloading all my content but I couldn't find anything useful!

I did how ever find a great application named Picasa Web Sync (http://www.geekytidbits.com/picasawebsync/) written by Brady Holt. Great peace of software for syncing up to Picasa but not the way I want to do it! So i started to check out the API for developing my own application, I took a quick look at the Google API Client Libraries. Not that surprising the java and python libraries was awesome and complete. The .Net C# however is not that good! There are things missing and stuff that doesn't work, spelling mistakes and so on. Google usually delivers above and beyond but in this case not so much.

How ever I started to code and used what I could from the client libraries, mostly to parse the feeds from the API. Then I realized there was a load of videos in my albums so I started to try to download them. Nothing in the documentation, that I could find anyway. But I found a way to do it and now I have a complete offline backup of my Picasa Web Albums, on a USB drive... Encrypted of course!

So the first working version of this console application is available for download! Written in c# and source will be posted soon for those who like that.