77import jwt
88import time
99from azure .identity import ManagedIdentityCredential
10+ import tenacity as tn
11+ from ._retry_strategy import _log_retry_info , _return_last_value
1012
1113from msal_extensions .persistence import FilePersistence
1214from msal_extensions .token_cache import PersistedTokenCache
15+ import errno
16+
1317
1418if not sys .platform .startswith ("linux" ):
1519 from msal_extensions import build_encrypted_persistence
@@ -19,13 +23,29 @@ def scope_for_resource(resource_id):
1923 return f"{ resource_id } /.default"
2024
2125
26+ def _maybe_nfs_exception (exception ):
27+ return isinstance (exception , OSError ) and (
28+ exception .errno in (errno .EAGAIN , errno .ESTALE )
29+ )
30+
31+
2232class AuthProvider :
2333 def __init__ (self , resource_id ):
2434 self ._resource_id = resource_id
2535 self ._scope = scope_for_resource (resource_id )
2636 self ._app = None
2737 return
2838
39+ @tn .retry (
40+ retry = tn .retry_if_exception (_maybe_nfs_exception ),
41+ stop = tn .stop_after_attempt (6 ),
42+ wait = (
43+ tn .wait_exponential (multiplier = 0.5 , exp_base = 2 )
44+ + tn .wait_random_exponential (multiplier = 0.5 , exp_base = 2 )
45+ ),
46+ retry_error_callback = _return_last_value ,
47+ before_sleep = _log_retry_info ,
48+ )
2949 def get_token (self ):
3050 accounts = self ._app .get_accounts ()
3151 if len (accounts ) == 0 :
@@ -77,6 +97,16 @@ def get_token_path(resource_id, suffix):
7797 )
7898
7999
100+ @tn .retry (
101+ retry = tn .retry_if_exception (_maybe_nfs_exception ),
102+ stop = tn .stop_after_attempt (6 ),
103+ wait = (
104+ tn .wait_exponential (multiplier = 0.5 , exp_base = 2 )
105+ + tn .wait_random_exponential (multiplier = 0.5 , exp_base = 2 )
106+ ),
107+ retry_error_callback = _return_last_value ,
108+ before_sleep = _log_retry_info ,
109+ )
80110def get_token_cache (resource_id , suffix ):
81111 # https://github.com/AzureAD/microsoft-authentication-extensions-\
82112 # for-python
@@ -110,6 +140,16 @@ def get_token_cache(resource_id, suffix):
110140 return cache
111141
112142
143+ @tn .retry (
144+ retry = tn .retry_if_exception (_maybe_nfs_exception ),
145+ stop = tn .stop_after_attempt (6 ),
146+ wait = (
147+ tn .wait_exponential (multiplier = 0.5 , exp_base = 2 )
148+ + tn .wait_random_exponential (multiplier = 0.5 , exp_base = 2 )
149+ ),
150+ retry_error_callback = _return_last_value ,
151+ before_sleep = _log_retry_info ,
152+ )
113153def protect_token_cache (resource_id , suffix ):
114154 token_path = get_token_path (resource_id , suffix )
115155
@@ -143,6 +183,16 @@ def __init__(self, client_id, authority, resource_id):
143183 pass
144184 return
145185
186+ @tn .retry (
187+ retry = tn .retry_if_exception (_maybe_nfs_exception ),
188+ stop = tn .stop_after_attempt (6 ),
189+ wait = (
190+ tn .wait_exponential (multiplier = 0.5 , exp_base = 2 )
191+ + tn .wait_random_exponential (multiplier = 0.5 , exp_base = 2 )
192+ ),
193+ retry_error_callback = _return_last_value ,
194+ before_sleep = _log_retry_info ,
195+ )
146196 def login (self ):
147197 scopes = [self ._scope + " offline_access" ]
148198 login_timeout_minutes = 7
@@ -200,6 +250,16 @@ def __init__(self, client_id, authority, resource_id):
200250 pass
201251 return
202252
253+ @tn .retry (
254+ retry = tn .retry_if_exception (_maybe_nfs_exception ),
255+ stop = tn .stop_after_attempt (6 ),
256+ wait = (
257+ tn .wait_exponential (multiplier = 0.5 , exp_base = 2 )
258+ + tn .wait_random_exponential (multiplier = 0.5 , exp_base = 2 )
259+ ),
260+ retry_error_callback = _return_last_value ,
261+ before_sleep = _log_retry_info ,
262+ )
203263 def login (self ):
204264 flow = self ._app .initiate_device_flow ([self ._scope ])
205265
@@ -232,13 +292,33 @@ def __init__(self, resource_id):
232292 self ._scope = scope_for_resource (resource_id )
233293 return
234294
295+ @tn .retry (
296+ retry = tn .retry_if_exception (_maybe_nfs_exception ),
297+ stop = tn .stop_after_attempt (6 ),
298+ wait = (
299+ tn .wait_exponential (multiplier = 0.5 , exp_base = 2 )
300+ + tn .wait_random_exponential (multiplier = 0.5 , exp_base = 2 )
301+ ),
302+ retry_error_callback = _return_last_value ,
303+ before_sleep = _log_retry_info ,
304+ )
235305 def get_token (self ):
236306 return self ._app .get_token (self ._scope ).token
237307
238308 pass
239309
240310
241311class AuthProviderSumoToken (AuthProvider ):
312+ @tn .retry (
313+ retry = tn .retry_if_exception (_maybe_nfs_exception ),
314+ stop = tn .stop_after_attempt (6 ),
315+ wait = (
316+ tn .wait_exponential (multiplier = 0.5 , exp_base = 2 )
317+ + tn .wait_random_exponential (multiplier = 0.5 , exp_base = 2 )
318+ ),
319+ retry_error_callback = _return_last_value ,
320+ before_sleep = _log_retry_info ,
321+ )
242322 def __init__ (self , resource_id ):
243323 protect_token_cache (resource_id , ".sharedkey" )
244324 token_path = get_token_path (resource_id , ".sharedkey" )
@@ -253,6 +333,16 @@ def get_authorization(self):
253333 return {"X-SUMO-Token" : self ._token }
254334
255335
336+ @tn .retry (
337+ retry = tn .retry_if_exception (_maybe_nfs_exception ),
338+ stop = tn .stop_after_attempt (6 ),
339+ wait = (
340+ tn .wait_exponential (multiplier = 0.5 , exp_base = 2 )
341+ + tn .wait_random_exponential (multiplier = 0.5 , exp_base = 2 )
342+ ),
343+ retry_error_callback = _return_last_value ,
344+ before_sleep = _log_retry_info ,
345+ )
256346def get_auth_provider (
257347 client_id ,
258348 authority ,
0 commit comments