AttributeError: 'module' object has no attribute 'SignedJwtAssertionCredentials'
Asked Answered
B

2

11

Problem: I've been using Python Script Samples by Google to upload the apk to Play Store and to get list of apps published via my account (list_apks.py and upload_apk.py). However recently it started breaking. I've tried to update the packages like google-api-python-client, oath2client etc by doing pip install --update packagename but it didn't help.

Logs:

This if while listing apk's:

Determining latest version for my.package.name...
error   25-Feb-2016 06:30:52    Traceback (most recent call last):
error   25-Feb-2016 06:30:52      File "list_apks.py", line 80, in <module>
error   25-Feb-2016 06:30:52        main()
error   25-Feb-2016 06:30:52      File "list_apks.py", line 46, in main
error   25-Feb-2016 06:30:52        credentials = client.SignedJwtAssertionCredentials(
error   25-Feb-2016 06:30:52    AttributeError: 'module' object has no attribute 'SignedJwtAssertionCredentials'
build   25-Feb-2016 06:30:52    Found latest APK version: 
build   25-Feb-2016 06:30:52    Generated new APK version: 1

This is when uploading apk:

25-Feb-2016 06:33:30    Uploading APK...
25-Feb-2016 06:33:30    Traceback (most recent call last):
25-Feb-2016 06:33:30      File "upload_apk.py", line 115, in <module>
25-Feb-2016 06:33:30        main(sys.argv)
25-Feb-2016 06:33:30      File "upload_apk.py", line 62, in main
25-Feb-2016 06:33:30        credentials = client.SignedJwtAssertionCredentials(
25-Feb-2016 06:33:30    AttributeError: 'module' object has no attribute 'SignedJwtAssertionCredentials'

Code sniplet:

import argparse

from apiclient.discovery import build
import httplib2
from oauth2client import client


SERVICE_ACCOUNT_EMAIL = (
    'myaccountemail.com')

# Declare command-line flags.
argparser = argparse.ArgumentParser(add_help=False)
argparser.add_argument('package_name',
                       help='The package name. Example: com.android.sample')


def main():
  # Load the key in PKCS 12 format that you downloaded from the Google APIs
  # Console when you created your Service account.
  f = file('mykeyname.p12', 'rb')
  key = f.read()
  f.close()

  # HERE IS THE EXCEPTION 
  credentials = client.SignedJwtAssertionCredentials(
      SERVICE_ACCOUNT_EMAIL,
      key,
      scope='https://www.googleapis.com/auth/androidpublisher')
  http = httplib2.Http()
  http = credentials.authorize(http)
  ...

What else I can try? I would appreciate your help.

Blanca answered 25/2, 2016 at 17:22 Comment(0)
B
30

Finally after so many days, I was able to find answer to it. It turns out that the class SignedJwtAssertionCredentials was removed from the oath2client python package in the 2.0.0 update. It was no more under oauth2client.client. The behaviour has been moved onto oauth2client.service_account.ServiceAccountCredentials.

Following worked for me:

import argparse

from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials

import httplib2
from oauth2client import client

SERVICE_ACCOUNT_EMAIL = ('myaccountemail.com')

# Declare command-line flags.
argparser = argparse.ArgumentParser(add_help=False)
argparser.add_argument('package_name',
                   help='The package name. Example: com.android.sample')

def main():
  key='mykeyname.p12'
  scope = 'https://www.googleapis.com/auth/androidpublisher'

  credentials = ServiceAccountCredentials.from_p12_keyfile(
      SERVICE_ACCOUNT_EMAIL,
      key,
      scopes=[scope]
  )
  http = httplib2.Http()
  http = credentials.authorize(http)
  ....

Source:

Blanca answered 27/2, 2016 at 6:7 Comment(4)
Thank you for sharing your solution, google python code samples on this project suck!Dye
Yeah, especially since it's now 2020, and their 'official' examples on how to do this are massively out of date.Chenee
That's not simply moving the class elsewhere. That's a completely different class...Copley
@Copley Thanks for the comment. It's been a while since I wrote this answer. On reading again, it seems the answer says that the behaviour has been moved to a different class, and doesn't necessarily imply that the class itself has been moved. However, if you feel answer can be improved, please feel free to suggest an edit :)Blanca
E
2

I had the same problem and also I did not have pyOpenSSL installed which is required when using from_p12_keyfile().

from_p12_keyfile()

Raises:
NotImplementedError if pyOpenSSL is not installed / not the active crypto library.

I read the JSON file into dictionary and passed it to from_json_keyfile_dict() like this:

import json
from oauth2client.service_account import ServiceAccountCredentials
# other imports and code from sample...

# modified authentication part
data = {}
with open('api.json') as json_file:
  data = json.load(json_file)
credentials = ServiceAccountCredentials.from_json_keyfile_dict(
    data,
    scopes=['https://www.googleapis.com/auth/androidpublisher']
)
http = httplib2.Http()
http = credentials.authorize(http)
# do what ever you want with the returned object

api.json file refers to the file which gets created when service account is created.

Of course there is also couple other functions to get the credentials but this solution helped me to get the stuff working. Maybe this will help someone in future.

Reference: Oauth2Client.service_account

Ellswerth answered 16/12, 2020 at 16:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.