I was able to get the following working. It uses the oauth2decorator
to do the heavy lifting, then it uses a small helper class TokenFromOAuth2Creds
to apply those same credentials to the gdata client.
I should preface that I'm no gdata expert - and there may be better ways of doing this - and I haven't thoroughly tested.
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)
Note, if you're not using the decorator, and have gotten your credentials object by other means, you can create the same pre-authorized http object by:
http = credentials.authorize(httplib2.Http())
An alternative to using gdata is to use the http
object (returned by decorator.http()
) directly - this object will automatically add the right authorization headers for you - this can be used to make requests to either API, but you'll need to handle crafting the request and parsing the XML/JSON yourself:
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])
Docs for httplib2:
http://httplib2.googlecode.com/hg/doc/html/libhttplib2.html#http-objects
http
object directly as you suggest. The code that I see in the library docs just passes the object into the library methods; it isn't called directly. – Triny