From 7d55faca782b0ff6e446b5c63be9b0922f3fe42f Mon Sep 17 00:00:00 2001 From: Seth Hollyman Date: Fri, 12 Jan 2024 19:11:56 +0000 Subject: [PATCH 1/5] feat: support universe resolution This PR wires up consumption of the universe_domain client option for resolving the endpoint for constructing the BQ client. Testing universes is not yet something we want to in this repo, so validation was done out of band. --- google/cloud/bigquery/_helpers.py | 2 ++ google/cloud/bigquery/client.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/google/cloud/bigquery/_helpers.py b/google/cloud/bigquery/_helpers.py index 4cf6dddac..035954681 100644 --- a/google/cloud/bigquery/_helpers.py +++ b/google/cloud/bigquery/_helpers.py @@ -55,6 +55,8 @@ _DEFAULT_HOST = "https://bigquery.googleapis.com" """Default host for JSON API.""" +_DEFAULT_UNIVERSE = "googleapis.com" +"""Default universe for the JSON API.""" def _get_bigquery_host(): return os.environ.get(BIGQUERY_EMULATOR_HOST, _DEFAULT_HOST) diff --git a/google/cloud/bigquery/client.py b/google/cloud/bigquery/client.py index 182319646..409c3e7fe 100644 --- a/google/cloud/bigquery/client.py +++ b/google/cloud/bigquery/client.py @@ -78,6 +78,7 @@ from google.cloud.bigquery._helpers import _verify_job_config_type from google.cloud.bigquery._helpers import _get_bigquery_host from google.cloud.bigquery._helpers import _DEFAULT_HOST +from google.cloud.bigquery._helpers import _DEFAULT_UNIVERSE from google.cloud.bigquery._job_helpers import make_job_id as _make_job_id from google.cloud.bigquery.dataset import Dataset from google.cloud.bigquery.dataset import DatasetListItem @@ -252,6 +253,8 @@ def __init__( if client_options.api_endpoint: api_endpoint = client_options.api_endpoint kw_args["api_endpoint"] = api_endpoint + elif client_options.universe_domain and client_options.universe_domain is not _DEFAULT_UNIVERSE: + kw_args["api_endpoint"] = _DEFAULT_HOST.replace(_DEFAULT_UNIVERSE, client_options.universe_domain) self._connection = Connection(self, **kw_args) self._location = location From 276a257cbad3dbcd4f63fc1d76205129b628f11d Mon Sep 17 00:00:00 2001 From: Seth Hollyman Date: Fri, 12 Jan 2024 19:23:06 +0000 Subject: [PATCH 2/5] formatting and testing --- google/cloud/bigquery/_helpers.py | 1 + google/cloud/bigquery/client.py | 9 +++++++-- tests/unit/test_client.py | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/google/cloud/bigquery/_helpers.py b/google/cloud/bigquery/_helpers.py index 035954681..905d4aee1 100644 --- a/google/cloud/bigquery/_helpers.py +++ b/google/cloud/bigquery/_helpers.py @@ -58,6 +58,7 @@ _DEFAULT_UNIVERSE = "googleapis.com" """Default universe for the JSON API.""" + def _get_bigquery_host(): return os.environ.get(BIGQUERY_EMULATOR_HOST, _DEFAULT_HOST) diff --git a/google/cloud/bigquery/client.py b/google/cloud/bigquery/client.py index 409c3e7fe..bbafd796a 100644 --- a/google/cloud/bigquery/client.py +++ b/google/cloud/bigquery/client.py @@ -253,8 +253,13 @@ def __init__( if client_options.api_endpoint: api_endpoint = client_options.api_endpoint kw_args["api_endpoint"] = api_endpoint - elif client_options.universe_domain and client_options.universe_domain is not _DEFAULT_UNIVERSE: - kw_args["api_endpoint"] = _DEFAULT_HOST.replace(_DEFAULT_UNIVERSE, client_options.universe_domain) + elif ( + client_options.universe_domain + and client_options.universe_domain is not _DEFAULT_UNIVERSE + ): + kw_args["api_endpoint"] = _DEFAULT_HOST.replace( + _DEFAULT_UNIVERSE, client_options.universe_domain + ) self._connection = Connection(self, **kw_args) self._location = location diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index ad22e0ddb..28cbf8ce9 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -201,6 +201,20 @@ def test_ctor_w_client_options_object(self): client._connection.API_BASE_URL, "https://www.foo-googleapis.com" ) + def test_ctor_w_client_options_universe(self): + from google.api_core.client_options import ClientOptions + + creds = _make_credentials() + http = object() + client_options = ClientOptions(universe_domain="foo.com") + client = self._make_one( + project=self.PROJECT, + credentials=creds, + _http=http, + client_options=client_options, + ) + self.assertEqual(client._connection.API_BASE_URL, "https://bigquery.foo.com") + def test_ctor_w_location(self): from google.cloud.bigquery._http import Connection From 25998bf62fcd9d20ee7ee4c46693c7897bfcf81f Mon Sep 17 00:00:00 2001 From: Seth Hollyman Date: Fri, 12 Jan 2024 21:22:59 +0000 Subject: [PATCH 3/5] conditionals for stale core --- google/cloud/bigquery/client.py | 1 + tests/unit/test_client.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/google/cloud/bigquery/client.py b/google/cloud/bigquery/client.py index bbafd796a..03f82d49c 100644 --- a/google/cloud/bigquery/client.py +++ b/google/cloud/bigquery/client.py @@ -254,6 +254,7 @@ def __init__( api_endpoint = client_options.api_endpoint kw_args["api_endpoint"] = api_endpoint elif ( + hasattr(client_options, "universe_domain") and client_options.universe_domain and client_options.universe_domain is not _DEFAULT_UNIVERSE ): diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 28cbf8ce9..db48c1c0c 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -201,12 +201,14 @@ def test_ctor_w_client_options_object(self): client._connection.API_BASE_URL, "https://www.foo-googleapis.com" ) + @pytest.mark.skipif(packaging.version.parse(getattr(google.api_core, "__version__", "0.0.0")) < packaging.version.Version('2.15.0'), + reason="universe_domain not supported with google-api-core < 2.15.0") def test_ctor_w_client_options_universe(self): from google.api_core.client_options import ClientOptions creds = _make_credentials() http = object() - client_options = ClientOptions(universe_domain="foo.com") + client_options = {"universe_domain": "foo.com"} client = self._make_one( project=self.PROJECT, credentials=creds, From f73e6c76d64d0c526be5ada093bccbc71ebe4e25 Mon Sep 17 00:00:00 2001 From: Seth Hollyman Date: Fri, 12 Jan 2024 21:29:21 +0000 Subject: [PATCH 4/5] formatting --- google/cloud/bigquery/client.py | 4 ++-- tests/unit/test_client.py | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/google/cloud/bigquery/client.py b/google/cloud/bigquery/client.py index 03f82d49c..b2ea130c4 100644 --- a/google/cloud/bigquery/client.py +++ b/google/cloud/bigquery/client.py @@ -254,8 +254,8 @@ def __init__( api_endpoint = client_options.api_endpoint kw_args["api_endpoint"] = api_endpoint elif ( - hasattr(client_options, "universe_domain") and - client_options.universe_domain + hasattr(client_options, "universe_domain") + and client_options.universe_domain and client_options.universe_domain is not _DEFAULT_UNIVERSE ): kw_args["api_endpoint"] = _DEFAULT_HOST.replace( diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index db48c1c0c..9c5c5859a 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -201,8 +201,11 @@ def test_ctor_w_client_options_object(self): client._connection.API_BASE_URL, "https://www.foo-googleapis.com" ) - @pytest.mark.skipif(packaging.version.parse(getattr(google.api_core, "__version__", "0.0.0")) < packaging.version.Version('2.15.0'), - reason="universe_domain not supported with google-api-core < 2.15.0") + @pytest.mark.skipif( + packaging.version.parse(getattr(google.api_core, "__version__", "0.0.0")) + < packaging.version.Version("2.15.0"), + reason="universe_domain not supported with google-api-core < 2.15.0", + ) def test_ctor_w_client_options_universe(self): from google.api_core.client_options import ClientOptions From 80a69b9f61d130d59138b0467fdb6aa41dc71792 Mon Sep 17 00:00:00 2001 From: Seth Hollyman Date: Fri, 12 Jan 2024 22:49:00 +0000 Subject: [PATCH 5/5] unused import --- tests/unit/test_client.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 9c5c5859a..56bdbad5e 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -207,8 +207,6 @@ def test_ctor_w_client_options_object(self): reason="universe_domain not supported with google-api-core < 2.15.0", ) def test_ctor_w_client_options_universe(self): - from google.api_core.client_options import ClientOptions - creds = _make_credentials() http = object() client_options = {"universe_domain": "foo.com"}