I am using python and appengine to create an application that uses Google Calendar API (V3).
I am able to list events, from multiple calendars etc. However, I am running into problems when trying to insert an event into a calendar.
If I use get() in my handler, everything works fine (ie. event is inserted properly. However, if I use a form and post() to insert the event (in the same calendar) it fails with the following message
<HttpError 401 when requesting https://www.googleapis.com/calendar/v3/calendars/.../events?alt=json returned "Login Required">
Traceback (most recent call last):
File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1511, in __call__
rv = self.handle_exception(request, response, e)
File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1505, in __call__
rv = self.router.dispatch(request, response)
File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
return route.handler_adapter(request, response)
File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 547, in dispatch
return self.handle_exception(e, self.app.debug)
File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 545, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/.../oauth2client/appengine.py", line 469, in check_oauth
return method(request_handler, *args, **kwargs)
File "/base/data/home/apps/...", line 99, in post
request = service.events().insert(calendarId='MyCalendarId', body=event).execute()
File "/base/data/home/apps/.../apiclient/http.py", line 678, in execute
raise HttpError(resp, content, uri=self.uri)
HttpError: <HttpError 401 when requesting https://www.googleapis.com/calendar/v3/calendars/.../events?alt=json returned "Login Required">
Simplified versions of functions get() and post() are below:
class AddEvent(webapp2.RequestHandler):
@decorator.oauth_required
def post(self):
if decorator.has_credentials():
#event_name = self.request.get('event-name')
event = {
'summary': self.request.get('summary'),
'location': self.request.get('place'),
'status' : self.request.get('status'),
'start': {
'dateTime': '2013-05-11T10:00:00.000-07:00' ,
'timeZone': 'America/New_York'
},
'end': {
'dateTime': '2013-05-11T10:25:00.000-07:00',
'timeZone': 'America/New_York'
},
}
request = service.events().insert(calendarId='MyCalendarId', body=event).execute()
else:
self.response.out.write(json.dumps({'error': 'No credentials'}))
page = 'main'
template_values = {
'url': url,
'url_linktext': url_linktext,
'menu' : page
}
template = jinja_environment.get_template('templates/index.html')
self.response.out.write(template.render(template_values))
@decorator.oauth_required
def get(self):
if decorator.has_credentials():
event_name = self.request.get('event-name')
event = {
'summary': 'Appointment from get',
'location': 'Somewhere close to it',
'start': {
'dateTime': '2013-04-15T10:00:00.000-07:00' ,
'timeZone': 'America/New_York'
},
'end': {
'dateTime': '2013-04-15T10:25:00.000-07:00',
'timeZone': 'America/New_York'
},
}
http = decorator.http()
request = service.events().insert(calendarId='MyCalendarId', body=event)
inserted = request.execute(http)
else:
self.response.out.write(json.dumps({'error': 'No credentials'}))
page = 'main'
template_values = {
'url': url,
'url_linktext': url_linktext,
'menu' : page
}
template = jinja_environment.get_template('templates/index.html')
self.response.out.write(template.render(template_values))
The OAuth2 is used as follow:
decorator = OAuth2Decorator(
client_id='client ID',
client_secret='client secret',
scope='https://www.googleapis.com/auth/calendar')
I cannot figure out what is wrong here and why I am getting "Login Required" exception in one case and not in the other when both methods do pretty much the same thing.
Any help is appreciated.
Found out how to resolve the problem.
I needed to change post() method to look something like this:
The solution is actually based on this answer.