OAuth 2.0, Python & Google Data APIs

 

Since March of this year, Google has supported OAuth 2.0 for many APIs, including Google Data APIs such as Google Calendar, Google Contacts and Google Documents List. Google’s implementation of OAuth 2.0 introduces many advantages compared to OAuth 1.0 such as simplicity for developers and a more polished user experience.

We’ve just added support for this authorization mechanism to the gdata-python-client library– let’s take a look at how it works by retrieving an access token for the Google Calendar and Google Documents List APIs and listing protected data.

Getting Started

First, you will need to retrieve or sync the project from the repository using Mercurial:

hg clone https://code.google.com/p/gdata-python-client/

For more information about installing this library, please refer to the Getting Started With the Google Data Python Library article.

Now that the client library is installed, you can go to your APIs Console to either create a new project, or use information about an existing one from the API Access pane:

Getting the Authorization URL

Your application will require the user to grant permission for it to access protected APIs on their behalf. It must redirect the user over to Google’s authorization server and specify the scopes of the APIs it is requesting permission to access.

Available Google Data API’s scopes are listed in the Google Data FAQ.

Here’s how your application can generate the appropriate URL and redirect the user:

import gdata.gauth

# The client id and secret can be found on your API Console.
CLIENT_ID = ''
CLIENT_SECRET = ''

# Authorization can be requested for multiple APIs at once by specifying multiple scopes separated by # spaces.
SCOPES = ['https://docs.google.com/feeds/', 'https://www.google.com/calendar/feeds/']  
USER_AGENT = ''

# Save the token for later use.
token = gdata.gauth.OAuth2Tokens(
   client_id=CLIENT_ID, client_secret=CLIENT_SECRET, scope=' '.join(SCOPES),
   user_agent=USER_AGENT)

# The “redirect_url” parameter needs to match the one you entered in the API Console and points
# to your callback handler.
self.redirect(
    token.generate_authorize_url(redirect_url='http://www.example.com/oauth2callback'))

If all the parameters match what has been provided by the API Console, the user will be shown this dialog:

When an action is taken (e.g allowing or declining the access), Google’s authorization server will redirect the user to the specified redirect URL and include an authorization code as a query parameter. Your application then needs to make a call to Google’s token endpoint to exchange this authorization code for an access token.

Getting an Access Token

import atom.http_core

url = atom.http_core.Uri.parse_uri(self.request.uri)
if 'error' in url.query:
  # The user declined the authorization request.
  # Application should handle this error appropriately.
  pass
else:
# This is the token instantiated in the first section.
  token.get_access_token(url.query)

The redirect handler retrieves the authorization code that has been returned by Google’s authorization server and exchanges it for a short-lived access token and a long-lived refresh token that can be used to retrieve a new access token. Both access and refresh tokens are to be kept private to the application server and should never be revealed to other client applications or stored as a cookie.

To store the token object in a secured datastore or keystore, the gdata.gauth.token_to_blob() function can be used to serialize the token into a string. The gdata.gauth.token_from_blob() function does the opposite operation and instantiate a new token object from a string.

Calling Protected APIs

Now that an access token has been retrieved, it can be used to authorize calls to the protected APIs specified in the scope parameter.

import gdata.calendar.client
import gdata.docs.client

# Access the Google Calendar API.
calendar_client = gdata.calendar.client.CalendarClient(source=USER_AGENT)
# This is the token instantiated in the first section.
calendar_client = token.authorize(calendar_client)
calendars_feed = client.GetCalendarsFeed()
for entry in calendars_feed.entry:
  print entry.title.text

# Access the Google Documents List API.
docs_client = gdata.docs.client.DocsClient(source=USER_AGENT)
# This is the token instantiated in the first section.
docs_client = token.authorize(docs_client)
docs_feed = client.GetDocumentListFeed()
for entry in docs_feed.entry:
  print entry.title.text

The Art Of Google Maps

