I have built this e-ink google calendar project which adapts the Google python quickstart code. I have OAuth working with a private account, but have found that the token expires every 7 days. I wanted to pursue a service account over making the app public because of the annoying steps with verifying this app that only I will use. I successfully created a google workspace service account, and created the private key but Im not sure if the key is the same as client_secrets.json which i cant seem to find.
My code comes from the suggestions from a similar question on stack overflow but I'm getting the error: Client secrets must be for a web or installed app. (traceback below)
The private key generated from the service account "ecalendar-#####.json" (replaced the real values with ###s) is in the working directory.
Here is the Calendar API part of my code:
#Calendar API part
import datetime
from datetime import date, timedelta
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google.oauth2 import service_account
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
#SERVICE_ACCOUNT_FILE = '/path/to/service.json'
SERVICE_ACCOUNT_FILE = 'ecalendar-#####.json'
try:
#Calendar API part
creds = None
if os.path.exists('token.json'):
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
# creds = Credentials.from_authorized_user_file('token.json', SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
SERVICE_ACCOUNT_FILE, SCOPES)
creds = flow.run_local_server(port=0)
with open('token.json', 'w') as token:
token.write(creds.to_json())
service = build('calendar', 'v3', credentials=creds)
now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
print('Getting the upcoming 10 events')
events_result = service.events().list(calendarId='primary', timeMin=now,
maxResults=30, singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])
if not events:
print('No upcoming events found.')
When I run this I get the following Traceback:
pi@raspberrypi:~/calendar/prog $ python3 ecalendar4.py
Traceback (most recent call last):
File "/home/pi/calendar/prog/ecalendar4.py", line 52, in <module>
flow = InstalledAppFlow.from_client_secrets_file(
File "/home/pi/.local/lib/python3.9/site-packages/google_auth_oauthlib/flow.py", line 207, in from_client_secrets_file
return cls.from_client_config(client_config, scopes=scopes, **kwargs)
File "/home/pi/.local/lib/python3.9/site-packages/google_auth_oauthlib/flow.py", line 165, in from_client_config
raise ValueError("Client secrets must be for a web or installed app.")
ValueError: Client secrets must be for a web or installed app.
Am I missing the correct client secrets file? Isnt that my private key json file? If not, where do I find them and where do they need to be?