humanbeing
humanbeing

Reputation: 1697

Oauth aware flow issue

Problem statement: calling methods on the oauth aware decorator causes a nonetype error.

I look at this page https://developers.google.com/api-client-library/python/guide/google_app_engine

Specifically the code in the guide under: In the following code snippet, the OAuth2DecoratorFromClientSecrets class is used to create an oauth_aware decorator, and the decorator is applied to a function that accesses the Google Tasks API:

and try and create something similar (included below).

My app is giving this error

 Traceback (most recent call last):
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/base/data/home/apps/APPNAME/DIRECTORYNAME/main.py", line 39, in get
    url = decorator.authorize_url()
  File "/base/data/home/apps/APPNAME/DIRECTORYNAME/oauth2client/appengine.py", line 798, in authorize_url
    url = self.flow.step1_get_authorize_url()
AttributeError: 'NoneType' object has no attribute 'step1_get_authorize_url'

When I do logging.info(decorator) it returns

and when I do

>>>logging.info(dir(decorator))
>>> ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_auth_uri', '_callback_path', '_client_id', '_client_secret', '_create_flow', '_credentials_class', '_credentials_property_name', '_display_error_message', '_in_error', '_kwargs', '_message', '_revoke_uri', '_scope', '_storage_class', '_tls', '_token_response_param', '_token_uri', '_user_agent', 'authorize_url', 'callback_application', 'callback_handler', 'callback_path', 'credentials', 'flow', 'get_credentials', 'get_flow', 'has_credentials', 'http', 'oauth_aware', 'oauth_required', 'set_credentials', 'set_flow']

but any of those methods like decorator.http() or decorator.has_credentials() triggers a none type error

My code

import webapp2
import logging
import jinja2
import pprint
import os
import json
import time
import httplib2

from apiclient.discovery import build
from apiclient.errors import HttpError
from google.appengine.ext.webapp.util import run_wsgi_app

from oauth2client.appengine import OAuth2DecoratorFromClientSecrets
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run

from google.appengine.api import urlfetch

decorator = OAuth2DecoratorFromClientSecrets(
    os.path.join(os.path.dirname(__file__), 'client_secrets.json'),
    scope='https://www.googleapis.com/auth/bigquery')

# Google App Engine project ID
PROJECT_NUMBER = 'XXXXXXXXXXXXX'
bigquery_service = build('bigquery', 'v2')

class MainHandler(webapp2.RequestHandler):
    def get(self):
        if decorator.has_credentials():
            logging.info('has credentials')
        else:
            logging.info('bouncing credentials')
            logging.info(decorator)
            url = decorator.authorize_url()
            return self.redirect(url)

        jinja_environment = self.jinja_environment
        template = jinja_environment.get_template("/index.html")
        self.response.out.write(template.render())

    @property
    def jinja_environment(self):
        jinja_environment = jinja2.Environment(
            loader=jinja2.FileSystemLoader('views')

        )
        return jinja_environment

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

Upvotes: 0

Views: 646

Answers (1)

mgilson
mgilson

Reputation: 309949

From perusing the source, I think the "decorator" should be used to decorate something before you use it to do other things. In this case, you probably want to decorate get with oauth_aware:

class MainHandler(webapp2.RequestHandler):
    @decorator.oauth_aware
    def get(self):
        if decorator.has_credentials():
            ...
        else:
            ...
            url = decorator.authorize_url()

Upvotes: 2

Related Questions