InstaEarth

Instagram is an exciting photography tool, but what really takes Instagram to the next level are applications like InstaEarth from Modea. InstaEarth is an easy way to search for and discover Instragram users and photos on a map. The application makes use of the Places API with Autocomplete to help users to search around a landmark or address. From InstaEarth, “InstaEarth is a way to discover and view beautiful Instagram photography taken around the world. View your feed, friends’ feeds, popular photos, or navigate the map and explore the world through the eyes of Instagrammers everywhere.”

TeleGeography – Submarine Cable Map

When you make a phone call or send an email abroad, most of the time that data travels by way of submarine cables. Submarine cables are the backbone of the global economy, so it’s fascinating to spend time exploring a map that shows where these cables are located. In addition to being a really interesting, fun, and a great looking map, this map is also technically savvy application. Each line representing a submarine cable is clickable and when selected grays out the other cables for better visibility. The map also uses Styled Maps to help the cables stand out better and Fusion Tables to help manage the data on the back-end.

DART St. Louis

There are two things I love to geek out on: maps and photography. That’s why I love this map from DART St. Louis. From their website, “In April 2011 over 250 creative St. Louisans gathered to throw darts at a huge map of the City of St. Louis. Participants then had one month to visit the area where their dart landed and make a photograph. The resulting collection of photographs shows a snapshot of St. Louis as it is today, one random block at a time.”

Berliner Morgenpost – Berlin Elections Map

This month we have yet another great map from Germany. Using Fusion Tables, Berliner Morgenpost mapped out the results of the September 2011 Berlin elections. Voting districts are colored coded by which political party received the majority of votes. Additionally, you can click on any one of the voting districts which will display an infowindow with a chart of the full voting results. This an excellent example of Google Maps API supporting the democratic process and bringing better transparency to government.

Dodge Journey Search

To promote the new Dodge Journey, Dodge is running a competition on YouTube where users can win one of three brand new Dodge Journeys. Video clues are released on YouTube to help users track down the secret location of the vehicle and if they find it, they own it. The clues are related to places in the real world, so users can rely on Google Maps and Places to help them figure out where the car is located. The Maps API serves as the hub of information for this competition and uses Styled Maps to match Dodge branding along with the Places API with Autocomplete to help users follow up on clues.

By Carlos Cuesta, Geo APIs Product Marketing Manager

Google Plus: Monetizing games

Kabam was part of the initial launch of Google+ Games with two game titles, Dragons of Atlantis and Edgeworld, and we recently added Global Warfare. For these games, we integrated Google In-App Payments and we’re pleased with our games’ monetization to date. There are a couple things we learned along the way that we’re happy to share with the community.

Integrating In-App Payments

Integrating In-App Payments in our games was very simple, especially when compared to other payment platforms. There is excellent documentation available, complete with examples for each step of the purchase flow. We also used open-source libraries such as ruby-jwt to generate the tokens required for each purchase option.

We designed our games and purchase pages around the expectation of instant feedback, making sure to incorporate page loads or refreshes wherever possible. For example, in Edgeworld, a player attacking an enemy base can load the list of Platinum options instantly, without waiting for the list of payment options to load. After their Platinum purchase, the player is immediately brought back to the game, with their new currency and items waiting for them.

Pro tip: strive to reduce purchaser friction

One of the keys to maximizing revenue is to remove as much friction as possible from the purchase flow, making sure as many people as possible get from one step of the flow to the next. Many payment platforms send players to their own website and multi-page checkout flow. The Google In-App Payments approach allows us to keep players on our game page for the entire flow, making sure we can manage more of the process and reduce abandonment.

Additionally, the player’s credit card information is stored securely, so once a player has made a purchase anywhere using In-App Payments, their information is available for future purchases without additional data entry. Finally, JavaScript callbacks provided by In-App Payments allow us to show the effects of the purchase immediately, improving customer satisfaction.