I seem to have hit a roadblock with my project which posts values to Google Sheets using gspread, which used to work perfectly until Google changed the required protocol for authentication to OAuth 2.0. I am unable to authenticate using the OAuth2 method provided by gspread because my application is broken on the Yun. I believe the issue is that oauth2client attempts to reference (call?) the undefined attribute (method?) sign from the OpenSSL module crypto. Apparently this can be fixed by updating the pyOpenSSL package to version 0.11 or higher (current version is 0.15) but I have been unable to find any version other than .10 compiled for the Yun. This is a roadblock for me at my novice skill level. I have tried hard to find a solution before I came here for help. I noticed that Federico Fissore seems to have gotten around this very problem with the Badger project?
- Insert 8 GB sd card.
- Upgrade Yun - YunSysupgradeImage_v1.5.3.zip
- Expand the Yún disk space - YunDiskSpaceExpander.ino
- Add swap partition.
- SSH into Yun…
- Prepare to Install gspread and necessary dependencies:
opkg update
opkg install nano
opkg install python-openssl
opkg install python-expat
opkg install distribute
- Install gspread
easy_install gspread
8.) Install OpenSSL.
opkg install pyopenssl
opkg upgrade libopenssl
Easy_install oauth2client
Note: In my attempts after the failure below, I did:
easy_install pip
pip install --upgrade pyopenssl
That was unsuccessful.
- Follow steps 1-4 to obtain credentials from google for the gspread OAuth2 authentication method here:
http://gspread.readthedocs.org/en/latest/oauth2.html
- Copy credentials to Yun (.json file from google)
/mnt/sd/oauth_test/HomeMon2-58d0c076206d.json
- My abbreviated python code for gspread from start to the point of failure:
# /mnt/sd/oauth_test/oauth_test.p
# -*- coding: utf-8 -*-
import gspread
import json
from oauth2client.client import SignedJwtAssertionCredentials
json_key = json.load(open('/mnt/sd/oauth_test/HomeMon2-58d0c076206d.json'))
scope = ['https://spreadsheets.google.com/feeds']
credentials = SignedJwtAssertionCredentials(json_key['client_email'], json_key['private_key'], scope)
print "Getting creds"
self.gc = gspread.authorize(credentials)
Here’s the traceback :
root@JBYun2:~# python /mnt/sd/oauth_test/oauth_test.py
Getting creds
Traceback (most recent call last):
File "/mnt/sd/oauth_test/oauth_test.py", line 21, in <module>
self.gc = gspread.authorize(credentials)
File "/usr/lib/python2.7/site-packages/gspread-0.2.5-py2.7.egg/gspread/client.py", line 335, in authorize
client.login()
File "/usr/lib/python2.7/site-packages/gspread-0.2.5-py2.7.egg/gspread/client.py", line 98, in login
self.auth.refresh(http)
File "/usr/lib/python2.7/site-packages/oauth2client-1.4.11-py2.7.egg/oauth2client/client.py", line 598, in refresh
self._refresh(http.request)
File "/usr/lib/python2.7/site-packages/oauth2client-1.4.11-py2.7.egg/oauth2client/client.py", line 769, in _refresh
self._do_refresh_request(http_request)
File "/usr/lib/python2.7/site-packages/oauth2client-1.4.11-py2.7.egg/oauth2client/client.py", line 795, in _do_refresh_request
body = self._generate_refresh_request_body()
File "/usr/lib/python2.7/site-packages/oauth2client-1.4.11-py2.7.egg/oauth2client/client.py", line 1425, in _generate_refresh_request_body
assertion = self._generate_assertion()
File "/usr/lib/python2.7/site-packages/oauth2client-1.4.11-py2.7.egg/oauth2client/client.py", line 1554, in _generate_assertion
private_key, self.private_key_password), payload)
File "/usr/lib/python2.7/site-packages/oauth2client-1.4.11-py2.7.egg/oauth2client/crypt.py", line 380, in make_signed_jwt
signature = signer.sign(signing_input)
File "/usr/lib/python2.7/site-packages/oauth2client-1.4.11-py2.7.egg/oauth2client/crypt.py", line 146, in sign
return crypto.sign(self._key, message, 'sha256')
AttributeError: 'module' object has no attribute 'sign'
root@JBYun2:~#
From what I can tell after googling, the issue can be summarized as;
OAuth2Client relies on PyOpenSSL and some older versions of PyOpenSSL do not have this method.
Is my code failing because the version of pyopenssl is older and the method is not available? Or can anyone tell me if I am doing something wrong/suggest a solution for this problem?
Thank You,
Jeff