Skip to content

Commit 48f392a

Browse files
committed
refactor(generator): use routing helper from api_core in templates and goldens
1 parent 0fe63b5 commit 48f392a

26 files changed

Lines changed: 247 additions & 1414 deletions

File tree

packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/services/%service/client.py.j2

Lines changed: 19 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ from google.api_core import exceptions as core_exceptions
3030
from google.api_core import extended_operation
3131
{% endif %}
3232
from google.api_core import gapic_v1
33+
from google.api_core.gapic_v1 import routing
3334
from google.api_core import retry as retries
3435
from google.auth import credentials as ga_credentials # type: ignore
3536
from google.auth.transport import mtls # type: ignore
@@ -145,37 +146,8 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
145146

146147
@staticmethod
147148
def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]:
148-
"""Converts api endpoint to mTLS endpoint.
149-
150-
Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
151-
"*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
152-
Args:
153-
api_endpoint (Optional[str]): the api endpoint to convert.
154-
Returns:
155-
Optional[str]: converted mTLS api endpoint.
156-
"""
157-
if not api_endpoint:
158-
return api_endpoint
159-
160-
mtls_endpoint_re = re.compile(
161-
r"(?P<name>[^.]+)(?P<mtls>\.mtls)?(?P<sandbox>\.sandbox)?(?P<googledomain>\.googleapis\.com)?"
162-
)
163-
164-
m = mtls_endpoint_re.match(api_endpoint)
165-
if m is None:
166-
# Could not parse api_endpoint; return as-is.
167-
return api_endpoint
168-
169-
name, mtls, sandbox, googledomain = m.groups()
170-
if mtls or not googledomain:
171-
return api_endpoint
172-
173-
if sandbox:
174-
return api_endpoint.replace(
175-
"sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
176-
)
177-
178-
return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
149+
"""Converts api endpoint to mTLS endpoint."""
150+
return routing.get_default_mtls_endpoint(api_endpoint)
179151

180152
# Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
181153
DEFAULT_ENDPOINT = {% if service.host %}"{{ service.host }}"{% else %}None{% endif %}
@@ -393,52 +365,25 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
393365

394366
@staticmethod
395367
def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint) -> str:
396-
"""Return the API endpoint used by the client.
397-
398-
Args:
399-
api_override (str): The API endpoint override. If specified, this is always
400-
the return value of this function and the other arguments are not used.
401-
client_cert_source (bytes): The client certificate source used by the client.
402-
universe_domain (str): The universe domain used by the client.
403-
use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters.
404-
Possible values are "always", "auto", or "never".
405-
406-
Returns:
407-
str: The API endpoint to be used by the client.
408-
"""
409-
if api_override is not None:
410-
api_endpoint = api_override
411-
elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source):
412-
_default_universe = {{ service.client_name }}._DEFAULT_UNIVERSE
413-
if universe_domain != _default_universe:
414-
raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.")
415-
api_endpoint = {{ service.client_name }}.DEFAULT_MTLS_ENDPOINT
416-
else:
417-
api_endpoint = {{ service.client_name }}._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain)
418-
return api_endpoint
368+
"""Return the API endpoint used by the client."""
369+
return routing.get_api_endpoint(
370+
api_override,
371+
client_cert_source,
372+
universe_domain,
373+
use_mtls_endpoint,
374+
{{ service.client_name }}._DEFAULT_UNIVERSE,
375+
{{ service.client_name }}.DEFAULT_MTLS_ENDPOINT,
376+
{{ service.client_name }}._DEFAULT_ENDPOINT_TEMPLATE,
377+
)
419378

420379
@staticmethod
421380
def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str:
422-
"""Return the universe domain used by the client.
423-
424-
Args:
425-
client_universe_domain (Optional[str]): The universe domain configured via the client options.
426-
universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable.
427-
428-
Returns:
429-
str: The universe domain to be used by the client.
430-
431-
Raises:
432-
ValueError: If the universe domain is an empty string.
433-
"""
434-
universe_domain = {{ service.client_name }}._DEFAULT_UNIVERSE
435-
if client_universe_domain is not None:
436-
universe_domain = client_universe_domain
437-
elif universe_domain_env is not None:
438-
universe_domain = universe_domain_env
439-
if len(universe_domain.strip()) == 0:
440-
raise ValueError("Universe Domain cannot be an empty string.")
441-
return universe_domain
381+
"""Return the universe domain used by the client."""
382+
return routing.get_universe_domain(
383+
client_universe_domain,
384+
universe_domain_env,
385+
{{ service.client_name }}._DEFAULT_UNIVERSE,
386+
)
442387

