Skip to content

Commit c4d05ff

Browse files
fix: Fix lint and unit tests
Signed-off-by: Radhika Agrawal <agrawalradhika@google.com>
1 parent 91570a3 commit c4d05ff

2 files changed

Lines changed: 132 additions & 64 deletions

File tree

packages/google-auth/google/auth/transport/grpc.py

Lines changed: 69 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525

2626
from google.auth import exceptions
27-
from google.auth import transport
27+
from google.auth import transport
2828
from google.auth.transport import _mtls_helper
2929
from google.auth.transport import mtls
3030
from google.oauth2 import service_account
@@ -408,12 +408,12 @@ class _MTLSCallInterceptor(
408408
grpc.StreamStreamClientInterceptor,
409409
):
410410
"""A gRPC client interceptor that provides automatic retry logic for mTLS certificate rotation.
411-
412-
This interceptor wraps all gRPC client calls (unary and streaming) with retryable
413-
futures or iterators. Its primary role is to monitor responses for `UNAUTHENTICATED`
414-
errors. When an authentication failure occurs, it uses `_should_retry()` to check
415-
if a new mTLS certificate is available. If a new certificate is found, it signals
416-
its associated `_MTLSRefreshingChannel` wrapper to refresh the underlying gRPC
411+
412+
This interceptor wraps all gRPC client calls (unary and streaming) with retryable
413+
futures or iterators. Its primary role is to monitor responses for `UNAUTHENTICATED`
414+
errors. When an authentication failure occurs, it uses `_should_retry()` to check
415+
if a new mTLS certificate is available. If a new certificate is found, it signals
416+
its associated `_MTLSRefreshingChannel` wrapper to refresh the underlying gRPC
417417
channel's credentials and automatically replays the failed RPC.
418418
"""
419419

@@ -423,15 +423,17 @@ def __init__(self):
423423

424424
def _should_retry(self, code, retry_count, attempt_cert):
425425
"""Determines if the RPC should be retried due to a certificate rotation.
426-
427-
Returns a tuple: (should_retry, call_cert_bytes, call_key_bytes, passphrase).
428-
"""
426+
427+
Returns a tuple: (should_retry, call_cert_bytes, call_key_bytes, passphrase).
428+
"""
429429
if code != grpc.StatusCode.UNAUTHENTICATED or not self._wrapper:
430430
return False, None, None, None
431431

432432
if retry_count >= self._max_retries:
433433
_LOGGER.debug(
434-
"Max retries reached (%d/%d) for channel recreation.", retry_count, self._max_retries
434+
"Max retries reached (%d/%d) for channel recreation.",
435+
retry_count,
436+
self._max_retries,
435437
)
436438
return False, None, None, None
437439

@@ -492,14 +494,14 @@ def __init__(self, target, factory_args, initial_channel, initial_cert):
492494
self._lock = threading.Lock()
493495
self._subscribers = set()
494496

495-
def refresh_logic(self, count, call_cert_bytes=None, call_key_bytes=None, passphrase=None):
497+
def refresh_logic(
498+
self, count, call_cert_bytes=None, call_key_bytes=None, passphrase=None
499+
):
496500
with self._lock:
497501
if not call_cert_bytes or self._cached_cert == call_cert_bytes:
498502
return
499503

500-
_LOGGER.debug(
501-
"Wrapper: Refreshing mTLS channel. Retry count: %d", count
502-
)
504+
_LOGGER.debug("Wrapper: Refreshing mTLS channel. Retry count: %d", count)
503505
old_channel = self._channel
504506

505507
if passphrase is not None:
@@ -630,15 +632,19 @@ def __next__(self):
630632
("method", "timeout", "metadata", "credentials", "wait_for_ready"),
631633
)
632634

635+
633636
class _DeadlineExceededError(grpc.RpcError, grpc.Call):
634637
def __init__(self, details):
635638
super().__init__()
636639
self._details = details
640+
637641
def code(self):
638642
return grpc.StatusCode.DEADLINE_EXCEEDED
643+
639644
def details(self):
640645
return self._details
641646

647+
642648
class _RetryableUnaryResponseFuture(grpc.Future, grpc.Call):
643649
def __init__(
644650
self,
@@ -698,7 +704,9 @@ def _start_call(self):
698704
elapsed = time.monotonic() - self._start_time
699705
remaining = self._initial_timeout - elapsed
700706
if remaining <= 0:
701-
raise _DeadlineExceededError("Deadline Exceeded during retry resolution.")
707+
raise _DeadlineExceededError(
708+
"Deadline Exceeded during retry resolution."
709+
)
702710
call_details = _ClientCallDetails(
703711
method=call_details.method,
704712
timeout=remaining,
@@ -742,7 +750,9 @@ def _on_inner_future_done(self, inner_future):
742750
if can_replay and should_retry:
743751
if getattr(self._interceptor, "_wrapper", None):
744752
try:
745-
self._interceptor._wrapper.refresh_logic(1, call_cert, call_key, pwd)
753+
self._interceptor._wrapper.refresh_logic(
754+
1, call_cert, call_key, pwd
755+
)
746756
except Exception as e:
747757
with self._lock:
748758
self._terminal_exception = e
@@ -757,18 +767,23 @@ def _on_inner_future_done(self, inner_future):
757767
self._terminal_exception = e
758768

759769
if self._interceptor._wrapper:
760-
chk_should_retry, chk_cert, chk_key, chk_pwd = self._interceptor._should_retry(
761-
status_code, 0, self._attempt_cert
762-
)
770+
(
771+
chk_should_retry,
772+
chk_cert,
773+
chk_key,
774+
chk_pwd,
775+
) = self._interceptor._should_retry(status_code, 0, self._attempt_cert)
763776
if chk_should_retry:
764777
try:
765-
self._interceptor._wrapper.refresh_logic(1, chk_cert, chk_key, chk_pwd)
778+
self._interceptor._wrapper.refresh_logic(
779+
1, chk_cert, chk_key, chk_pwd
780+
)
766781
except Exception:
767782
pass
768783
with self._lock:
769784
self._completion_event.set()
770785
callbacks_to_fire = list(self._done_callbacks)
771-
786+
772787
for fn in callbacks_to_fire:
773788
try:
774789
fn(self)
@@ -929,7 +944,9 @@ def _start_call(self):
929944
elapsed = time.monotonic() - self._start_time
930945
remaining = self._initial_timeout - elapsed
931946
if remaining <= 0:
932-
raise _DeadlineExceededError("Deadline Exceeded during retry resolution.")
947+
raise _DeadlineExceededError(
948+
"Deadline Exceeded during retry resolution."
949+
)
933950
call_details = _ClientCallDetails(
934951
method=call_details.method,
935952
timeout=remaining,
@@ -959,9 +976,12 @@ def _on_inner_call_done(self, inner_call):
959976
if self._call is not inner_call:
960977
return
961978
# Intercept and suppress premature callbacks for UNAUTHENTICATED.
962-
# __next__ inherently handles this error and manages triggering callbacks
979+
# __next__ inherently handles this error and manages triggering callbacks
963980
# later if retriies are exhausted.
964-
if callable(getattr(inner_call, "code", None)) and inner_call.code() == grpc.StatusCode.UNAUTHENTICATED:
981+
if (
982+
callable(getattr(inner_call, "code", None))
983+
and inner_call.code() == grpc.StatusCode.UNAUTHENTICATED
984+
):
965985
return
966986
self._trigger_callbacks()
967987

@@ -994,42 +1014,52 @@ def __next__(self):
9941014
)
9951015
)
9961016

997-
should_retry, call_cert, call_key, pwd = self._interceptor._should_retry(
1017+
(
1018+
should_retry,
1019+
call_cert,
1020+
call_key,
1021+
pwd,
1022+
) = self._interceptor._should_retry(
9981023
status_code,
9991024
self._retry_count,
10001025
getattr(self, "_attempt_cert", None),
10011026
)
10021027

1003-
if (
1004-
not self._yielded_any_response
1005-
and can_replay
1006-
and should_retry
1007-
):
1028+
if not self._yielded_any_response and can_replay and should_retry:
10081029
try:
10091030
if getattr(self._interceptor, "_wrapper", None):
1010-
self._interceptor._wrapper.refresh_logic(1, call_cert, call_key, pwd)
1011-
1031+
self._interceptor._wrapper.refresh_logic(
1032+
1, call_cert, call_key, pwd
1033+
)
1034+
10121035
with self._lock:
10131036
self._retry_count += 1
10141037
self._start_call()
1015-
1038+
10161039
except Exception as fallback_e:
10171040
self._trigger_callbacks()
10181041
raise fallback_e
1019-
1042+
10201043
continue
10211044
else:
10221045
# Non-retryable error, check if another rotation happened while we were finishing
10231046
if getattr(self._interceptor, "_wrapper", None):
1024-
chk_should_retry, chk_cert, chk_key, chk_pwd = self._interceptor._should_retry(
1047+
(
1048+
chk_should_retry,
1049+
chk_cert,
1050+
chk_key,
1051+
chk_pwd,
1052+
) = self._interceptor._should_retry(
10251053
status_code, 0, getattr(self, "_attempt_cert", None)
10261054
)
10271055
if chk_should_retry:
10281056
try:
1029-
self._interceptor._wrapper.refresh_logic(1, chk_cert, chk_key, chk_pwd)
1057+
self._interceptor._wrapper.refresh_logic(
1058+
1, chk_cert, chk_key, chk_pwd
1059+
)
10301060
except Exception:
1031-
pass # Terminal anyway
1032-
1061+
pass # Terminal anyway
1062+
10331063
self._trigger_callbacks()
10341064
raise e
10351065

0 commit comments

Comments
 (0)