LoginSignup
8
8

More than 5 years have passed since last update.

[Python] gspreadでGoogle Spreadsheetにアクセスするまでのトラブルシューティング

Posted at

やること

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

成功

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8