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

21Oct/135

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?

Background

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

Response:

{
"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

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 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 '<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 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())
#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 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...

Conclusion

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.

Links

Comments (5) Trackbacks (1)
  1. Finding this post has been a lifesaver!

  2. Thank you very much for this article. Scope and Request URI is exactly what I needed.

  3. Thanks for this article, that was very helpful.

  4. Ok, you are the boss still in 2016…


Leave a Reply