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