且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

应用引擎调用Google API python客户端返回403与@oauth_required

更新时间:2022-10-15 14:18:35

显然,问题是尝试插入全天事件 endTimeUnspecified:True ...



我在google-api- python-client GitHub跟踪器: https://github.com/google/ google-api-python-client / issues / 334



也许有人会研究它或发布更准确的答案。
$ b

Tha大家都来。


It should be a trivial job but i cannot get it out.

I need to call the Google Calendar API from Gae; thus I set all up as per Google docs and examples:

I've an /auth.py:

CLIENT_SECRETS = os.path.join(os.path.dirname(__file__), 'client_secrets.json')
SCOPES = [
    'https://www.googleapis.com/auth/calendar',
]
decorator = appengine.OAuth2DecoratorFromClientSecrets(
    filename=CLIENT_SECRETS,
    scope=SCOPES,
    cache=memcache,
    prompt='consent',
)

called by main.py functions:

class Landing(webapp2.RequestHandler):
    @auth.decorator.oauth_aware
    def get(self):
        if auth.decorator.has_credentials():
            self.redirect('/in')
        else:
            self.response.out.write('''
            etc. {}'''.format(auth.decorator.authorize_url()))

class Main(webapp2.RequestHandler):
    @auth.decorator.oauth_required
    def get(self):
        links = { ... }
        render(self, 'base.html', template_values=links)

class Calendar(webapp2.RequestHandler):
    @auth.decorator.oauth_required
    def get(self):
        service = build('calendar', 'v3', http=auth.decorator.http())
        api_request = service.events().list(calendarId='primary')
        api_response = api_request.execute()
        self.response.headers['Content-Type'] = 'application/json; charset=utf-8'
        self.response.out.write(json.dumps(api_response, indent=4))

class PutEvent(webapp2.RequestHandler):
    @auth.decorator.oauth_required
    def post(self):
        # ...
        # http = httplib2.Http(memcache)
        service = build('calendar', 'v3') #, http=http)

        api_response = []
        for i in json.loads(self.request.get('events')):
            # ...
            event = { ... } # Google Calendar event
            api_request = service.events().insert(calendarId='primary', body=scadenza)
            api_response.append(api_request.execute(http=auth.decorator.http()))

        self.response.headers['Content-Type'] = 'application/json; charset=utf-8'
        self.response.out.write(json.dumps(api_response, indent=4))

As you can see this is a fairly simple post requested by an Ajax jQuery call ($.post('{{ putEvent_url }}', jsonData, function( data ){ console.log(data); })...

I'm in the development server, using test@example user, and the app is authorized to access my personal account's Google Calendar.

Strange thing to me is that any call to Calendar() works as expected, but call to PutEvent() end in ERROR 500.

Looking to the end of the traceback in console:

  File "/home/pierpaolo/Devnos/whiterabbit/include/oauth2client/contrib/appengine.py", line 644, in check_oauth
    resp = method(request_handler, *args, **kwargs)
  File "/home/pierpaolo/Devnos/whiterabbit/main.py", line 211, in post
    api_response.append(api_request.execute(http=auth.decorator.http()))
  File "/home/pierpaolo/Devnos/whiterabbit/include/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/home/pierpaolo/Devnos/whiterabbit/include/googleapiclient/http.py", line 838, in execute
    raise HttpError(resp, content, uri=self.uri)
HttpError: <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/primary/events?alt=json returned "Forbidden">
INFO     2017-01-04 15:13:32,385 module.py:788] default: "POST /api/put/scadenze HTTP/1.1" 500 -

I cannot understand the

HttpError: https://www.googleapis.com/calendar/v3/calendars/primary/events?alt=json returned "Forbidden">

it looks to me I already granted the app access to my account and that Google App Engine decorators have been correctly put in place to make the OAuth2.0 thing as per https://developers.google.com/api-client-library/python/guide/google_app_engine...

EDIT: I was wondering if my trouble can be related to the way i call Google Calendar API:

     HTML/JS            GAE/Py
+------------------+
|                  |
| <form>           |
|   ...data        |
| <\JS/Ajax        |
|   $.post(...data |  -->  GAE/main.py
|                  |         @auth.decorator.oauth_required
|                  |         def post(self, data):
+------------------+           event = elaborate(data)
                               service = build('calendar', 'v3')
                               api_request = service.events()
                                             .insert(calendarId='primary',
                                                     body=event)
                               api_response = api_request
                                              .execute(auth.decorator
                                                           .http())
                               self.response(api_response)

EDIT 3: I looked a bit into oauth2client.contrib.appengine and I added some logger.debug here and there: I think the problem could be in execute(http=decorator.http()) call, but it is the same in my other handlers! Neither positional nor keyword nor put authrized Http in service build changes the misbehaviour...

Nor can I see what problem may pose _helpers.py", line 133, in positional_wrapper...

Dear all, some hint on how to research further?

Actually, I can insert Acl and/or insert a secondary calendar in the same RequestHandler that throws Forbidden exception with events().insert()...!

Apparently, the problem is to try to insert an all-day event with endTimeUnspecified: True...

I opened an issue on google-api-python-client GitHub tracker: https://github.com/google/google-api-python-client/issues/334.

Maybe someone will look into it or post a more precise answer.

Thank you all.