问题
Several years ago I created a small Python program which were able to maintain my calendar using oauth2client which is now deprecated and replaced with google.auth - but I cannot find any useful documentation and my program stopped working complaining about a _module KeyError which nobody appear to have solved except by upgrading.
I cannot figure out how to replace the oauth2client with google.auth:
import datetime
import httplib2
import os
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
...
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('calendar', 'v3', http=http)
回答1:
According to the oauth2client deprecation notes, the replacement to be used to manage Google user credentials is google-auth-oauthlib. Below a snippet working on my PC (python 3.6).
As the documentation highlights the new library does not save the credentials, that's why I am using pickle to save them. Maybe, depending on your application requirements, you want to have a more robust solution (like a database).
import os
import pickle
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly', ]
# we check if the file to store the credentials exists
if not os.path.exists('credentials.dat'):
flow = InstalledAppFlow.from_client_secrets_file('client_id.json', SCOPES)
credentials = flow.run_local_server()
with open('credentials.dat', 'wb') as credentials_dat:
pickle.dump(credentials, credentials_dat)
else:
with open('credentials.dat', 'rb') as credentials_dat:
credentials = pickle.load(credentials_dat)
if credentials.expired:
credentials.refresh(Request())
calendar_sdk = build('calendar', 'v3', credentials=credentials)
calendars_get_params = {
'calendarId': 'primary',
}
test = calendar_sdk.calendars().get(**calendars_get_params).execute()
print(test)
回答2:
I haven't robustly tested this, but it works for testing snippets with my personal account. I'm sure there are changes that could and/or should be made to it for enterprise applications, such as passing auth'd Http()
instances, detecting scope changes, and so on.
You can review the full code on my GitHub repo:
requirements:
- google-api-python-client
- google-auth
- google-auth-oauthlib
- whatever deps the above pull in
I use the InstalledAppFlow class, and generally followed the instructions on Google's Python auth guide.
Code (Python 3.6)
# Google API imports
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
SCOPES = ['your scopes', 'here']
def get_saved_credentials(filename='creds.json'):
'''Read in any saved OAuth data/tokens
'''
fileData = {}
try:
with open(filename, 'r') as file:
fileData: dict = json.load(file)
except FileNotFoundError:
return None
if fileData and 'refresh_token' in fileData and 'client_id' in fileData and 'client_secret' in fileData:
return Credentials(**fileData)
return None
def store_creds(credentials, filename='creds.json'):
if not isinstance(credentials, Credentials):
return
fileData = {'refresh_token': credentials.refresh_token,
'token': credentials.token,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'token_uri': credentials.token_uri}
with open(filename, 'w') as file:
json.dump(fileData, file)
print(f'Credentials serialized to {filename}.')
def get_credentials_via_oauth(filename='client_secret.json', scopes=SCOPES, saveData=True) -> Credentials:
'''Use data in the given filename to get oauth data
'''
iaflow: InstalledAppFlow = InstalledAppFlow.from_client_secrets_file(filename, scopes)
iaflow.run_local_server()
if saveData:
store_creds(iaflow.credentials)
return iaflow.credentials
def get_service(credentials, service='sheets', version='v4'):
return build(service, version, credentials=credentials)
Usage is then:
creds = get_saved_credentials()
if not creds:
creds = get_credentials_via_oauth()
sheets = get_service(creds)
来源:https://stackoverflow.com/questions/52085054/how-do-i-use-google-auth-instead-of-oauth2client-in-python-to-get-access-to-my-g