2

I'm unable to create Pub/Sub Publisher Client using .json file (instead using implicit Application Default / GOOGLE_APPLICATION_CREDENTIALS env var). Is something wrong I'm doing or does Pub/Sub has some nuances ? in which case why so...?

Most Google Client Libraries allow this, for ex BigQuery

client = bigquery.Client.from_service_account_json(json_credentials_path = ‘PATH/service_account.json')

Digging through PubSub Client Library code, I tried to do same with Pub/Sub Client Library:

from google.cloud.pubsub_v1.gapic.publisher_client import PublisherClient
publisher = PublisherClient.from_service_account_file(filename='PATH/service_account.json')

And get the following error:

Traceback (most recent call last): File "", line 1, in

File “/[VIRT_ENV_PATH]/lib/python3.6/site-packages/google/cloud/pubsub_v1/gapic/publisher_client.py", line 78, in from_service_account_file return cls(*args, **kwargs)

File "/[VIRT_ENV_PATH]/lib/python3.6/site-packages/google/cloud/pubsub_v1/gapic/publisher_client.py", line 167, in init self.iam_policy_stub = (iam_policy_pb2.IAMPolicyStub(channel))

File "/[VIRT_ENV_PATH]/lib/python3.6/site-packages/google/iam/v1/iam_policy_pb2.py", line 344, in init self.SetIamPolicy = channel.unary_unary( AttributeError: 'NoneType' object has no attribute 'unary_unary'

If I want to use key .json file, I could only make it work using workaround,

cred = `service_account.Credentials.from_service_account_file(filename = 'PATH/service_account.json')
publisher = pubsub_v1.PublisherClient(credentials = cred)

Thanks in advance for giving me.

Vibhor Jain
  • 1,396
  • 1
  • 11
  • 32
  • It looks like this function ask for some cls object ( *def from_service_account_file(cls, filename, *args, **kwargs):* ). But, in any case, inside the function it does exactly what you do. So, your workaround could be a good solution. Did you found what CLS stands for? – Temu Aug 17 '18 at 14:38
  • 1
    Hi Temu, it's a @classmethod, an thats why cls as first argument: https://stackoverflow.com/questions/12179271/meaning-of-classmethod-and-staticmethod-for-beginner – Vibhor Jain Aug 17 '18 at 18:34
  • Wow, you are totally right, I missed it. Long day. Sorry for the oversight! – Temu Aug 20 '18 at 10:57

1 Answers1

4

As far as I can see, we can do this in three different ways:

If you want to specify directly the key.json file instead of setting the environment variable GOOGLE_APPLICATION_CREDENTIALS as specified in docs... which would be this:

import os
import google.cloud.pubsub_v1 as pub 
os.environ['GOOGLE_APPLICATION_CREDENTIALS']='.path/auth.json'
publisher = pub.PublisherClient() 

Furthermore, you can use your workaround:

import google.cloud.pubsub_v1 as pub 
from google.cloud.pubsub_v1.gapic.publisher_client import PublisherClient 
cred = service_account.Credentials.from_service_account_file(filename = './auth.json') #or just from_service_account_file('./auth.json')
publisher = pub.PublisherClient(credentials = cred)

But regarding the third way...

from google.cloud.pubsub_v1.gapic.publisher_client import PublisherClient #VERSION 1
publisher = PublisherClient.from_service_account_file('./auth.json')
#which raises the same error than:
#publisher = PublisherClient('./auth.json') 

... a GitHub issue should be opened since it is related with providing none channel in the constructor, line 101 and this is not behavior expected. You were doing it right on the first time.

Temu
  • 859
  • 4
  • 11