Skip to content

Commit 7875e80

Browse files
committed
check universe is not supported for api-core <= 2.18.0
1 parent 9ce24de commit 7875e80

File tree

2 files changed

+156
-115
lines changed

2 files changed

+156
-115
lines changed

googleapiclient/discovery.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@
130130
STACK_QUERY_PARAMETERS = frozenset(["trace", "pp", "userip", "strict"])
131131
STACK_QUERY_PARAMETER_DEFAULT_VALUE = {"type": "string", "location": "query"}
132132

133+
class APICoreVersionError(ValueError):
134+
def __init__(self):
135+
message = "google-api-core >= 2.18.0 is required to use the universe domain feature."
136+
super().__init__(message)
137+
133138
# Library-specific reserved words beyond Python keywords.
134139
RESERVED_WORDS = frozenset(["body"])
135140

@@ -559,6 +564,9 @@ def build_from_document(
559564
client_options.universe_domain, universe_domain_env
560565
)
561566
base = base.replace(universe.DEFAULT_UNIVERSE, universe_domain)
567+
else:
568+
if client_options.universe_domain:
569+
raise APICoreVersionError
562570

563571
audience_for_self_signed_jwt = base
564572
if client_options.api_endpoint:
@@ -613,7 +621,7 @@ def build_from_document(
613621
):
614622
credentials = credentials.with_always_use_jwt_access(always_use_jwt_access)
615623
credentials._create_self_signed_jwt(audience_for_self_signed_jwt)
616-
624+
617625
# If credentials are provided, create an authorized http instance;
618626
# otherwise, skip authentication.
619627
if credentials:
@@ -688,6 +696,12 @@ def build_from_document(
688696
)
689697
base = mtls_endpoint
690698

699+
if not HAS_UNIVERSE:
700+
credentials = getattr(http, "credentials", None)
701+
universe_domain = getattr(credentials, "universe_domain", None)
702+
if universe_domain != "googleapis.com":
703+
raise APICoreVersionError
704+
691705
if model is None:
692706
features = service.get("features", [])
693707
model = JsonModel("dataWrapper" in features)

tests/test_discovery.py

Lines changed: 141 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
V1_DISCOVERY_URI,
7272
V2_DISCOVERY_URI,
7373
ResourceMethodParameters,
74+
APICoreVersionError,
7475
_fix_up_media_path_base_url,
7576
_fix_up_media_upload,
7677
_fix_up_method_description,
@@ -2501,170 +2502,196 @@ def test_validate_credentials_with_already_validated_credentials(self):
25012502
# Calling service._validate_credentials() again returns service.credentials_validated.
25022503
assert service._validate_credentials()
25032504

2504-
def test_validate_credentials_before_api_request_success(self):
2505-
fake_universe = "foo.com"
2506-
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2507-
credentials.universe_domain = fake_universe
2508-
discovery = read_datafile("tasks.json")
2509-
tasks = build_from_document(
2510-
discovery,
2511-
credentials=credentials,
2512-
client_options=google.api_core.client_options.ClientOptions(
2513-
universe_domain=fake_universe
2514-
),
2515-
)
2516-
2517-
tasklists = tasks.tasklists()
2518-
request = tasklists.list()
2519-
2520-
# Check that credentials are indeed verified before request.
2521-
assert tasklists._validate_credentials()
2522-
2523-
def test_validate_credentials_before_api_request_failure(self):
2524-
fake_universe = "foo.com"
2525-
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2526-
credentials.universe_domain = fake_universe
2527-
discovery = read_datafile("tasks.json")
2528-
tasks = build_from_document(
2529-
discovery,
2530-
credentials=credentials,
2531-
client_options=google.api_core.client_options.ClientOptions(
2532-
universe_domain=universe.DEFAULT_UNIVERSE
2533-
),
2534-
)
2505+
def test_validate_credentials_before_api_request_success(self):
2506+
fake_universe = "foo.com"
2507+
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2508+
credentials.universe_domain = fake_universe
2509+
discovery = read_datafile("tasks.json")
2510+
tasks = build_from_document(
2511+
discovery,
2512+
credentials=credentials,
2513+
client_options=google.api_core.client_options.ClientOptions(
2514+
universe_domain=fake_universe
2515+
),
2516+
)
25352517

2536-
# Check that credentials are verified before request.
2537-
with self.assertRaises(universe.UniverseMismatchError):
2538-
request = tasks.tasklists().list()
2518+
tasklists = tasks.tasklists()
2519+
request = tasklists.list()
25392520

2540-
def test_validate_credentials_before_another_universe_api_request_failure(self):
2541-
fake_universe = "foo.com"
2542-
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2543-
credentials.universe_domain = fake_universe
2544-
another_fake_universe = "bar.com"
2545-
discovery = read_datafile("tasks.json")
2546-
tasks = build_from_document(
2547-
discovery,
2548-
credentials=credentials,
2549-
client_options=google.api_core.client_options.ClientOptions(
2550-
universe_domain=another_fake_universe
2551-
),
2552-
)
2521+
# Check that credentials are indeed verified before request.
2522+
assert tasklists._validate_credentials()
25532523

