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