I'm following these guides: https://developers.google.com/google-apps/calendar/quickstart/python, https://developers.google.com/gmail/api/quickstart/python.
I've completed all the setup steps for both, and the calendar API code works fine, while the Gmail API code fails with a 403 error. What's causing this? What's different between these two APIs?
I've combined the code from these two different examples, so they are sharing as much of the API setup code as possible, to rule out a mistake there.
I've disabled and re-enabled Gmail API in Google Dev Console.
As mentioned here, I've enabled the Contacts and Google+ APIs.
As mentioned here, I've tried all three combinations for Gmail scopes - just the scope from the example, just 'https://mail.google.com/', or both.
This answer, as well as several other sources, suggest 'setting the "Referers" to "Any referer allowed"', but there is no page in Dev Console I can find that contains this option. I can add a domain through the "domain verification" tab, but this does not seem to affect anything.
Code:
import httplib2
import os
from pprint import pprint
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
import datetime
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
class GoogleApi(object):
client_secret_file = 'client_secret.json'
application_name = 'test_app'
def __init__(self):
self.credentials = self.get_credentials()
self.http = self.credentials.authorize(httplib2.Http())
self.service = discovery.build(self.api_name, self.api_version, http=self.http)
def get_credentials(self):
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'test-app.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(self.client_secret_file, self.scopes)
flow.user_agent = self.application_name
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatability with Python 2.6
credentials = tools.run(flow, store)
print 'Storing credentials to ' + credential_path
return credentials
class CalendarApi(GoogleApi):
scopes = 'https://www.googleapis.com/auth/calendar.readonly'
api_name = 'calendar'
api_version = 'v3'
def get_calendar_ids(self):
cl = self.service.calendarList().list().execute()
ids = [x['id'] for x in cl['items']]
return ids
class GmailApi(GoogleApi):
scopes = 'https://mail.google.com/'
#scopes = 'https://www.googleapis.com/auth/gmail.readonly'
api_name = 'gmail'
api_version = 'v1'
def get_labels(self):
ml = self.service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
return labels
def main():
cc = CalendarApi()
ids = cc.get_calendar_ids()
print(ids)
m = GmailApi()
labels = m.get_labels()
print(labels)
if __name__ == '__main__':
main()
Current error ("Insufficient Permission"):
Traceback (most recent call last):
File "gmail_api_test.py", line 92, in <module>
main()
File "gmail_api_test.py", line 87, in main
labels = m.get_labels()
File "gmail_api_test.py", line 76, in get_labels
ml = self.service.users().labels().list(userId='me').execute()
File "/usr/local/lib/python2.7/site-packages/oauth2client/util.py", line 140, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/googleapiclient/http.py", line 729, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/me/labels?alt=json returned "Insufficient Permission">
Error from a previous version of the code ("Access Not Configured. The API (Gmail API) is not enabled for your project. Please use the Google Developers Console to update your configuration."):
Traceback (most recent call last):
File "gmail_demo.py", line 71, in <module>
main()
File "gmail_demo.py", line 59, in main
results = service.users().labels().list(userId='me').execute()
File "/usr/local/lib/python2.7/site-packages/oauth2client/util.py", line 142, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/googleapiclient/http.py", line 729, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/me/labels?alt=json returned "Access Not Configured. The API (Gmail API) is not enabled for your project. Please use the Google Developers Console to update your configuration.">