443388
def _validate_universe_domain(self):
444389
"""Validates client's and credentials' universe domains are consistent.

packages/gapic-generator/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -313,29 +313,7 @@ def test__get_client_cert_source():
313313
assert {{ service.client_name }}._get_client_cert_source(None, True) is mock_default_cert_source
314314
assert {{ service.client_name }}._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source
315315

316-
@mock.patch.object({{ service.client_name }}, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template({{ service.client_name }}))
317-
{% if 'grpc' in opts.transport %}
318-
@mock.patch.object({{ service.async_client_name }}, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template({{ service.async_client_name }}))
319-
{% endif %}
320-
def test__get_api_endpoint():
321-
api_override = "foo.com"
322-
mock_client_cert_source = mock.Mock()
323-
default_universe = {{ service.client_name }}._DEFAULT_UNIVERSE
324-
default_endpoint = {{ service.client_name }}._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe)
325-
mock_universe = "bar.com"
326-
mock_endpoint = {{ service.client_name }}._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe)
327-
328-
assert {{ service.client_name }}._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override
329-
assert {{ service.client_name }}._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == {{ service.client_name }}.DEFAULT_MTLS_ENDPOINT
330-
assert {{ service.client_name }}._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint
331-
assert {{ service.client_name }}._get_api_endpoint(None, None, default_universe, "always") == {{ service.client_name }}.DEFAULT_MTLS_ENDPOINT
332-
assert {{ service.client_name }}._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == {{ service.client_name }}.DEFAULT_MTLS_ENDPOINT
333-
assert {{ service.client_name }}._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint
334-
assert {{ service.client_name }}._get_api_endpoint(None, None, default_universe, "never") == default_endpoint
335316

336-
with pytest.raises(MutualTLSChannelError) as excinfo:
337-
{{ service.client_name }}._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto")
338-
assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com."
339317

340318
{% if service.version %}
341319
{% for method in service.methods.values() %}{% with method_name = method.name|snake_case %}
@@ -384,17 +362,7 @@ def test_{{ method_name }}_api_version_header(transport_name):
384362
{% endfor %}
385363
{% endif %}{# service.version #}
386364

387-
def test__get_universe_domain():
388-
client_universe_domain = "foo.com"
389-
universe_domain_env = "bar.com"
390-
391-
assert {{ service.client_name }}._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain
392-
assert {{ service.client_name }}._get_universe_domain(None, universe_domain_env) == universe_domain_env
393-
assert {{ service.client_name }}._get_universe_domain(None, None) == {{ service.client_name }}._DEFAULT_UNIVERSE
394365

395-
with pytest.raises(ValueError) as excinfo:
396-
{{ service.client_name }}._get_universe_domain("", None)
397-
assert str(excinfo.value) == "Universe Domain cannot be an empty string."
398366

399367
@pytest.mark.parametrize("error_code,cred_info_json,show_cred_info", [
400368
(401, CRED_INFO_JSON, True),

packages/gapic-generator/tests/integration/goldens/asset/google/cloud/asset_v1/services/asset_service/client.py

Lines changed: 19 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from google.api_core import client_options as client_options_lib
2828
from google.api_core import exceptions as core_exceptions
2929
from google.api_core import gapic_v1
30+
from google.api_core.gapic_v1 import routing
3031
from google.api_core import retry as retries
3132
from google.auth import credentials as ga_credentials # type: ignore
3233
from google.auth.transport import mtls # type: ignore
@@ -102,37 +103,8 @@ class AssetServiceClient(metaclass=AssetServiceClientMeta):
102103

103104
@staticmethod
104105
def _get_default_mtls_endpoint(api_endpoint) -> Optional[str]:
105-
"""Converts api endpoint to mTLS endpoint.
106-
107-
Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
108-
"*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
109-
Args:
110-
api_endpoint (Optional[str]): the api endpoint to convert.
111-
Returns:
112-
Optional[str]: converted mTLS api endpoint.
113-
"""
114-
if not api_endpoint:
115-
return api_endpoint
116-
117-
mtls_endpoint_re = re.compile(
118-
r"(?P<name>[^.]+)(?P<mtls>\.mtls)?(?P<sandbox>\.sandbox)?(?P<googledomain>\.googleapis\.com)?"
119-
)
120-
121-
m = mtls_endpoint_re.match(api_endpoint)
122-
if m is None:
123-
# Could not parse api_endpoint; return as-is.
124-
return api_endpoint
125-
126-
name, mtls, sandbox, googledomain = m.groups()
127-
if mtls or not googledomain:
128-
return api_endpoint
129-
130-
if sandbox:
131-
return api_endpoint.replace(
132-
"sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
133-
)
134-
135-
return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
106+
"""Converts api endpoint to mTLS endpoint."""
107+
return routing.get_default_mtls_endpoint(api_endpoint)
136108

137109
# Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
138110
DEFAULT_ENDPOINT = "cloudasset.googleapis.com"
@@ -451,52 +423,25 @@ def _get_client_cert_source(provided_cert_source, use_cert_flag):
451423

452424
@staticmethod
453425
def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint) -> str:
454-
"""Return the API endpoint used by the client.
455-
456-
Args:
457-
api_override (str): The API endpoint override. If specified, this is always
458-
the return value of this function and the other arguments are not used.
459-
client_cert_source (bytes): The client certificate source used by the client.
460-
universe_domain (str): The universe domain used by the client.
461-
use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters.
462-
Possible values are "always", "auto", or "never".
463-
464-
Returns:
465-
str: The API endpoint to be used by the client.
466-
"""
467-
if api_override is not None:
468-
api_endpoint = api_override
469-
elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source):
470-
_default_universe = AssetServiceClient._DEFAULT_UNIVERSE
471-
if universe_domain != _default_universe:
472-
raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.")
473-
api_endpoint = AssetServiceClient.DEFAULT_MTLS_ENDPOINT
474-
else:
475-
api_endpoint = AssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain)
476-
return api_endpoint
426+
"""Return the API endpoint used by the client."""
427+
return routing.get_api_endpoint(
428+
api_override,
429+
client_cert_source,
430+
universe_domain,
431+
use_mtls_endpoint,
432+
AssetServiceClient._DEFAULT_UNIVERSE,
433+
AssetServiceClient.DEFAULT_MTLS_ENDPOINT,
434+
AssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE,
435+
)
477436

478437
@staticmethod
479438
def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str:
480-
"""Return the universe domain used by the client.
481-
482-
Args:
483-
client_universe_domain (Optional[str]): The universe domain configured via the client options.
484-
universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable.
485-
486-
Returns:
487-
str: The universe domain to be used by the client.
488-
489-
Raises:
490-
ValueError: If the universe domain is an empty string.
491-
"""
492-
universe_domain = AssetServiceClient._DEFAULT_UNIVERSE
493-
if client_universe_domain is not None:
494-
universe_domain = client_universe_domain
495-
elif universe_domain_env is not None:
496-
universe_domain = universe_domain_env
497-
if len(universe_domain.strip()) == 0:
498-
raise ValueError("Universe Domain cannot be an empty string.")
499-
return universe_domain
439+
"""Return the universe domain used by the client."""
440+
return routing.get_universe_domain(
441+
client_universe_domain,
442+
universe_domain_env,
443+
AssetServiceClient._DEFAULT_UNIVERSE,
444+
)
500445

501446
def _validate_universe_domain(self):
502447
"""Validates client's and credentials' universe domains are consistent.

