質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Google Cloud Platform

Google Cloud Platformは、Google社がクラウド上で提供しているサービス郡の総称です。エンドユーザー向けサービスと同様のインフラストラクチャーで運営されており、Webサイト開発から複雑なアプリ開発まで対応可能です。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

2138閲覧

Python の Google Calendar API の認証の有効期間の設定について

nori_nori

総合スコア0

Google Cloud Platform

Google Cloud Platformは、Google社がクラウド上で提供しているサービス郡の総称です。エンドユーザー向けサービスと同様のインフラストラクチャーで運営されており、Webサイト開発から複雑なアプリ開発まで対応可能です。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/02/14 03:08

編集2022/01/12 10:55

Python の Google Calendar API の認証の有効期間について質問させてください。

expiredが設定される条件の有無、および、expiredの設定方法について教えて頂けないでしょうか?

私の環境で公式サイトのプログラムを実行したところcreds.refresh(Request())のロジックを通っていません。

printで値をを出力したところcreds.validがTrueでした。
credsの内容をそのまま出力したところexpiredの日付の記述もありませんでした。
以下はgoogle.auth.credentials moduleのURLです。
https://google-auth.readthedocs.io/en/latest/reference/google.auth.credentials.html

以下Python の Google Calender APIの公式のURLです。
https://developers.google.com/calendar/quickstart/python

公式のサンプルを一部抜粋

python

1if os.path.exists('token.pickle'): 2 with open('token.pickle', 'rb') as token: 3 creds = pickle.load(token) 4# If there are no (valid) credentials available, let the user log in. 5if not creds or not creds.valid: 6 if creds and creds.expired and creds.refresh_token: 7 creds.refresh(Request()) 8 else: 9 flow = InstalledAppFlow.from_client_secrets_file( 10 'credentials.json', SCOPES) 11 creds = flow.run_local_server(port=0) 12 # Save the credentials for the next run 13 with open('token.pickle', 'wb') as token: 14 pickle.dump(creds, token) 15 16print(creds.to_json()) 17service = build('calendar', 'v3', credentials=creds)

実行結果

{"token": "ya29.a0AfHxxxxxxx", "refresh_token": "1//0euR5aD1RP7Qxxxxx", "token_uri": "https://oauth2.googleapis.com/token", "client_id": "3783162xxxxxxx9m.apps.googleusercontent.com", "client_secret": "HE8IkGcZxxxxxxx", "scopes": ["https://www.googleapis.com/auth/calendar.readonly"]}

補足情報(FW/ツールのバージョンなど)

bash

1raspberry pi 3 2No LSB modules are available. 3Distributor ID: Raspbian 4Description: Raspbian GNU/Linux 10 (buster) 5Release: 10 6Codename: buster

bash

1macOS big sur version 11.2.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

credsの内容をそのまま出力したところexpiredの日付の記述もありませんでした。

credsの内容を、どの段階で、どのように出力されたのかこちらでは分かりかねますが、
reflesh()関数もしくは、InstalledAppFlow.from_client_secrets_file()関数を実行した後
Credentialsオブジェクトの中にある、expiryが有効期限を表すdatetimeオブジェクトです。
(こちらの環境はwindows10です)

https://google-auth.readthedocs.io/en/latest/reference/google.auth.credentials.html#google.auth.credentials.Credentials.expiry

(なお、このオブジェクトはnaiveであり、暗黙的にUTCであるように思われますので注意が必要です)

expiryは、おおむね作成時刻(更新時刻)の1時間後で設定されます。

※少なくともGoogle Calendar APIの場合、ユーザー側で任意の有効期限は設定できないと思います。
私は試しませんが、こちらでtoken.pickle内のexpiryを故意に延長したcredsをbuild関数に渡しても、おそらく無視されるでしょう(非推奨)。
したがって、質問文で引用されている公式サンプルコードのように、有効期限を過ぎているかどうかを調べ、過ぎているならば、reflesh()を実行して有効期限を延長する(正確には、有効期限が延長された新しいトークンを取得する)というのが通常の使い方になります。