2554-
# Check that credentials are verified before request.
2555-
with self.assertRaises(universe.UniverseMismatchError):
2556-
request = tasks.tasklists().list()
2524+
def test_validate_credentials_before_api_request_failure(self):
2525+
fake_universe = "foo.com"
2526+
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2527+
credentials.universe_domain = fake_universe
2528+
discovery = read_datafile("tasks.json")
2529+
tasks = build_from_document(
2530+
discovery,
2531+
credentials=credentials,
2532+
client_options=google.api_core.client_options.ClientOptions(
2533+
universe_domain=universe.DEFAULT_UNIVERSE
2534+
),
2535+
)
25572536

2558-
def test_client_options_with_empty_universe(self):
2559-
fake_universe = "foo.com"
2560-
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2561-
discovery = read_datafile("tasks.json")
2537+
# Check that credentials are verified before request.
2538+
with self.assertRaises(universe.UniverseMismatchError):
2539+
request = tasks.tasklists().list()
25622540

2563-
with self.assertRaises(universe.EmptyUniverseError):
2541+
def test_validate_credentials_before_another_universe_api_request_failure(self):
2542+
fake_universe = "foo.com"
2543+
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2544+
credentials.universe_domain = fake_universe
2545+
another_fake_universe = "bar.com"
2546+
discovery = read_datafile("tasks.json")
25642547
tasks = build_from_document(
25652548
discovery,
25662549
credentials=credentials,
25672550
client_options=google.api_core.client_options.ClientOptions(
2568-
universe_domain=""
2551+
universe_domain=another_fake_universe
25692552
),
25702553
)
25712554

2572-
def test_client_options_universe_configured_with_mtls(self):
2573-
fake_universe = "foo.com"
2574-
discovery = read_datafile("tasks.json")
2555+
# Check that credentials are verified before request.
2556+
with self.assertRaises(universe.UniverseMismatchError):
2557+
request = tasks.tasklists().list()
25752558

2576-
with self.assertRaises(MutualTLSChannelError):
2577-
with mock.patch.dict(
2578-
"os.environ", {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}
2579-
):
2559+
def test_client_options_with_empty_universe(self):
2560+
fake_universe = "foo.com"
2561+
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2562+
discovery = read_datafile("tasks.json")
2563+
2564+
with self.assertRaises(universe.EmptyUniverseError):
25802565
tasks = build_from_document(
25812566
discovery,
2567+
credentials=credentials,
25822568
client_options=google.api_core.client_options.ClientOptions(
2583-
universe_domain=fake_universe
2569+
universe_domain=""
25842570
),
25852571
)
25862572

2587-
def test_client_options_universe_configured_with_api_override(self):
2588-
fake_universe = "foo.com"
2589-
fake_api_endpoint = "https://www.bar.com/"
2590-
credentials = mock.Mock(universe_domain=fake_universe)
2591-
discovery = read_datafile("tasks.json")
2573+
def test_client_options_universe_configured_with_mtls(self):
2574+
fake_universe = "foo.com"
2575+
discovery = read_datafile("tasks.json")
25922576

2593-
tasks = build_from_document(
2594-
discovery,
2595-
credentials=credentials,
2596-
client_options=google.api_core.client_options.ClientOptions(
2597-
api_endpoint=fake_api_endpoint, universe_domain=fake_universe
2598-
),
2599-
)
2577+
with self.assertRaises(MutualTLSChannelError):
2578+
with mock.patch.dict(
2579+
"os.environ", {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}
2580+
):
2581+
tasks = build_from_document(
2582+
discovery,
2583+
client_options=google.api_core.client_options.ClientOptions(
2584+
universe_domain=fake_universe
2585+
),
2586+
)
26002587

2601-
assert tasks._baseUrl == fake_api_endpoint
2588+
def test_client_options_universe_configured_with_api_override(self):
2589+
fake_universe = "foo.com"
2590+
fake_api_endpoint = "https://www.bar.com/"
2591+
credentials = mock.Mock(universe_domain=fake_universe)
2592+
discovery = read_datafile("tasks.json")
26022593

