Unifying OAuth operations between gdata and new Google APIs

I work with the Google Contacts API and the Google Calendar API in Python. The first is the GData API, and the last is the Google API API ... so that although clients are available, each one is covered by separate clients - here is GData and the Google API .

The problem that I encounter working with these clients is that both have their own way of communicating with OAuth2. GData library provides methods gdata.gauth.token_to_blob(auth_token)and gdata.gauth.token_from_blob(auth_token)to transfer tokens authentication to / from strings to store in the database, while the google-api library provides a method Engine the App (the platform on which I am writing) for storing data OAuth credentials.

I don’t see a clear way to save one thing (be it an access token or credentials) available for both APIs, but I really do not want users to double-authenticate. Is there any way to do this, with the exception of feeds in Google client libraries and writing direct HTTP calls?

+1
source share
2 answers

I was able to get the next job. It uses oauth2decoratorto do the hard work, and then uses a small helper class TokenFromOAuth2Credsto apply the same credentials to the gdata client.

, gdata, - .

import webapp2
import httplib2
from oauth2client.appengine import oauth2decorator_from_clientsecrets
from apiclient.discovery import build

import gdata.contacts.client

decorator = oauth2decorator_from_clientsecrets(
  "client_secrets.json",
  scope=["https://www.google.com/m8/feeds", "https://www.googleapis.com/auth/calendar.readonly"]
)


# Helper class to add headers to gdata
class TokenFromOAuth2Creds:
  def __init__(self, creds):
    self.creds = creds
  def modify_request(self, req):
    if self.creds.access_token_expired or not self.creds.access_token:
      self.creds.refresh(httplib2.Http())
    self.creds.apply(req.headers)


class MainHandler(webapp2.RequestHandler):
  @decorator.oauth_required
  def get(self):
    # This object is all we need for google-api-python-client access
    http = decorator.http()

    # Create a gdata client
    gd_client = gdata.contacts.client.ContactsClient(source='<var>YOUR_APPLICATION_NAME</var>')

    # And tell it to use the same credentials
    gd_client.auth_token = TokenFromOAuth2Creds(decorator.get_credentials())

    # Use Contacts API with gdata library
    feed = gd_client.GetContacts()
    for i, entry in enumerate(feed.entry):
      self.response.write('\n%s %s' % (i+1, entry.name.full_name.text if entry.name else ''))

    # Use Calendar API with google-api-python-client
    service = build("calendar", "v3")
    result = service.calendarList().list().execute(http=http)
    self.response.write(repr(result))

app = webapp2.WSGIApplication([
  ("/", MainHandler),
  (decorator.callback_path, decorator.callback_handler()),
], debug=True)

: , http:

http = credentials.authorize(httplib2.Http())

GData http ( decorator.http()) - - API, XML/JSON :

class MainHandler(webapp2.RequestHandler):
  @decorator.oauth_required
  def get(self):
    http = decorator.http()

    self.response.write(http.request('https://www.google.com/m8/feeds/contacts/default/full')[1])    
    self.response.write(http.request('https://www.googleapis.com/calendar/v3/users/me/calendarList')[1])

httplib2: http://httplib2.googlecode.com/hg/doc/html/libhttplib2.html#http-objects

+3

, API GData, Storage.

GData , , , (), API GData API Google . , .

0

All Articles