下記は、公式サンプルコードに、トークンの有効期限を日本時間で表示する部分を追加したものになります。

diff

1from __future__ import print_function 2import datetime 3import pickle 4import os.path 5from googleapiclient.discovery import build 6from google_auth_oauthlib.flow import InstalledAppFlow 7from google.auth.transport.requests import Request 8from datetime import datetime, timedelta, timezone 9# If modifying these scopes, delete the file token.pickle. 10SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'] 11 12+JST = timezone(timedelta(hours=+9), 'JST') 13 14+def conv_jst(d:datetime): 15+ if d.tzinfo is None or d.tzinfo.utcoffset is None: 16+ return (d.replace(tzinfo=timezone.utc)).astimezone(JST) 17 18def main(): 19 """Shows basic usage of the Google Calendar API. 20 Prints the start and name of the next 10 events on the user's calendar. 21 """ 22+ print("現在時刻: ",datetime.now(JST)) 23 creds = None 24 # The file token.pickle stores the user's access and refresh tokens, and is 25 # created automatically when the authorization flow completes for the first 26 # time. 27 if os.path.exists('token.pickle'): 28 with open('token.pickle', 'rb') as token: 29 creds = pickle.load(token) 30 # If there are no (valid) credentials available, let the user log in. 31 32 if not creds or not creds.valid: 33 if creds and creds.expired and creds.refresh_token: 34+ old_expiry_time = creds.expiry 35+ print("credentialの有効期限が古いです。:",conv_jst(old_expiry_time)) 36 creds.refresh(Request()) 37+ print("有効期限を更新しました。") 38+ print("更新前",conv_jst(old_expiry_time)," -> 更新後:", conv_jst(creds.expiry)) 39 else: 40 flow = InstalledAppFlow.from_client_secrets_file( 41 'credentials.json', SCOPES) 42 creds = flow.run_local_server(port=0) 43 44 # Save the credentials for the next run 45 with open('token.pickle', 'wb') as token: 46 pickle.dump(creds, token) 47+ print("更新チェックが完了しました。:") 48+ print("有効:", creds.valid) 49+ print("有効期限:", conv_jst(creds.expiry)) 50 service = build('calendar', 'v3', credentials=creds) 51 52 # Call the Calendar API 53 now = datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time 54 print('Getting the upcoming 10 events') 55 events_result = service.events().list(calendarId='primary', timeMin=now, 56 maxResults=10, singleEvents=True, 57 orderBy='startTime').execute() 58 events = events_result.get('items', []) 59 60 if not events: 61 print('No upcoming events found.') 62 for event in events: 63 start = event['start'].get('dateTime', event['start'].get('date')) 64 print(start, event['summary']) 65 66 67if __name__ == '__main__': 68 main()

投稿2021/02/14 07:03

編集2021/02/14 07:09
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nori_nori

2021/02/14 20:58 編集

qnoir様 ご回答ありがとうございます。 お世話になっております。 私の環境では print(creds.to_json()) にしても質問文の実行結果のようになってしまいます。 できればexpiredの情報が含まれてほしいのですが、どうやっても含まれてない状態です。 ログイン認証要求を初回だけ出るだけでその後、 最低一ヶ月ほどはログイン画面が出ないでアクセスしたいのです。 最低一日一回はアクセスします。 そのため有効期限が必要なのかなと思ってますが、expiredがなくても済みそうならそれでも大丈夫です。 公式のコードとは違いますが以下はそれ用に作ったコードです。 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(): creds = None if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) creds.refresh(Request()) # 外部APIに接続 else: # from_client_secrets_file returns google_auth_oauthlib.flow.Flow object flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) # 外部APIに接続 creds = flow.run_console() # 外部APIに接続 # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) print(creds.to_json()) 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() 流れとしては token.pickleの有無 ↓ (有)credsのrefresh (無)初回ログインでcreds生成 ↓ credsを元にtoken.pickleを書き込み ↓ 一日最低一回以上繰り返し このやり方でも問題なければいいのですが、 検証中でしてご存知であればご教授ください。 よろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問