2603-
def test_universe_env_var_configured_empty(self):
2604-
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2605-
discovery = read_datafile("tasks.json")
2594+
tasks = build_from_document(
2595+
discovery,
2596+
credentials=credentials,
2597+
client_options=google.api_core.client_options.ClientOptions(
2598+
api_endpoint=fake_api_endpoint, universe_domain=fake_universe
2599+
),
2600+
)
2601+
2602+
assert tasks._baseUrl == fake_api_endpoint
2603+
2604+
def test_universe_env_var_configured_empty(self):
2605+
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2606+
discovery = read_datafile("tasks.json")
2607+
2608+
with self.assertRaises(universe.EmptyUniverseError):
2609+
with mock.patch.dict(
2610+
"os.environ", {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": ""}
2611+
):
2612+
tasks = build_from_document(
2613+
discovery,
2614+
credentials=credentials,
2615+
)
2616+
2617+
def test_universe_env_var_configured_with_mtls(self):
2618+
fake_universe = "foo.com"
2619+
discovery = read_datafile("tasks.json")
2620+
2621+
with self.assertRaises(MutualTLSChannelError):
2622+
with mock.patch.dict(
2623+
"os.environ",
2624+
{
2625+
"GOOGLE_API_USE_MTLS_ENDPOINT": "always",
2626+
"GOOGLE_CLOUD_UNIVERSE_DOMAIN": fake_universe,
2627+
},
2628+
):
2629+
tasks = build_from_document(discovery)
2630+
2631+
def test_universe_env_var_configured_with_api_override(self):
2632+
fake_universe = "foo.com"
2633+
fake_api_endpoint = "https://www.bar.com/"
2634+
credentials = mock.Mock(universe_domain=fake_universe)
2635+
discovery = read_datafile("tasks.json")
26062636

2607-
with self.assertRaises(universe.EmptyUniverseError):
26082637
with mock.patch.dict(
2609-
"os.environ", {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": ""}
2638+
"os.environ", {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": fake_universe}
26102639
):
26112640
tasks = build_from_document(
26122641
discovery,
26132642
credentials=credentials,
2643+
client_options=google.api_core.client_options.ClientOptions(
2644+
api_endpoint=fake_api_endpoint
2645+
),
26142646
)
26152647

2616-
def test_universe_env_var_configured_with_mtls(self):
2617-
fake_universe = "foo.com"
2618-
discovery = read_datafile("tasks.json")
2648+
assert tasks._baseUrl == fake_api_endpoint
2649+
2650+
def test_universe_env_var_configured_with_client_options_universe(self):
2651+
fake_universe = "foo.com"
2652+
another_fake_universe = "bar.com"
2653+
credentials = mock.Mock(universe_domain=fake_universe)
2654+
discovery = read_datafile("tasks.json")
26192655

2620-
with self.assertRaises(MutualTLSChannelError):
26212656
with mock.patch.dict(
2622-
"os.environ",
2623-
{
2624-
"GOOGLE_API_USE_MTLS_ENDPOINT": "always",
2625-
"GOOGLE_CLOUD_UNIVERSE_DOMAIN": fake_universe,
2626-
},
2657+
"os.environ", {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": another_fake_universe}
26272658
):
2628-
tasks = build_from_document(discovery)
2659+
tasks = build_from_document(
2660+
discovery,
2661+
credentials=credentials,
2662+
client_options=google.api_core.client_options.ClientOptions(
2663+
universe_domain=fake_universe
2664+
),
2665+
)
26292666

2630-
def test_universe_env_var_configured_with_api_override(self):
2667+
assert tasks._universe_domain == fake_universe
2668+
2669+
def test_client_options_universe_with_older_version_of_api_core(self):
26312670
fake_universe = "foo.com"
2632-
fake_api_endpoint = "https://www.bar.com/"
2633-
credentials = mock.Mock(universe_domain=fake_universe)
2671+
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2672+
credentials.universe_domain = fake_universe
26342673
discovery = read_datafile("tasks.json")
2635-
2636-
with mock.patch.dict(
2637-
"os.environ", {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": fake_universe}
2638-
):
2674+
with self.assertRaises(APICoreVersionError):
26392675
tasks = build_from_document(
26402676
discovery,
26412677
credentials=credentials,
26422678
client_options=google.api_core.client_options.ClientOptions(
2643-
api_endpoint=fake_api_endpoint
2679+
universe_domain=fake_universe
26442680
),
26452681
)
26462682

2647-
assert tasks._baseUrl == fake_api_endpoint
26482683

2649-
def test_universe_env_var_configured_with_client_options_universe(self):
2684+
def test_credentials_universe_with_older_version_of_api_core(self):
26502685
fake_universe = "foo.com"
2651-
another_fake_universe = "bar.com"
2652-
credentials = mock.Mock(universe_domain=fake_universe)
2686+
credentials = mock.Mock(spec=google.auth.credentials.Credentials)
2687+
credentials.universe_domain = fake_universe
26532688
discovery = read_datafile("tasks.json")
2654-
2655-
with mock.patch.dict(
2656-
"os.environ", {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": another_fake_universe}
2657-
):
2689+
with self.assertRaises(APICoreVersionError):
26582690
tasks = build_from_document(
26592691
discovery,
26602692
credentials=credentials,
2661-
client_options=google.api_core.client_options.ClientOptions(
2662-
universe_domain=fake_universe
2663-
),
26642693
)
2665-
2666-
assert tasks._universe_domain == fake_universe
2667-
2694+
26682695

26692696
if __name__ == "__main__":
26702697
unittest.main()

0 commit comments

Comments
 (0)