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