Skip to content

Commit

Permalink
feat(spanner): add client_options to constructor (#9151)
Browse files Browse the repository at this point in the history
  • Loading branch information
busunkim96 committed Oct 22, 2019
1 parent 9872fb0 commit fbc10b8
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
20 changes: 17 additions & 3 deletions spanner/google/cloud/spanner_v1/client.py
Expand Up @@ -111,6 +111,10 @@ class Client(ClientWithProject):
:param user_agent:
(Deprecated) The user agent to be used with API request.
Not used.
:type client_options: :class:`~google.api_core.client_options.ClientOptions`
or :class:`dict`
:param client_options: (Optional) Client options used to set user options
on the client. API Endpoint should be set through client_options.
:raises: :class:`ValueError <exceptions.ValueError>` if both ``read_only``
and ``admin`` are :data:`True`
Expand All @@ -125,7 +129,12 @@ class Client(ClientWithProject):
"""The scopes required for Google Cloud Spanner."""

def __init__(
self, project=None, credentials=None, client_info=_CLIENT_INFO, user_agent=None
self,
project=None,
credentials=None,
client_info=_CLIENT_INFO,
user_agent=None,
client_options=None,
):
# NOTE: This API has no use for the _http argument, but sending it
# will have no impact since the _http() @property only lazily
Expand All @@ -134,6 +143,7 @@ def __init__(
project=project, credentials=credentials, _http=None
)
self._client_info = client_info
self._client_options = client_options

if user_agent is not None:
warnings.warn(_USER_AGENT_DEPRECATED, DeprecationWarning, stacklevel=2)
Expand Down Expand Up @@ -173,7 +183,9 @@ def instance_admin_api(self):
"""Helper for session-related API calls."""
if self._instance_admin_api is None:
self._instance_admin_api = InstanceAdminClient(
credentials=self.credentials, client_info=self._client_info
credentials=self.credentials,
client_info=self._client_info,
client_options=self._client_options,
)
return self._instance_admin_api

Expand All @@ -182,7 +194,9 @@ def database_admin_api(self):
"""Helper for session-related API calls."""
if self._database_admin_api is None:
self._database_admin_api = DatabaseAdminClient(
credentials=self.credentials, client_info=self._client_info
credentials=self.credentials,
client_info=self._client_info,
client_options=self._client_options,
)
return self._database_admin_api

Expand Down
5 changes: 4 additions & 1 deletion spanner/google/cloud/spanner_v1/database.py
Expand Up @@ -177,8 +177,11 @@ def spanner_api(self):
if isinstance(credentials, google.auth.credentials.Scoped):
credentials = credentials.with_scopes((SPANNER_DATA_SCOPE,))
client_info = self._instance._client._client_info
client_options = self._instance._client._client_options
self._spanner_api = SpannerClient(
credentials=credentials, client_info=client_info
credentials=credentials,
client_info=client_info,
client_options=client_options,
)
return self._spanner_api

Expand Down
22 changes: 18 additions & 4 deletions spanner/tests/unit/test_client.py
Expand Up @@ -55,6 +55,7 @@ def _constructor_test_helper(
expected_creds=None,
client_info=None,
user_agent=None,
client_options=None,
):
from google.cloud.spanner_v1 import client as MUT

Expand All @@ -79,6 +80,7 @@ def _constructor_test_helper(
self.assertEqual(client.project, self.PROJECT)
self.assertIs(client._client_info, expected_client_info)
self.assertEqual(client.user_agent, user_agent)
self.assertEqual(client._client_options, client_options)

def test_constructor_default_scopes(self):
from google.cloud.spanner_v1 import client as MUT
Expand Down Expand Up @@ -130,8 +132,12 @@ def test_instance_admin_api(self):

credentials = _make_credentials()
client_info = mock.Mock()
client_options = mock.Mock()
client = self._make_one(
project=self.PROJECT, credentials=credentials, client_info=client_info
project=self.PROJECT,
credentials=credentials,
client_info=client_info,
client_options=client_options,
)
expected_scopes = (SPANNER_ADMIN_SCOPE,)

Expand All @@ -146,7 +152,9 @@ def test_instance_admin_api(self):
self.assertIs(again, api)

instance_admin_client.assert_called_once_with(
credentials=credentials.with_scopes.return_value, client_info=client_info
credentials=credentials.with_scopes.return_value,
client_info=client_info,
client_options=client_options,
)

credentials.with_scopes.assert_called_once_with(expected_scopes)
Expand All @@ -156,8 +164,12 @@ def test_database_admin_api(self):

credentials = _make_credentials()
client_info = mock.Mock()
client_options = mock.Mock()
client = self._make_one(
project=self.PROJECT, credentials=credentials, client_info=client_info
project=self.PROJECT,
credentials=credentials,
client_info=client_info,
client_options=client_options,
)
expected_scopes = (SPANNER_ADMIN_SCOPE,)

Expand All @@ -172,7 +184,9 @@ def test_database_admin_api(self):
self.assertIs(again, api)

database_admin_client.assert_called_once_with(
credentials=credentials.with_scopes.return_value, client_info=client_info
credentials=credentials.with_scopes.return_value,
client_info=client_info,
client_options=client_options,
)

credentials.with_scopes.assert_called_once_with(expected_scopes)
Expand Down
7 changes: 6 additions & 1 deletion spanner/tests/unit/test_database.py
Expand Up @@ -233,6 +233,7 @@ def test_name_property(self):
def test_spanner_api_property_w_scopeless_creds(self):
client = _Client()
client_info = client._client_info = mock.Mock()
client_options = client._client_options = mock.Mock()
credentials = client.credentials = object()
instance = _Instance(self.INSTANCE_NAME, client=client)
pool = _Pool()
Expand All @@ -250,7 +251,9 @@ def test_spanner_api_property_w_scopeless_creds(self):
self.assertIs(again, api)

spanner_client.assert_called_once_with(
credentials=credentials, client_info=client_info
credentials=credentials,
client_info=client_info,
client_options=client_options,
)

def test_spanner_api_w_scoped_creds(self):
Expand All @@ -271,6 +274,7 @@ def with_scopes(self, scopes):
expected_scopes = (SPANNER_DATA_SCOPE,)
client = _Client()
client_info = client._client_info = mock.Mock()
client_options = client._client_options = mock.Mock()
credentials = client.credentials = _CredentialsWithScopes()
instance = _Instance(self.INSTANCE_NAME, client=client)
pool = _Pool()
Expand All @@ -291,6 +295,7 @@ def with_scopes(self, scopes):
called_args, called_kw = spanner_client.call_args
self.assertEqual(called_args, ())
self.assertEqual(called_kw["client_info"], client_info)
self.assertEqual(called_kw["client_options"], client_options)
scoped = called_kw["credentials"]
self.assertEqual(scoped._scopes, expected_scopes)
self.assertIs(scoped._source, credentials)
Expand Down

0 comments on commit fbc10b8

Please sign in to comment.