概要
Heroku で google-api-python-client
ライブラリを Python で使用した際につまづいたことをまとめました。
注意点
ここで使用している oauth2client
ライブラリは廃止予定です。
Note: oauth2client is now deprecated. As such, it is unlikely that we will address or respond to your issue. We recommend you use google-auth and oauthlib.
oauth2client/.github/ISSUE_TEMPLATE.md
気が向いたら修正します。
実行環境
- Python 3.6.5
- google-api-python-client==1.7.7
- httplib2==0.12.0
- oauth2client==4.1.3
- Heroku CLI
課題1:token.json
をそのまま上げるわけにはいかない
解決策①:Heroku CLI で環境変数を設定
以下コマンドで、JSON ファイルを環境変数として設定できます。
$ heroku config:set GOOGLE_APPLICATION_CREDENTIALS="$(< token.json)"
解決策②:ブラウザ上から環境変数を設定
どちらでも OK です。
課題2:環境変数をどう使うか
以下 Google Calendar API のサンプルプログラムの抜粋。
store = file.Storage('token.json')
creds = store.get()
# 省略
service = build('calendar', 'v3', http=creds.authorize(Http()))
ここではローカルにある token.json
を読み込んで、「なにか」してからgoogleapiclient.discovery.build
に渡しています。
つまり、環境変数をそのまま渡してもうまくいきません。
環境変数に対して同じ「なにか」をしてあげる必要があります。
解決策: ソース を見る
以下 oauth2client のソースコード抜粋。
try:
f = open(self._filename, 'rb')
content = f.read()
f.close()
except IOError:
return credentials
try:
credentials = client.Credentials.new_from_json(content)
credentials.set_store(self)
except ValueError:
pass
JSON ファイルを開いた後に、client.Credentials.new_from_json
で処理しています。
そこで、環境変数 GOOGLE_APPLICATION_CREDENTIALS
に対しても同じことをしてあげれば OK です。
from httplib2 import Http
from oauth2client import client
from googleapiclient.discovery import build
CONTENTS = os.environ.get('GOOGLE_APPLICATION_CREDENTIALS')
CREDS = client.Credentials.new_from_json(CONTENTS)
SERVICE = build('calendar', 'v3', http=CREDS.authorize(Http()))
oauth2client/oauth2client/file.py
で with
ブロックが使われていないことに違和感を感じ、いろいろ見ていたら oauth2client
が廃止予定であることがわかりました。
おわりに
Google API のサンプルプログラムが廃止予定の oauth2client
で書かれていますが、現在こちらで issue が立っているので、そのうち修正されると思います。