From b8b1c454d05ede9b111826f67dfb05a75bcc043c Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Fri, 30 Aug 2019 14:13:24 -0700 Subject: [PATCH 1/4] Add to constructor. --- spanner/google/cloud/spanner_v1/client.py | 20 +++++++++++++++++--- spanner/tests/unit/test_client.py | 22 ++++++++++++++++++---- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/spanner/google/cloud/spanner_v1/client.py b/spanner/google/cloud/spanner_v1/client.py index a6f3bd25f5e6..e112a5b7b411 100644 --- a/spanner/google/cloud/spanner_v1/client.py +++ b/spanner/google/cloud/spanner_v1/client.py @@ -110,6 +110,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 ` if both ``read_only`` and ``admin`` are :data:`True` @@ -124,7 +128,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 @@ -133,6 +142,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) @@ -172,7 +182,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 @@ -181,7 +193,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 diff --git a/spanner/tests/unit/test_client.py b/spanner/tests/unit/test_client.py index 8cef6313afe9..e42031cea4fb 100644 --- a/spanner/tests/unit/test_client.py +++ b/spanner/tests/unit/test_client.py @@ -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 @@ -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 @@ -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,) @@ -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) @@ -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,) @@ -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) From 21a392fef4449264da6f714df3f8479fc442b836 Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Fri, 30 Aug 2019 14:16:59 -0700 Subject: [PATCH 2/4] Add client_options to Database.spanner_api. --- spanner/google/cloud/spanner_v1/database.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spanner/google/cloud/spanner_v1/database.py b/spanner/google/cloud/spanner_v1/database.py index 77efca155a98..0ab04a87e3a4 100644 --- a/spanner/google/cloud/spanner_v1/database.py +++ b/spanner/google/cloud/spanner_v1/database.py @@ -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 From d8afd8b1b1eb10c339b75d1096e6fbceb5e3a63f Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Fri, 18 Oct 2019 17:12:08 -0700 Subject: [PATCH 3/4] test: add mocks for client_options --- spanner/tests/unit/test_database.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spanner/tests/unit/test_database.py b/spanner/tests/unit/test_database.py index e553e0bbb8dc..5445fb9f0519 100644 --- a/spanner/tests/unit/test_database.py +++ b/spanner/tests/unit/test_database.py @@ -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() @@ -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): @@ -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() From 0ff911c459e7c819136f1292276cc1d70a05025f Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Mon, 21 Oct 2019 11:02:25 -0700 Subject: [PATCH 4/4] test: add assert for client_options --- spanner/tests/unit/test_database.py | 1 + 1 file changed, 1 insertion(+) diff --git a/spanner/tests/unit/test_database.py b/spanner/tests/unit/test_database.py index 5445fb9f0519..f6f367e00161 100644 --- a/spanner/tests/unit/test_database.py +++ b/spanner/tests/unit/test_database.py @@ -295,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)