I'm trying to connect to Google Analytics in a server application, following the instructions here: https://developers.google.com/analytics/devguides/reporting/core/v3/quickstart/service-py. This page suggests using the P12 key, but I need to use the JSON key for business reasons (it's also "recommended" on the key generation page in developer console).
The code example works fine for me when I use a P12 file - the authorize
and build
calls both work, and then I can use the API properly. I can't use a JSON file. Here is a minimal example:
from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials
import json
import base64
import httplib2
def authorize(ga_email, ga_secret):
jwt = SignedJwtAssertionCredentials(ga_email, ga_secret, scope=self.ga_scope, private_key_password='notasecret')
http = jwt.authorize(httplib2.Http())
return build('analytics', 'v3', http=http)
# this works
ga_email = 'random@words.gserviceaccount.com'
with open('client_secrets.p12', 'rb') as f:
ga_secret = f.read()
service = authorize(ga_email, ga_secret)
# this fails
with open('client_secrets.json', 'r') as f:
json_data = json.load(f)
ga_email = json_data['client_email']
ga_secret_json = json_data['private_key']
ga_secret_b64 = ''.join(ga_secret_json.split('\n')[1:-2])
ga_secret_bin = base64.b64decode(ga_secret_b64)
ga_secret = ga_secret_bin # or ga_secret_b64 or ga_secret_json
service = authorize(ga_email, ga_secret)
The JSON attempt fails with this error (using ga_secret_bin):
File "/usr/local/lib/python2.7/dist-packages/pyOpenSSL-0.15.1-py2.7.egg/OpenSSL/_util.py", line 48, in exception_from_error_queue
raise exception_type(errors)
Error: [('asn1 encoding routines', 'ASN1_CHECK_TLEN', 'wrong tag'), ('asn1 encoding routines', 'ASN1_TEMPLATE_EX_D2I', 'nested asn1 error'), ('asn1 encoding routines', 'ASN1_TEMPLATE_NOEXP_D2I', 'nested asn1 error')]
Or similarly (using ga_secret_json or ga_secret_b64):
Error: [('asn1 encoding routines', 'ASN1_CHECK_TLEN', 'wrong tag'), ('asn1 encoding routines', 'ASN1_ITEM_EX_D2I', 'nested asn1 error')]
I've tried a few other permutations: variations on the string processing and base64 decoding, not using the private_key_password
arg, et cetera. I also tried using from_json
by populating the email, key, and other fields based on the output of to_json
after creating a credentials object with a P12 key.
I think I'm missing something simple, but I'm not very familiar with OpenSSL, so I don't know what to look for.