やること
PythonプログラムからGoogle Spreadsheetにアクセスするまでに発生した問題と、その対策の覚書。
方法
Google Spreadsheetを読み書きするためのPythonライブラリであるgspread
を使う。
https://github.com/burnash/gspread
gspreadの使い方
あらかじめ、testbook
という名前のスプレッドシートをGoogle Spreadsheet上に作成した。
アクセスは
http://gspread.readthedocs.org/en/latest/oauth2.html
の通りに。
ほぼサンプルそのままの以下を実行する。
import gspread
from oauth2client.service_account import ServiceAccountCredentials
scope = ['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'sample-xxxxxx.json', scope)
gc = gspread.authorize(credentials)
wks = gc.open("testbook")
読み書きの準備としてGoogle spreadsheet上にあるスプレッドシートを開くだけ。
が、失敗した。
以下、上記を動かすまでに発生した複数の問題それぞれについて、内容とその対策。
トラブルシューティング
oauth2client.client.HttpAccessTokenRefreshError
まず出たエラー
Traceback (most recent call last):
(中略)
gc = gspread.authorize(credentials)
File "/usr/local/lib/python2.7/dist-packages/gspread/client.py", line 331, in authorize
client.login()
File "/usr/local/lib/python2.7/dist-packages/gspread/client.py", line 101, in login
self.auth.refresh(http)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 659, in refresh
self._refresh(http.request)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 864, in _refresh
self._do_refresh_request(http_request)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 933, in _do_refresh_request
raise HttpAccessTokenRefreshError(error_msg, status=resp.status)
oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Invalid JWT: Token must be a short-lived token and in a reasonable timeframe
原因は時刻同期がされたいなかったこと(実時間より遅れていた)。
時刻を同期後に再度実行すると
oauth2client.client.HttpAccessTokenRefreshError
は出なくなった。
google api - Token must be a short-lived token and in a reasonable timeframe - Stack Overflow
http://stackoverflow.com/questions/36189612/token-must-be-a-short-lived-token-and-in-a-reasonable-timeframe
が、別のエラーで失敗。
requests.exceptions.SSLError
Traceback (most recent call last):
(中略)
wks = gc.open("testbook")
File "/usr/local/lib/python2.7/dist-packages/gspread/client.py", line 145, in open
feed = self.get_spreadsheets_feed()
File "/usr/local/lib/python2.7/dist-packages/gspread/client.py", line 231, in get_spreadsheets_feed
r = self.session.get(url)
File "/usr/local/lib/python2.7/dist-packages/gspread/httpsession.py", line 75, in get
return self.request('GET', url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/gspread/httpsession.py", line 67, in request
response = func(url, data=data, headers=request_headers)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 60, in get
return request('get', url, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 49, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 457, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 569, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 420, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError
python 2.7系だと発生する?Python 3.5.1では発生しなかった。
python 2.7での当面の対策は旧バージョンのcertifi
を入れること。
pip uninstall -y certifi && pip install certifi==2015.04.28
ssl - SSL3_GET_SERVER_CERTIFICATE certificate verify failed on Python when requesting (only) *.google.com - Stack Overflow
http://stackoverflow.com/questions/34646942/ssl3-get-server-certificate-certificate-verify-failed-on-python-when-requesting
元々入っていたcertifi
のバージョンは
pip list | grep certifi
certifi (2015.11.20.1)
再実行すると、requests.exceptions.SSLError
は出なくなったが、また別のエラーが発生。
SpreadsheetNotFound
Traceback (most recent call last):
(中略)
wks = gc.open("testbook")
File "/usr/local/lib/python2.7/dist-packages/gspread/client.py", line 152, in open
raise SpreadsheetNotFound
gspread.exceptions.SpreadsheetNotFound
gspread
のドキュメントに以下のような一文がある。
Using OAuth2 for Authorization — gspread 0.3.0 documentation
http://gspread.readthedocs.org/en/latest/oauth2.html
Go to Google Sheets and share your spreadsheet with an email you have in your json_key['client_email']. Otherwise you’ll get a SpreadsheetNotFound exception when trying to open it.
これの通り、Credential情報のJSONファイル中に記載されているclient_email
に
編集者権限を与えた。
再度実行すると成功した。
その他トラブルシューティング
PyOpenSSL
パッケージのインストールに失敗
PyOpenSSL の依存パッケージインストール(cffi
パッケージ)中に失敗した。
原因はLinux側の依存パッケージ不足。
cffi
パッケージのドキュメントを見ると以下の様な一文がある
on CPython, on non-Windows platforms, you also need to install libffi-dev in order to compile CFFI itself.
$ sudo aptitude search libffi-dev
p libffi-dev - Foreign Function Interface library (development files)
$ sudo aptitude install libffi-dev
pip install PyOpenSSL --upgrade
成功