Introduction
Building web apps with Google APIs
is pretty straightforward for the most part. Specially when using the Google API Client Libraries! But if you want to accomplish something that is outside of all the nice tutorials that Google supplies us with, it gets trickier! Being a C# programmer for many years, I have noticed that there are 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
with pretty many people in that community willing to share?
Background
I'm currently developing a web application running on Google App Engine that uses the Picasa Web API. User gets 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 here.
Usually, you get pretty quick answers from your peers but this time, nothing! Again... I'm the only one doing stuff like this? Doubt it! So I needed to solve the issue myself, 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. Soon I realized that what I needed wasn't even sent back to me. So I needed to request the information!
After some Googling 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!
I went over to the OAuth 2.0 Playground to check out what feeds would help me get the user information. In the list on the playground, I didn't find much! Some of the other services provided the information with their 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:
Checking Out the Scopes
So over to the OAuth playground and tried them out to see what information I could get out of them.
Scope: https://www.googleapis.com/auth/userinfo.email
Request URL: https://www.googleapis.com/userinfo/v2/me
Response:
{
"id": "113303504361682404626",
"email": "puh.kallsbo@gmail.com",
"verified_email": true
}
More or less exactly what I was looking for, I 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
Response:
{
"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 information, 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 I access it as well as the Picasa Web API? So if we start from this example:
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 '<a href="%s">Login to your Google account</a>' % 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 string
s 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 already 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())
#Display
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 do the following:
userClient = gdata.client.GDClient()
Just creating an instance of the Gdata
client.
oauthToken = gdata.gauth.AuthSubToken(gd_client.GetAuthSubToken())
Retrieving the OAuth token already 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 information and so on...
Conclusion
Not all the documentation is great when it comes to Google APIs and the Google App Engine. I have been programming since 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 information is there like protocol specifications and stuff like that. Then there are 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. Please see the links below.
Links