Ronan Jouchet
Ronan Jouchet

Reputation: 1333

GAE-1.7.7's oauth2client/appengine.py:_create_flow(self, request_handler) returns AttributeError: 'Resource' object has no attribute 'request'

I have an OAuth2 decorator:

decorator = OAuth2DecoratorFromClientSecrets(CLIENT_SECRETS, YOUTUBE_READ_WRITE_SCOPE)

... and I sometimes call a function that requires authentication:

  playlist_id = youtube_create_playlist(youtube)

... so I prepend it with decorator:

@decorator.oauth_required
def youtube_create_playlist(youtube):
  playlists_insert_response = youtube.playlists().insert(
  ...

→ As expected, when stepping into youtube_create_playlist(), I go through oauth2client/appengine.py:oauth_required(), then check_oauth(), then _create_flow(), where at line 674 of appengine.py 1.7.7 we have:

redirect_uri = request_handler.request.relative_url(
          self._callback_path) # Usually /oauth2callback

→ But at this step, GAE trips up and throws exception AttributeError: 'Resource' object has no attribute 'request'. And indeed I can see in my Variables debugging pane that the request_handler object has no attribute 'request'. Am I doing something wrong? Is it a bug? I also created google-api-python-client issue264.

Upvotes: 0

Views: 2475

Answers (1)

Tim Hoffman
Tim Hoffman

Reputation: 12986

Ok I think you are missing some understanding on how this decorator will work,

It is intended to be used as a decorator for a web handler (GET/POST handler) in the docs the example using the Calendar api https://developers.google.com/api-client-library/python/platforms/google_app_engine#Decorators

Shows

@decorator.oauth_required
  def get(self):
    # Get the authorized Http object created by the decorator.
    http = decorator.http()
    # Call the service using the authorized Http object.
    request = service.events().list(calendarId='primary')
    response = request.execute(http=http)
    ...

You haven't shared all your code, but your youtube_create_playlist doesn't look like a standard web handler (ok, maybe your not using webapp(2)) and not using class based handlers

The request object needs to be passed in somehow. In webapp handlers the request is passed in to an instance of the handler when it is requested, and if you set it up this way your method would have access to self.request (and the decorator would too).

If above doesn't make sense I suggest you include more code.

Upvotes: 2

Related Questions