@@ -22,9 +22,9 @@ from google.oauth2 import service_account # type: ignore
2222{% endfilter %}
2323from .transports.base import {{ service.name }}Transport
2424from .transports.grpc_asyncio import {{ service.name }}GrpcAsyncIOTransport
25- from .base_client import {{ service.name }}BaseClient, {{ service.name }}BaseClientMeta
2625
27- class {{ service.async_client_name }}Meta({{ service.name }}BaseClientMeta):
26+
27+ class {{ service.async_client_name }}Meta(type):
2828 """Metaclass for the {{ service.name }} client.
2929
3030 This provides class-level methods for building and retrieving
@@ -55,13 +55,149 @@ class {{ service.async_client_name }}Meta({{ service.name }}BaseClientMeta):
5555 return next(iter(cls._transport_registry.values()))
5656
5757
58- class {{ service.async_client_name }}({{ service.name }}BaseClient, metaclass={{ service.async_client_name }}Meta):
58+ class {{ service.async_client_name }}(metaclass={{ service.async_client_name }}Meta):
5959 """{{ service.meta.doc|rst(width=72, indent=4) }}"""
6060
61+ @staticmethod
62+ def _get_default_mtls_endpoint(api_endpoint):
63+ """Convert api endpoint to mTLS endpoint.
64+ Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
65+ "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
66+ Args:
67+ api_endpoint (Optional[str]): the api endpoint to convert.
68+ Returns:
69+ str: converted mTLS api endpoint.
70+ """
71+ if not api_endpoint:
72+ return api_endpoint
73+
74+ mtls_endpoint_re = re.compile(
75+ r"(?P<name >[^.]+)(?P<mtls >\.mtls)?(?P<sandbox >\.sandbox)?(?P<googledomain >\.googleapis\.com)?"
76+ )
77+
78+ m = mtls_endpoint_re.match(api_endpoint)
79+ name, mtls, sandbox, googledomain = m.groups()
80+ if mtls or not googledomain:
81+ return api_endpoint
82+
83+ if sandbox:
84+ return api_endpoint.replace(
85+ "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
86+ )
87+
88+ return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
89+
90+ DEFAULT_ENDPOINT = {% if service .host %} '{{ service.host }}'{% else %} None{% endif %}
91+ DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
92+ DEFAULT_ENDPOINT
93+ )
94+ DEFAULT_MTLS_TRANSPORT = {{ service.grpc_asyncio_transport_name }}
95+
6196 @classmethod
62- def _default_mtls_transport(cls) -> str:
63- """Returns the default MTLS transport name."""
64- return "grpc_asyncio"
97+ def from_service_account_file(cls, filename: str, *args, **kwargs):
98+ """Creates an instance of this client using the provided credentials
99+ file.
100+
101+ Args:
102+ filename (str): The path to the service account private key json
103+ file.
104+ args: Additional arguments to pass to the constructor.
105+ kwargs: Additional arguments to pass to the constructor.
106+
107+ Returns:
108+ {@api.name}: The constructed client.
109+ """
110+ credentials = service_account.Credentials.from_service_account_file(
111+ filename)
112+ kwargs['credentials'] = credentials
113+ return cls(*args, **kwargs)
114+
115+ from_service_account_json = from_service_account_file
116+
117+
118+ {% for message in service .resource_messages -%}
119+ @staticmethod
120+ def {{ message.resource_type|snake_case }}_path({% for arg in message .resource_path_args %} {{ arg }}: str,{% endfor %} ) -> str:
121+ """Return a fully-qualified {{ message.resource_type|snake_case }} string."""
122+ return "{{ message.resource_path }}".format({% for arg in message .resource_path_args %} {{ arg }}={{ arg }}, {% endfor %} )
123+
124+ {% endfor %}
125+
126+ def __init__(self, *,
127+ credentials: credentials.Credentials = None,
128+ transport: Union[str, {{ service.name }}Transport] = None,
129+ client_options: ClientOptions = None,
130+ ) -> None:
131+ """Instantiate the {{ (service.client_name|snake_case).replace('_', ' ') }}.
132+
133+ Args:
134+ credentials (Optional[google.auth.credentials.Credentials]): The
135+ authorization credentials to attach to requests. These
136+ credentials identify the application to the service; if none
137+ are specified, the client will attempt to ascertain the
138+ credentials from the environment.
139+ transport (Union[str, ~.{{ service.name }}Transport]): The
140+ transport to use. If set to None, a transport is chosen
141+ automatically.
142+ client_options (ClientOptions): Custom options for the client.
143+ (1) The ``api_endpoint`` property can be used to override the
144+ default endpoint provided by the client.
145+ (2) If ``transport`` argument is None, ``client_options`` can be
146+ used to create a mutual TLS transport. If ``client_cert_source``
147+ is provided, mutual TLS transport will be created with the given
148+ ``api_endpoint`` or the default mTLS endpoint, and the client
149+ SSL credentials obtained from ``client_cert_source``.
150+
151+ Raises:
152+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
153+ creation failed for any reason.
154+ """
155+ if isinstance(client_options, dict):
156+ client_options = ClientOptions.from_dict(client_options)
157+
158+ # Save or instantiate the transport.
159+ # Ordinarily, we provide the transport, but allowing a custom transport
160+ # instance provides an extensibility point for unusual situations.
161+ if isinstance(transport, {{ service.name }}Transport):
162+ # transport is a {{ service.name }}Transport instance.
163+ if credentials:
164+ raise ValueError('When providing a transport instance, '
165+ 'provide its credentials directly.')
166+ self._transport = transport
167+ elif client_options is None or (
168+ client_options.api_endpoint == None
169+ and client_options.client_cert_source is None
170+ ):
171+ # Don't trigger mTLS if we get an empty ClientOptions.
172+ Transport = type(self).get_transport_class(transport)
173+ self._transport = Transport(
174+ credentials=credentials, host=self.DEFAULT_ENDPOINT
175+ )
176+ else:
177+ # We have a non-empty ClientOptions. If client_cert_source is
178+ # provided, trigger mTLS with user provided endpoint or the default
179+ # mTLS endpoint.
180+ if client_options.client_cert_source:
181+ api_mtls_endpoint = (
182+ client_options.api_endpoint
183+ if client_options.api_endpoint
184+ else self.DEFAULT_MTLS_ENDPOINT
185+ )
186+ else:
187+ api_mtls_endpoint = None
188+
189+ api_endpoint = (
190+ client_options.api_endpoint
191+ if client_options.api_endpoint
192+ else self.DEFAULT_ENDPOINT
193+ )
194+
195+ self._transport = self.DEFAULT_MTLS_TRANSPORT(
196+ credentials=credentials,
197+ host=api_endpoint,
198+ api_mtls_endpoint=api_mtls_endpoint,
199+ client_cert_source=client_options.client_cert_source,
200+ )
65201
66202 {% for method in service .methods .values () -%}
67203 {% if not method .server_streaming %} async {% endif -%} def {{ method.name|snake_case }}(self,
@@ -176,7 +312,7 @@ class {{ service.async_client_name }}({{ service.name }}BaseClient, metaclass={{
176312 ),
177313 {% - endif %}
178314 default_timeout={{ method.timeout }},
179- client_info=self. _client_info,
315+ client_info=_client_info,
180316 )
181317 {% - if method .field_headers %}
182318
@@ -231,6 +367,16 @@ class {{ service.async_client_name }}({{ service.name }}BaseClient, metaclass={{
231367 {% endfor %}
232368
233369
370+ try:
371+ _client_info = gapic_v1.client_info.ClientInfo(
372+ gapic_version=pkg_resources.get_distribution(
373+ '{{ api.naming.warehouse_package_name }}',
374+ ).version,
375+ )
376+ except pkg_resources.DistributionNotFound:
377+ _client_info = gapic_v1.client_info.ClientInfo()
378+
379+
234380__all__ = (
235381 '{{ service.async_client_name }}',
236382)
0 commit comments