简体   繁体   English

Google 日历 API 使用入门

[英]Google calender API getting started

I'm trying to get familiar with the google calendar api.我正在尝试熟悉谷歌日历 api。 In the getting started guide they have this code example:在入门指南中,他们有这个代码示例:

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()

In this example we automatically open a window to ask the user to access their calendar, if we don't already have access through the pickle file.在这个例子中,如果我们还没有通过 pickle 文件进行访问,我们会自动打开一个窗口,要求用户访问他们的日历。 The thing is I don't want this window to open automatically, I want to print a link instead that the user can click to authenticate.问题是我不希望这个窗口自动打开,我想打印一个链接,而不是用户可以单击以进行身份​​验证。 I have looked around in the documentation but can't seem to find anything usefull.我在文档中环顾四周,但似乎找不到任何有用的东西。 I would appriciate any help i could get, thanks!我会感谢我能得到的任何帮助,谢谢!

  • For authorizing process, you want to show only the URL.对于授权过程,您只想显示 URL。 You don't want to automatically open the browser.您不想自动打开浏览器。
  • You want to achieve this using googleapis with python.您想使用 googleapis 和 python 来实现这一点。

If my understanding is correct, how about this answer?如果我的理解是正确的,这个答案怎么样? Please think of this as just one of several possible answers.请将此视为几种可能的答案之一。

In this case, please use Flow.from_client_secrets_file instead of InstalledAppFlow.from_client_secrets_file .在这种情况下,请使用Flow.from_client_secrets_file而不是InstalledAppFlow.from_client_secrets_file

Modified script:修改后的脚本:

When your script is modified, please modify as follows.当您的脚本被修改时,请进行如下修改。

From:从:

from google_auth_oauthlib.flow import InstalledAppFlow

To:到:

from google_auth_oauthlib.flow import Flow

and

From:从:

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)

To:到:

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)
  • In this case, when you run the script under token.pickle is not existing, the URL for the authorization is displayed to the console.在这种情况下,当您在token.pickle is not existing 下运行脚本时,授权的 URL 将显示到控制台。 The browser is not opened.浏览器没有打开。 So please access to the URL by opening the browser and authorize the scopes.因此,请通过打开浏览器访问 URL 并授权范围。 Then, please the copied authorization code to the console and input enter key.然后,请将复制的授权码发送到控制台并输入回车键。 By this, the access token is retrieved and the file of token.pickle is created.通过这种方式,检索访问令牌并创建token.pickle文件。

Note:笔记:

  • If an error related to the redirect uri occurs, please modify it to http://localhost and test it again.如果出现重定向uri相关的错误,请将其修改为http://localhost并再次测试。

Reference:参考:

If I misunderstood your question and this was not the direction you want, I apologize.如果我误解了您的问题并且这不是您想要的方向,我深表歉意。

Added:添加:

  • From I want to print a link instead that the user can click to authenticate in your question, I proposed above sample script.I want to print a link instead that the user can click to authenticate在您的问题中I want to print a link instead that the user can click to authenticate ,我提出了上面的示例脚本。
  • From some way not to manually confirm authorization codes in your replying, I think that that above sample script is not suitable.some way not to manually confirm authorization codes在您的回复中some way not to manually confirm authorization codes ,我认为上面的示例脚本不合适。

In this case, how about using the service account?在这种情况下,如何使用服务帐户? When the service account is used, no authorization code is required.使用服务帐号时,不需要授权码。 The script for using the service account is as follows.使用服务帐号的脚本如下。

Sample script:示例脚本:

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)

Note:笔记:

  • In order to access to the Google calendar using the service account, at first, please share the Google calendar with the email of the service account.为了使用服务帐号访问谷歌日历,首先请将谷歌日历与服务帐号的邮箱共享。 Please be careful this.请注意这一点。

Reference:参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM