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