0

I'm trying to use the Google Slides API on Google App Engine, and despite using the Google code samples (specifically for OAuth2 & the Slides API on App Engine), I'm running into problems.

Here is my App Engine code, with unnecessary cruft removed (everything's in main.app). What I'm doing is trying to posting a string from an HTML form and then build a blank presentation. I've already used the Slides API with a simple script that I prototyped; I'm now trying to make this self-serve via an App Engine app, but it's the change in authentication that's tripping me up.

from googleapiclient import discovery
from oauth2client import client
from oauth2client.contrib import appengine
from google.appengine.api import memcache

CLIENT_SECRETS = os.path.join(os.path.dirname(__file__), 'client_secrets.json')
MISSING_CLIENT_SECRETS_MESSAGE = """[omitted]""" % CLIENT_SECRETS    

http = httplib2.Http()
service = discovery.build('slides', 'v1', http=http)
decorator = appengine.OAuth2DecoratorFromClientSecrets(
    CLIENT_SECRETS,
    scope='https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/drive',
    message=MISSING_CLIENT_SECRETS_MESSAGE)

class SlideBuilder(webapp2.RequestHandler):

  @decorator.oauth_required
  def post(self):
    programslug = self.request.get('programid')
    presoname = str(programslug) + ' Mentors'

    presentationbody = {
        'title': presoname
    }
    presentation = service.presentations().create(body=presentationbody).execute()

I want to point out that I downloaded the most recent client_secrets.json directly from the API console, so that should match up correctly for CLIENT_SECRETS.

The error I'm getting (on dev server; but it's also on the live app) is this:

Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/Users/jedc/pm-tools/oauth2client/contrib/appengine.py", line 644, in check_oauth
    resp = method(request_handler, *args, **kwargs)
  File "/Users/jedc/pm-tools/main.py", line 113, in post
    presentation = service.presentations().create(body=presentationbody).execute()
  File "/Users/jedc/pm-tools/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/Users/jedc/pm-tools/googleapiclient/http.py", line 840, in execute
    raise HttpError(resp, content, uri=self.uri)
HttpError: <HttpError 401 when requesting https://slides.googleapis.com/v1/presentations?alt=json returned "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.">

It feels like there's something subtle but dumb that I'm doing here. I'd appreciate any help or pointers to figure out what that is!

Jed Christiansen
  • 659
  • 10
  • 21

1 Answers1

0

This error happening because your http is not authorized with the credentials. To authorize the http with the credentials you should use the decorator.

decorator = appengine.OAuth2DecoratorFromClientSecrets(
    CLIENT_SECRETS,
    scope='https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/drive',
    message=MISSING_CLIENT_SECRETS_MESSAGE)
http = decorator.http()
service = discovery.build('slides', 'v1', http=http)

This will fix your problem. For further reference read this app engine decorators documentation from Google