@@ -295,6 +295,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
295
295
m = re .match (r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$" , path )
296
296
return m .groupdict () if m else {}
297
297
298
+ @classmethod
299
+ def get_mtls_endpoint_and_cert_source (
300
+ cls , client_options : Optional [client_options_lib .ClientOptions ] = None
301
+ ):
302
+ """Return the API endpoint and client cert source for mutual TLS.
303
+
304
+ The client cert source is determined in the following order:
305
+ (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
306
+ client cert source is None.
307
+ (2) if `client_options.client_cert_source` is provided, use the provided one; if the
308
+ default client cert source exists, use the default one; otherwise the client cert
309
+ source is None.
310
+
311
+ The API endpoint is determined in the following order:
312
+ (1) if `client_options.api_endpoint` if provided, use the provided one.
313
+ (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
314
+ default mTLS endpoint; if the environment variabel is "never", use the default API
315
+ endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
316
+ use the default API endpoint.
317
+
318
+ More details can be found at https://google.aip.dev/auth/4114.
319
+
320
+ Args:
321
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
322
+ client. Only the `api_endpoint` and `client_cert_source` properties may be used
323
+ in this method.
324
+
325
+ Returns:
326
+ Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the
327
+ client cert source to use.
328
+
329
+ Raises:
330
+ google.auth.exceptions.MutualTLSChannelError: If any errors happen.
331
+ """
332
+ if client_options is None :
333
+ client_options = client_options_lib .ClientOptions ()
334
+ use_client_cert = os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" )
335
+ use_mtls_endpoint = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
336
+ if use_client_cert not in ("true" , "false" ):
337
+ raise ValueError (
338
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
339
+ )
340
+ if use_mtls_endpoint not in ("auto" , "never" , "always" ):
341
+ raise MutualTLSChannelError (
342
+ "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
343
+ )
344
+
345
+ # Figure out the client cert source to use.
346
+ client_cert_source = None
347
+ if use_client_cert == "true" :
348
+ if client_options .client_cert_source :
349
+ client_cert_source = client_options .client_cert_source
350
+ elif mtls .has_default_client_cert_source ():
351
+ client_cert_source = mtls .default_client_cert_source ()
352
+
353
+ # Figure out which api endpoint to use.
354
+ if client_options .api_endpoint is not None :
355
+ api_endpoint = client_options .api_endpoint
356
+ elif use_mtls_endpoint == "always" or (
357
+ use_mtls_endpoint == "auto" and client_cert_source
358
+ ):
359
+ api_endpoint = cls .DEFAULT_MTLS_ENDPOINT
360
+ else :
361
+ api_endpoint = cls .DEFAULT_ENDPOINT
362
+
363
+ return api_endpoint , client_cert_source
364
+
298
365
def __init__ (
299
366
self ,
300
367
* ,
@@ -345,57 +412,22 @@ def __init__(
345
412
if client_options is None :
346
413
client_options = client_options_lib .ClientOptions ()
347
414
348
- # Create SSL credentials for mutual TLS if needed.
349
- if os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) not in (
350
- "true" ,
351
- "false" ,
352
- ):
353
- raise ValueError (
354
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
355
- )
356
- use_client_cert = (
357
- os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ) == "true"
415
+ api_endpoint , client_cert_source_func = self .get_mtls_endpoint_and_cert_source (
416
+ client_options
358
417
)
359
418
360
- client_cert_source_func = None
361
- is_mtls = False
362
- if use_client_cert :
363
- if client_options .client_cert_source :
364
- is_mtls = True
365
- client_cert_source_func = client_options .client_cert_source
366
- else :
367
- is_mtls = mtls .has_default_client_cert_source ()
368
- if is_mtls :
369
- client_cert_source_func = mtls .default_client_cert_source ()
370
- else :
371
- client_cert_source_func = None
372
-
373
- # Figure out which api endpoint to use.
374
- if client_options .api_endpoint is not None :
375
- api_endpoint = client_options .api_endpoint
376
- else :
377
- use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
378
- if use_mtls_env == "never" :
379
- api_endpoint = self .DEFAULT_ENDPOINT
380
- elif use_mtls_env == "always" :
381
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
382
- elif use_mtls_env == "auto" :
383
- if is_mtls :
384
- api_endpoint = self .DEFAULT_MTLS_ENDPOINT
385
- else :
386
- api_endpoint = self .DEFAULT_ENDPOINT
387
- else :
388
- raise MutualTLSChannelError (
389
- "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted "
390
- "values: never, auto, always"
391
- )
419
+ api_key_value = getattr (client_options , "api_key" , None )
420
+ if api_key_value and credentials :
421
+ raise ValueError (
422
+ "client_options.api_key and credentials are mutually exclusive"
423
+ )
392
424
393
425
# Save or instantiate the transport.
394
426
# Ordinarily, we provide the transport, but allowing a custom transport
395
427
# instance provides an extensibility point for unusual situations.
396
428
if isinstance (transport , DatastreamTransport ):
397
429
# transport is a DatastreamTransport instance.
398
- if credentials or client_options .credentials_file :
430
+ if credentials or client_options .credentials_file or api_key_value :
399
431
raise ValueError (
400
432
"When providing a transport instance, "
401
433
"provide its credentials directly."
@@ -407,6 +439,15 @@ def __init__(
407
439
)
408
440
self ._transport = transport
409
441
else :
442
+ import google .auth ._default # type: ignore
443
+
444
+ if api_key_value and hasattr (
445
+ google .auth ._default , "get_api_key_credentials"
446
+ ):
447
+ credentials = google .auth ._default .get_api_key_credentials (
448
+ api_key_value
449
+ )
450
+
410
451
Transport = type (self ).get_transport_class (transport )
411
452
self ._transport = Transport (
412
453
credentials = credentials ,
0 commit comments