packages/gapic-generator/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -278,41 +278,6 @@ def test__get_client_cert_source():
278278
assert AssetServiceClient._get_client_cert_source(None, True) is mock_default_cert_source
279279
assert AssetServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source
280280

281-
@mock.patch.object(AssetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(AssetServiceClient))
282-
@mock.patch.object(AssetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(AssetServiceAsyncClient))
283-
def test__get_api_endpoint():
284-
api_override = "foo.com"
285-
mock_client_cert_source = mock.Mock()
286-
default_universe = AssetServiceClient._DEFAULT_UNIVERSE
287-
default_endpoint = AssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe)
288-
mock_universe = "bar.com"
289-
mock_endpoint = AssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe)
290-
291-
assert AssetServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override
292-
assert AssetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == AssetServiceClient.DEFAULT_MTLS_ENDPOINT
293-
assert AssetServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint
294-
assert AssetServiceClient._get_api_endpoint(None, None, default_universe, "always") == AssetServiceClient.DEFAULT_MTLS_ENDPOINT
295-
assert AssetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == AssetServiceClient.DEFAULT_MTLS_ENDPOINT
296-
assert AssetServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint
297-
assert AssetServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint
298-
299-
with pytest.raises(MutualTLSChannelError) as excinfo:
300-
AssetServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto")
301-
assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com."
302-
303-
304-
def test__get_universe_domain():
305-
client_universe_domain = "foo.com"
306-
universe_domain_env = "bar.com"
307-
308-
assert AssetServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain
309-
assert AssetServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env
310-
assert AssetServiceClient._get_universe_domain(None, None) == AssetServiceClient._DEFAULT_UNIVERSE
311-
312-
with pytest.raises(ValueError) as excinfo:
313-
AssetServiceClient._get_universe_domain("", None)
314-
assert str(excinfo.value) == "Universe Domain cannot be an empty string."
315-
316281
@pytest.mark.parametrize("error_code,cred_info_json,show_cred_info", [
317282
(401, CRED_INFO_JSON, True),
318283
(403, CRED_INFO_JSON, True),

0 commit comments

Comments
 (0)