【问题标题】:Google calender API getting startedGoogle 日历 API 入门
【发布时间】:2020-06-25 06:23:55
【问题描述】:

我正在尝试熟悉谷歌日历 API。在入门指南中,他们有以下代码示例:

from __future__ import print_function
import datetime
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']


def main():
    """Shows basic usage of the Google Calendar API.
    Prints the start and name of the next 10 events on the user's calendar.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    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(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('calendar', 'v3', credentials=creds)

    # Call the Calendar API
    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=10, singleEvents=True,
                                        orderBy='startTime').execute()
    events = events_result.get('items', [])

    if not events:
        print('No upcoming events found.')
    for event in events:
        start = event['start'].get('dateTime', event['start'].get('date'))
        print(start, event['summary'])


if __name__ == '__main__':
    main()

在此示例中,如果我们还没有通过 pickle 文件访问的权限,我们会自动打开一个窗口来要求用户访问他们的日历。问题是我不希望这个窗口自动打开,我想打印一个链接,而不是用户可以单击以进行身份​​验证。我在文档中四处查看,但似乎找不到任何有用的东西。如果我能得到任何帮助,我会很高兴的,谢谢!

【问题讨论】:

    标签: python oauth-2.0 google-calendar-api google-oauth


    【解决方案1】:
    • 对于授权过程,您只想显示 URL。您不想自动打开浏览器。
    • 您希望使用 googleapis 和 python 来实现此目的。

    如果我的理解是正确的,那么这个答案呢?请认为这只是几个可能的答案之一。

    在这种情况下,请使用Flow.from_client_secrets_file 而不是InstalledAppFlow.from_client_secrets_file

    修改后的脚本:

    当你的脚本被修改时,请进行如下修改。

    发件人:

    from google_auth_oauthlib.flow import InstalledAppFlow
    

    收件人:

    from google_auth_oauthlib.flow import Flow
    

    发件人:

    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    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(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    
    service = build('calendar', 'v3', credentials=creds)
    

    收件人:

    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            # Create the flow using the client secrets file from the Google API
            # Console.
            flow = Flow.from_client_secrets_file('client_secret.json', SCOPES, redirect_uri='urn:ietf:wg:oauth:2.0:oob')
    
            # Tell the user to go to the authorization URL.
            auth_url, _ = flow.authorization_url(prompt='consent')
    
            print('Please go to this URL: {}'.format(auth_url))
    
            # The user will get an authorization code. This code is used to get the
            # access token.
            code = input('Enter the authorization code: ')
            flow.fetch_token(code=code)
            creds = flow.credentials
    
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    
    service = build('calendar', 'v3', credentials=creds)
    
    • 在这种情况下,当您在token.pickle 不存在下运行脚本时,授权的URL 将显示到控制台。浏览器未打开。所以请打开浏览器访问URL并授权范围。然后,请将复制的授权码到控制台并输入回车键。这样,访问令牌被检索并创建了token.pickle 的文件。

    注意:

    • 如果出现重定向uri相关的错误,请修改为http://localhost重新测试。

    参考:

    如果我误解了您的问题并且这不是您想要的方向,我深表歉意。

    补充:

    • 从您的问题中的I want to print a link instead that the user can click to authenticate,我提出了上述示例脚本。
    • some way not to manually confirm authorization codes在您的回复中,我认为上面的示例脚本不适合。

    在这种情况下,如何使用服务帐户?使用服务帐号时,无需授权码。使用服务帐号的脚本如下。

    示例脚本:

    from google.oauth2 import service_account
    from googleapiclient.discovery import build
    
    SERVICE_ACCOUNT_FILE = 'service-account-credentials.json'  # Here, please set the creadential file of the service account.
    SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
    creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    
    service = build('calendar', 'v3', credentials=creds)
    

    注意:

    • 为了使用服务帐号访问谷歌日历,首先请与服务帐号的邮箱共享谷歌日历。请注意这一点。

    参考:

    【讨论】:

    • 是的,您正确理解了我的问题,这绝对是我想要的方向。但是我觉得他们会以某种方式不手动确认授权码。你知道有没有办法做到这一点?需要什么?也许somhow'监听'使用我的client_secret的身份验证?再次感谢您!
    • @WilliamG 感谢您的回复。我带来的不便表示歉意。根据您的问题,我提出了上述示例脚本。但是,从您的回复中,我可以知道我的理解是不正确的。这是因为我的英语水平不好。我对此深表歉意。为了您的回复,我又添加了一种方法和示例脚本。你能确认一下吗?如果这不是您想要的方向,我很抱歉。
    • 我也在考虑服务帐户。因为它们可以用来访问其他人的日历,对吧?
    • @WilliamG 感谢您的回复。我认为当 Google 日历与包含服务帐户的脚本一起使用时,您可以让多个用户使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多