1616#
1717
1818from collections import OrderedDict
19+ from distutils import util
1920import os
2021import re
21- from typing import Callable , Dict , Sequence , Tuple , Type , Union
22+ from typing import Callable , Dict , Optional , Sequence , Tuple , Type , Union
2223import pkg_resources
2324
24- import google .api_core . client_options as ClientOptions # type: ignore
25+ from google .api_core import client_options as client_options_lib # type: ignore
2526from google .api_core import exceptions # type: ignore
2627from google .api_core import gapic_v1 # type: ignore
2728from google .api_core import retry as retries # type: ignore
2829from google .auth import credentials # type: ignore
2930from google .auth .transport import mtls # type: ignore
31+ from google .auth .transport .grpc import SslCredentials # type: ignore
3032from google .auth .exceptions import MutualTLSChannelError # type: ignore
3133from google .oauth2 import service_account # type: ignore
3234
@@ -130,6 +132,15 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
130132
131133 from_service_account_json = from_service_account_file
132134
135+ @property
136+ def transport (self ) -> ErrorGroupServiceTransport :
137+ """Return the transport used by the client instance.
138+
139+ Returns:
140+ ErrorGroupServiceTransport: The transport used by the client instance.
141+ """
142+ return self ._transport
143+
133144 @staticmethod
134145 def error_group_path (project : str , group : str ,) -> str :
135146 """Return a fully-qualified error_group string."""
@@ -141,12 +152,71 @@ def parse_error_group_path(path: str) -> Dict[str, str]:
141152 m = re .match (r"^projects/(?P<project>.+?)/groups/(?P<group>.+?)$" , path )
142153 return m .groupdict () if m else {}
143154
155+ @staticmethod
156+ def common_billing_account_path (billing_account : str ,) -> str :
157+ """Return a fully-qualified billing_account string."""
158+ return "billingAccounts/{billing_account}" .format (
159+ billing_account = billing_account ,
160+ )
161+
162+ @staticmethod
163+ def parse_common_billing_account_path (path : str ) -> Dict [str , str ]:
164+ """Parse a billing_account path into its component segments."""
165+ m = re .match (r"^billingAccounts/(?P<billing_account>.+?)$" , path )
166+ return m .groupdict () if m else {}
167+
168+ @staticmethod
169+ def common_folder_path (folder : str ,) -> str :
170+ """Return a fully-qualified folder string."""
171+ return "folders/{folder}" .format (folder = folder ,)
172+
173+ @staticmethod
174+ def parse_common_folder_path (path : str ) -> Dict [str , str ]:
175+ """Parse a folder path into its component segments."""
176+ m = re .match (r"^folders/(?P<folder>.+?)$" , path )
177+ return m .groupdict () if m else {}
178+
179+ @staticmethod
180+ def common_organization_path (organization : str ,) -> str :
181+ """Return a fully-qualified organization string."""
182+ return "organizations/{organization}" .format (organization = organization ,)
183+
184+ @staticmethod
185+ def parse_common_organization_path (path : str ) -> Dict [str , str ]:
186+ """Parse a organization path into its component segments."""
187+ m = re .match (r"^organizations/(?P<organization>.+?)$" , path )
188+ return m .groupdict () if m else {}
189+
190+ @staticmethod
191+ def common_project_path (project : str ,) -> str :
192+ """Return a fully-qualified project string."""
193+ return "projects/{project}" .format (project = project ,)
194+
195+ @staticmethod
196+ def parse_common_project_path (path : str ) -> Dict [str , str ]:
197+ """Parse a project path into its component segments."""
198+ m = re .match (r"^projects/(?P<project>.+?)$" , path )
199+ return m .groupdict () if m else {}
200+
201+ @staticmethod
202+ def common_location_path (project : str , location : str ,) -> str :
203+ """Return a fully-qualified location string."""
204+ return "projects/{project}/locations/{location}" .format (
205+ project = project , location = location ,
206+ )
207+
208+ @staticmethod
209+ def parse_common_location_path (path : str ) -> Dict [str , str ]:
210+ """Parse a location path into its component segments."""
211+ m = re .match (r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$" , path )
212+ return m .groupdict () if m else {}
213+
144214 def __init__ (
145215 self ,
146216 * ,
147- credentials : credentials .Credentials = None ,
148- transport : Union [str , ErrorGroupServiceTransport ] = None ,
149- client_options : ClientOptions = None ,
217+ credentials : Optional [ credentials .Credentials ] = None ,
218+ transport : Union [str , ErrorGroupServiceTransport , None ] = None ,
219+ client_options : Optional [ client_options_lib . ClientOptions ] = None ,
150220 client_info : gapic_v1 .client_info .ClientInfo = DEFAULT_CLIENT_INFO ,
151221 ) -> None :
152222 """Instantiate the error group service client.
@@ -160,53 +230,74 @@ def __init__(
160230 transport (Union[str, ~.ErrorGroupServiceTransport]): The
161231 transport to use. If set to None, a transport is chosen
162232 automatically.
163- client_options (ClientOptions): Custom options for the client. It
164- won't take effect if a ``transport`` instance is provided.
233+ client_options (client_options_lib. ClientOptions): Custom options for the
234+ client. It won't take effect if a ``transport`` instance is provided.
165235 (1) The ``api_endpoint`` property can be used to override the
166- default endpoint provided by the client. GOOGLE_API_USE_MTLS
236+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
167237 environment variable can also be used to override the endpoint:
168238 "always" (always use the default mTLS endpoint), "never" (always
169- use the default regular endpoint, this is the default value for
170- the environment variable) and "auto" (auto switch to the default
171- mTLS endpoint if client SSL credentials is present). However,
172- the ``api_endpoint`` property takes precedence if provided.
173- (2) The ``client_cert_source`` property is used to provide client
174- SSL credentials for mutual TLS transport. If not provided, the
175- default SSL credentials will be used if present.
176- client_info (google.api_core.gapic_v1.client_info.ClientInfo):
177- The client info used to send a user-agent string along with
178- API requests. If ``None``, then default info will be used.
179- Generally, you only need to set this if you're developing
239+ use the default regular endpoint) and "auto" (auto switch to the
240+ default mTLS endpoint if client certificate is present, this is
241+ the default value). However, the ``api_endpoint`` property takes
242+ precedence if provided.
243+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
244+ is "true", then the ``client_cert_source`` property can be used
245+ to provide client certificate for mutual TLS transport. If
246+ not provided, the default SSL client certificate will be used if
247+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
248+ set, no client certificate will be used.
249+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
250+ The client info used to send a user-agent string along with
251+ API requests. If ``None``, then default info will be used.
252+ Generally, you only need to set this if you're developing
180253 your own client library.
181254
182255 Raises:
183256 google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
184257 creation failed for any reason.
185258 """
186259 if isinstance (client_options , dict ):
187- client_options = ClientOptions .from_dict (client_options )
260+ client_options = client_options_lib .from_dict (client_options )
188261 if client_options is None :
189- client_options = ClientOptions .ClientOptions ()
262+ client_options = client_options_lib .ClientOptions ()
263+
264+ # Create SSL credentials for mutual TLS if needed.
265+ use_client_cert = bool (
266+ util .strtobool (os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ))
267+ )
190268
191- if client_options .api_endpoint is None :
192- use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS" , "never" )
269+ ssl_credentials = None
270+ is_mtls = False
271+ if use_client_cert :
272+ if client_options .client_cert_source :
273+ import grpc # type: ignore
274+
275+ cert , key = client_options .client_cert_source ()
276+ ssl_credentials = grpc .ssl_channel_credentials (
277+ certificate_chain = cert , private_key = key
278+ )
279+ is_mtls = True
280+ else :
281+ creds = SslCredentials ()
282+ is_mtls = creds .is_mtls
283+ ssl_credentials = creds .ssl_credentials if is_mtls else None
284+
285+ # Figure out which api endpoint to use.
286+ if client_options .api_endpoint is not None :
287+ api_endpoint = client_options .api_endpoint
288+ else :
289+ use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
193290 if use_mtls_env == "never" :
194- client_options . api_endpoint = self .DEFAULT_ENDPOINT
291+ api_endpoint = self .DEFAULT_ENDPOINT
195292 elif use_mtls_env == "always" :
196- client_options . api_endpoint = self .DEFAULT_MTLS_ENDPOINT
293+ api_endpoint = self .DEFAULT_MTLS_ENDPOINT
197294 elif use_mtls_env == "auto" :
198- has_client_cert_source = (
199- client_options .client_cert_source is not None
200- or mtls .has_default_client_cert_source ()
201- )
202- client_options .api_endpoint = (
203- self .DEFAULT_MTLS_ENDPOINT
204- if has_client_cert_source
205- else self .DEFAULT_ENDPOINT
295+ api_endpoint = (
296+ self .DEFAULT_MTLS_ENDPOINT if is_mtls else self .DEFAULT_ENDPOINT
206297 )
207298 else :
208299 raise MutualTLSChannelError (
209- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
300+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
210301 )
211302
212303 # Save or instantiate the transport.
@@ -230,10 +321,9 @@ def __init__(
230321 self ._transport = Transport (
231322 credentials = credentials ,
232323 credentials_file = client_options .credentials_file ,
233- host = client_options . api_endpoint ,
324+ host = api_endpoint ,
234325 scopes = client_options .scopes ,
235- api_mtls_endpoint = client_options .api_endpoint ,
236- client_cert_source = client_options .client_cert_source ,
326+ ssl_channel_credentials = ssl_credentials ,
237327 quota_project_id = client_options .quota_project_id ,
238328 client_info = client_info ,
239329 )
0 commit comments