@@ -239,6 +239,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
239239 m  =  re .match (r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$" , path )
240240 return  m .groupdict () if  m  else  {}
241241
242+  @classmethod  
243+  def  get_mtls_endpoint_and_cert_source (
244+  cls , client_options : Optional [client_options_lib .ClientOptions ] =  None 
245+  ):
246+  """Return the API endpoint and client cert source for mutual TLS. 
247+ 
248+  The client cert source is determined in the following order: 
249+  (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the 
250+  client cert source is None. 
251+  (2) if `client_options.client_cert_source` is provided, use the provided one; if the 
252+  default client cert source exists, use the default one; otherwise the client cert 
253+  source is None. 
254+ 
255+  The API endpoint is determined in the following order: 
256+  (1) if `client_options.api_endpoint` if provided, use the provided one. 
257+  (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the 
258+  default mTLS endpoint; if the environment variabel is "never", use the default API 
259+  endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise 
260+  use the default API endpoint. 
261+ 
262+  More details can be found at https://google.aip.dev/auth/4114. 
263+ 
264+  Args: 
265+  client_options (google.api_core.client_options.ClientOptions): Custom options for the 
266+  client. Only the `api_endpoint` and `client_cert_source` properties may be used 
267+  in this method. 
268+ 
269+  Returns: 
270+  Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the 
271+  client cert source to use. 
272+ 
273+  Raises: 
274+  google.auth.exceptions.MutualTLSChannelError: If any errors happen. 
275+  """ 
276+  if  client_options  is  None :
277+  client_options  =  client_options_lib .ClientOptions ()
278+  use_client_cert  =  os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" )
279+  use_mtls_endpoint  =  os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
280+  if  use_client_cert  not  in   ("true" , "false" ):
281+  raise  ValueError (
282+  "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" 
283+  )
284+  if  use_mtls_endpoint  not  in   ("auto" , "never" , "always" ):
285+  raise  MutualTLSChannelError (
286+  "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" 
287+  )
288+ 
289+  # Figure out the client cert source to use. 
290+  client_cert_source  =  None 
291+  if  use_client_cert  ==  "true" :
292+  if  client_options .client_cert_source :
293+  client_cert_source  =  client_options .client_cert_source 
294+  elif  mtls .has_default_client_cert_source ():
295+  client_cert_source  =  mtls .default_client_cert_source ()
296+ 
297+  # Figure out which api endpoint to use. 
298+  if  client_options .api_endpoint  is  not   None :
299+  api_endpoint  =  client_options .api_endpoint 
300+  elif  use_mtls_endpoint  ==  "always"  or  (
301+  use_mtls_endpoint  ==  "auto"  and  client_cert_source 
302+  ):
303+  api_endpoint  =  cls .DEFAULT_MTLS_ENDPOINT 
304+  else :
305+  api_endpoint  =  cls .DEFAULT_ENDPOINT 
306+ 
307+  return  api_endpoint , client_cert_source 
308+ 
242309 def  __init__ (
243310 self ,
244311 * ,
@@ -289,57 +356,22 @@ def __init__(
289356 if  client_options  is  None :
290357 client_options  =  client_options_lib .ClientOptions ()
291358
292-  # Create SSL credentials for mutual TLS if needed. 
293-  if  os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) not  in   (
294-  "true" ,
295-  "false" ,
296-  ):
297-  raise  ValueError (
298-  "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" 
299-  )
300-  use_client_cert  =  (
301-  os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) ==  "true" 
359+  api_endpoint , client_cert_source_func  =  self .get_mtls_endpoint_and_cert_source (
360+  client_options 
302361 )
303362
304-  client_cert_source_func  =  None 
305-  is_mtls  =  False 
306-  if  use_client_cert :
307-  if  client_options .client_cert_source :
308-  is_mtls  =  True 
309-  client_cert_source_func  =  client_options .client_cert_source 
310-  else :
311-  is_mtls  =  mtls .has_default_client_cert_source ()
312-  if  is_mtls :
313-  client_cert_source_func  =  mtls .default_client_cert_source ()
314-  else :
315-  client_cert_source_func  =  None 
316- 
317-  # Figure out which api endpoint to use. 
318-  if  client_options .api_endpoint  is  not   None :
319-  api_endpoint  =  client_options .api_endpoint 
320-  else :
321-  use_mtls_env  =  os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
322-  if  use_mtls_env  ==  "never" :
323-  api_endpoint  =  self .DEFAULT_ENDPOINT 
324-  elif  use_mtls_env  ==  "always" :
325-  api_endpoint  =  self .DEFAULT_MTLS_ENDPOINT 
326-  elif  use_mtls_env  ==  "auto" :
327-  if  is_mtls :
328-  api_endpoint  =  self .DEFAULT_MTLS_ENDPOINT 
329-  else :
330-  api_endpoint  =  self .DEFAULT_ENDPOINT 
331-  else :
332-  raise  MutualTLSChannelError (
333-  "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " 
334-  "values: never, auto, always" 
335-  )
363+  api_key_value  =  getattr (client_options , "api_key" , None )
364+  if  api_key_value  and  credentials :
365+  raise  ValueError (
366+  "client_options.api_key and credentials are mutually exclusive" 
367+  )
336368
337369 # Save or instantiate the transport. 
338370 # Ordinarily, we provide the transport, but allowing a custom transport 
339371 # instance provides an extensibility point for unusual situations. 
340372 if  isinstance (transport , PublisherTransport ):
341373 # transport is a PublisherTransport instance. 
342-  if  credentials  or  client_options .credentials_file :
374+  if  credentials  or  client_options .credentials_file   or   api_key_value :
343375 raise  ValueError (
344376 "When providing a transport instance, " 
345377 "provide its credentials directly." 
@@ -351,6 +383,15 @@ def __init__(
351383 )
352384 self ._transport  =  transport 
353385 else :
386+  import  google .auth ._default  # type: ignore 
387+ 
388+  if  api_key_value  and  hasattr (
389+  google .auth ._default , "get_api_key_credentials" 
390+  ):
391+  credentials  =  google .auth ._default .get_api_key_credentials (
392+  api_key_value 
393+  )
394+ 
354395 Transport  =  type (self ).get_transport_class (transport )
355396 self ._transport  =  Transport (
356397 credentials = credentials ,
0 commit comments