I've run:
gcloud auth application-default login --client-id-file google_oauth_client_id.json --scopes="https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/calendar.calendars.readonly"
successfully. My browser opened, I granted the calendar and cloud-platform permissions to my test app, and the results were saved to disk:
Credentials saved to file:[/home/*****/.config/gcloud/application_default_credentials.json]
However, running the following snippet leads to a 403 error:
from google.auth import default
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
SCOPES = ["https://www.googleapis.com/auth/calendar.calendars.readonly"]
credentials, project_id = default(scopes=SCOPES, quota_project_id='my-project-id')
credentials.refresh(Request())
access_token = credentials.token
service = build("calendar", "v3", credentials=credentials)
events = service.events().list(calendarId="My Calendar Id", maxResults=10, singleEvents=True, orderBy="startTime").execute()
At first I thought maybe I wasn't using the correct calendarId
, but when I was in the debugger, I noticed that the credentials
object has no scopes defined:
>>> (credentials.scopes, credentials.default_scopes, credentials.granted_scopes)
(None, None, None)
However, if I delete the application_default_credentials.json
file the default
method throws an appropriate error, so it does seem like it's reading from the file properly-- it's just not realizing that the permissions have been granted...
Looking at the application_default_credentials.json
, I'm not seeing any mention of scopes: dict_keys(['account', 'client_id', 'client_secret', 'refresh_token', 'type', 'universe_domain'])
This leads me to believe that either:
- The scopes are saved server-side, and I need to properly request them when refreshing the token
- The
gcode
client isn't saving this information properly.
Option 1 seems more likely, since the CLI is properly displaying the scopes and passing them to the OAuth session....
1 Answer 1
You should use calendar.events.readonly
for service.events().list
.
This is documented by APIs Explorer for Calendar API for events.list
under Authorization
Your issue is that the scopes granted by gcloud auth application-default login
to your user credentials do not include this scope. You may verify using e.g. this link:
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={ACCESS_TOKEN}
When you login, you can request the additional scopes:
gcloud auth application-default login \
--scopes=\
https://www.googleapis.com/auth/cloud-platform,\
https://www.googleapis.com/auth/calendar.events.readonly
Comments
Explore related questions
See similar questions with these tags.
https://www.googleapis.com/auth/cloud-platform
into the SCOPES? try changing your scope intoSCOPES = ["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/calendar.calendars.readonly"]
None
calendar.events.readonly
notcalendar.calendars.readonly
forservice.events().list
. Your issue is that the scopes granted bygcloud auth application-defaullt login
to your user credentials do not include this scope. You may verify e.g.https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={ACCESS_TOKEN}
and can fix by adding the scope when you login e.g.gcloud auth application-default login --scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/calendar.events.readonly