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