-
Notifications
You must be signed in to change notification settings - Fork 17
Description
Copied from an internal bug 191836777 with some examples tweaked to have generic names.
@tseaver Could you take a look?
When creating a bq client with explicit project name, for example ('my-project') and explicit gcp json key ('other-project.json'). The connection context is set to the project specified in the json (other-project) and not the explicit one given as an argument (my-project).
Created a service account in project "pynix-cloud"
Create a test script as below:
from google.cloud import bigquery
project1 = "pynix-cloud"
project2 = "fileshare-project"
print('Creating client1 for project: %s' %project1)
client1 = bigquery.Client.from_service_account_json('owner-sa.json', project=project1)
print("Getting the project context for client1: %s" %client1.project)
print(" ")
print("Creating client2 for project: %s" %project2)
client2 = bigquery.Client.from_service_account_json('owner-sa.json', project=project2)
print("Getting the project context for client2: %s" %client2.project)Running this scripts outputs as below:
Creating client1 for project: pynix-cloud
Getting the project context for client1: pynix-cloud
Creating client2 for project: fileshare-project
Getting the project context for client2: pynix-cloud
However, the intended behaviour should be that the context for client2 should be the project "fileshare-project" as that is the project been passed explicitly as argument.
Debugging on the issue and going over the code I have following observations:
The bigquery client class has a call to super class "ClientWithProject" as per [1]. The class "ClientWithProject" is imported in the same code and is part of the core package [2].
I read thru the code for class "ClientWithProject" and stopped at this line [3]. I suspected there to be missing something so I tired to play around the same. What I did was I modified the line in [3]
from :
return cls.from_service_account_info(credentials_info)
to:
return cls.from_service_account_info(credentials_info,**kwargs)mind the keywords been passed as arguments. Post this I again ran my test script and I got the expected results, ie the context was from the project been passed as argument:
Creating client1 for project: pynix-cloud
Getting the project context for client1: pynix-cloud
Creating client2 for project: fileshare-project
Getting the project context for client2: fileshare-project
As this is something seen broken in v1.7 for core component. Looking at the release note for core 1.7 [4] there was a change where in we added 'Client.from_service_account_info' factory [5]. this function is indeed the one been called in [3]. If we refer to the code from 1.4.1 this was not implemented there [6]. Also when the customer downgraded the core component to 1.4 it started working as expected.
So my best take is that may be this is a bug and not the intended behaviour for v1.7. We might have missed passing the keywords as args so when at line [7] the keyword dict is empty and we tend to fetch the project from the service account json file itself.
Kindly let me know if this observation is correct and if we can do the required changes to get this working again in case the issue reported is not an indented behaviour in v1.7.
[2] from google.cloud.client import ClientWithProject
[3]
python-cloud-core/google/cloud/client.py
Line 109 in 1d3e273
| return cls.from_service_account_info(credentials_info) |
[4] https://github.com/googleapis/python-cloud-core/tree/master/google/cloud
[5] #54
[7]
python-cloud-core/google/cloud/client.py
Line 78 in 1d3e273
| if "project" not in kwargs: |
GitHub repository: https://github.com/googleapis/python-cloud-core