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