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

23Sep/143

Pros and cons with WordPress on Google App Engine

Running WordPress on Google App Engine is possible but different from any other hosting you ever used. Stability and performance are really great but it comes at the price of flexibility. In return you get a highly scalable and robust solution for your website. After running a few months on Google App Engine platform I switched again and in this article I will tell you why.

Continue reading...

30Jun/140

Migrate WordPress to Google App Engine

Wordpress on Google App Engine

Why not run WordPress on Google App Engine? You will get performance and stability while only paying for the resources you actually use. Reading the official Google tutorial "Running WordPress in App Engine" it gives you a fare idea what you are in for. But if you want to migrate a currently running site then you have to do some tweaking. So here is a run down on how to do it!

Continue reading...

1Feb/143

Python: Remove querystring from URL

Needed to clean an URL from it's querystring in Python. Found a lot of examples telling me to use urlparse and then put all the bits and pieces back together. An easier and more efficient  way is this:

url = 'http://www.hackviking.com/?var=value'
url = url[:url.find('?')]

url now reads 'http://www.hackviking.com/'

30Oct/130

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'
xmlns:media='http://search.yahoo.com/mrss/'
xmlns:gphoto='http://schemas.google.com/photos/2007'>
<title type='text'>Trip To Italy</title>
<summary type='text'>This was the recent trip I took to Italy.</summary>
<gphoto:location>Italy</gphoto:location>
<gphoto:access>public</gphoto:access>
<gphoto:timestamp>1152255600000</gphoto:timestamp>
<media:group>
<media:keywords>italy, vacation</media:keywords>
</media:group>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/photos/2007#album'></category>
</entry>

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
gd_client.UpgradeToSessionToken()

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')

or

gd_client.email = 'default'

Then it all will work just fine!

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