@@ -364,6 +364,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
364
364
m = re .match (r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$" , path )
365
365
return m .groupdict () if m else {}
366
366
367
+ @classmethod
368
+ def get_mtls_endpoint_and_cert_source (
369
+ cls , client_options : Optional [client_options_lib .ClientOptions ] = None
370
+ ):
371
+ """Return the API endpoint and client cert source for mutual TLS.
372
+
373
+ The client cert source is determined in the following order:
374
+ (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
375
+ client cert source is None.
376
+ (2) if `client_options.client_cert_source` is provided, use the provided one; if the
377
+ default client cert source exists, use the default one; otherwise the client cert
378
+ source is None.
379
+
380
+ The API endpoint is determined in the following order:
381
+ (1) if `client_options.api_endpoint` if provided, use the provided one.
382
+ (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
383
+ default mTLS endpoint; if the environment variabel is "never", use the default API
384
+ endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
385
+ use the default API endpoint.
386
+
387
+ More details can be found at https://google.aip.dev/auth/4114.
388
+
389
+ Args:
390
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
391
+ client. Only the `api_endpoint` and `client_cert_source` properties may be used
392
+ in this method.
393
+
394
+ Returns:
395
+ Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the
396
+ client cert source to use.
397
+
398
+ Raises:
399
+ google.auth.exceptions.MutualTLSChannelError: If any errors happen.
400
+ """
401
+ if client_options is None :
402
+ client_options = client_options_lib .ClientOptions ()
403
+ use_client_cert = os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" )
404
+ use_mtls_endpoint = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
405
+ if use_client_cert not in ("true" , "false" ):
406
+ raise ValueError (
407
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
408
+ )
409
+ if use_mtls_endpoint not in ("auto" , "never" , "always" ):
410
+ raise MutualTLSChannelError (
411
+ "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
412
+ )
413
+
414
+ # Figure out the client cert source to use.
415
+ client_cert_source = None
416
+ if use_client_cert == "true" :
417
+ if client_options .client_cert_source :
418
+ client_cert_source = client_options .client_cert_source
419
+ elif mtls .has_default_client_cert_source ():
420
+ client_cert_source = mtls .default_client_cert_source ()
421
+
422
+ # Figure out which api endpoint to use.
423
+ if client_options .api_endpoint is not None :
424
+ api_endpoint = client_options .api_endpoint
425
+ elif use_mtls_endpoint == "always" or (
426
+ use_mtls_endpoint == "auto" and client_cert_source
427
+ ):
428
+ api_endpoint = cls .DEFAULT_MTLS_ENDPOINT
429
+ else :
430
+ api_endpoint = cls .DEFAULT_ENDPOINT
431
+
432
+ return api_endpoint , client_cert_source
433
+
367
434
def __init__ (
368
435
self ,
369
436
* ,
@@ -414,57 +481,22 @@ def __init__(
414
481
if client_options is None :
415
482
client_options = client_options_lib .ClientOptions ()
416
483
417
- # Create SSL credentials for mutual TLS if needed.
418
- if os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) not in (
419
- "true" ,
420
- "false" ,
421
- ):
422
- raise ValueError (
423
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
424
- )
425
- use_client_cert = (
426
- os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) == "true"
484
+ api_endpoint , client_cert_source_func = self .get_mtls_endpoint_and_cert_source (
485
+ client_options
427
486
)
428
487
429
- client_cert_source_func = None
430
- is_mtls = False
431
- if use_client_cert :
432
- if client_options .client_cert_source :
433
- is_mtls = True
434
- client_cert_source_func = client_options .client_cert_source
435
- else :
436
- is_mtls = mtls .has_default_client_cert_source ()
437
- if is_mtls :
438
- client_cert_source_func = mtls .default_client_cert_source ()
439
- else :
440
- client_cert_source_func = None
441
-
442
- # Figure out which api endpoint to use.
443
- if client_options .api_endpoint is not None :
444
- api_endpoint = client_options .api_endpoint
445
- else :
446
- use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
447
- if use_mtls_env == "never" :
448
- api_endpoint = self .DEFAULT_ENDPOINT
449
- elif use_mtls_env == "always" :
450
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
451
- elif use_mtls_env == "auto" :
452
- if is_mtls :
453
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
454
- else :
455
- api_endpoint = self .DEFAULT_ENDPOINT
456
- else :
457
- raise MutualTLSChannelError (
458
- "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted "
459
- "values: never, auto, always"
460
- )
488
+ api_key_value = getattr (client_options , "api_key" , None )
489
+ if api_key_value and credentials :
490
+ raise ValueError (
491
+ "client_options.api_key and credentials are mutually exclusive"
492
+ )
461
493
462
494
# Save or instantiate the transport.
463
495
# Ordinarily, we provide the transport, but allowing a custom transport
464
496
# instance provides an extensibility point for unusual situations.
465
497
if isinstance (transport , CloudDeployTransport ):
466
498
# transport is a CloudDeployTransport instance.
467
- if credentials or client_options .credentials_file :
499
+ if credentials or client_options .credentials_file or api_key_value :
468
500
raise ValueError (
469
501
"When providing a transport instance, "
470
502
"provide its credentials directly."
@@ -476,6 +508,15 @@ def __init__(
476
508
)
477
509
self ._transport = transport
478
510
else :
511
+ import google .auth ._default # type: ignore
512
+
513
+ if api_key_value and hasattr (
514
+ google .auth ._default , "get_api_key_credentials"
515
+ ):
516
+ credentials = google .auth ._default .get_api_key_credentials (
517
+ api_key_value
518
+ )
519
+
479
520
Transport = type (self ).get_transport_class (transport )
480
521
self ._transport = Transport (
481
522
credentials = credentials ,
0 commit comments