1010 NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT.
1111"""
1212
13+ import asyncio
1314import json
15+ import math
16+ import random
17+ import sys
1418from datetime import datetime , timedelta
1519
1620import urllib3
1721
22+ from openfga_sdk .configuration import Configuration
1823from openfga_sdk .credentials import Credentials
1924from openfga_sdk .exceptions import AuthenticationError
2025
2126
27+ def jitter (loop_count , min_wait_in_ms ):
28+ """
29+ Generate a random jitter value for exponential backoff
30+ """
31+ minimum = math .ceil (2 ** loop_count * min_wait_in_ms )
32+ maximum = math .ceil (2 ** (loop_count + 1 ) * min_wait_in_ms )
33+ jitter = random .randrange (minimum , maximum ) / 1000
34+
35+ # If running in pytest, set jitter to 0 to speed up tests
36+ if "pytest" in sys .modules :
37+ jitter = 0
38+
39+ return jitter
40+
41+
2242class OAuth2Client :
2343
24- def __init__ (self , credentials : Credentials ):
44+ def __init__ (self , credentials : Credentials , configuration = None ):
2545 self ._credentials = credentials
2646 self ._access_token = None
2747 self ._access_expiry_time = None
2848
49+ if configuration is None :
50+ configuration = Configuration .get_default_copy ()
51+
52+ self .configuration = configuration
53+
2954 def _token_valid (self ):
3055 """
3156 Return whether token is valid
@@ -41,37 +66,65 @@ async def _obtain_token(self, client):
4166 Perform OAuth2 and obtain token
4267 """
4368 configuration = self ._credentials .configuration
69+
4470 token_url = f"https://{ configuration .api_issuer } /oauth/token"
71+
4572 post_params = {
4673 "client_id" : configuration .client_id ,
4774 "client_secret" : configuration .client_secret ,
4875 "audience" : configuration .api_audience ,
4976 "grant_type" : "client_credentials" ,
5077 }
78+
5179 headers = urllib3 .response .HTTPHeaderDict (
5280 {
5381 "Accept" : "application/json" ,
5482 "Content-Type" : "application/x-www-form-urlencoded" ,
5583 "User-Agent" : "openfga-sdk (python) 0.4.1" ,
5684 }
5785 )
58- raw_response = await client .POST (
59- token_url , headers = headers , post_params = post_params
86+
87+ max_retry = (
88+ self .configuration .retry_params .max_retry
89+ if (
90+ self .configuration .retry_params is not None
91+ and self .configuration .retry_params .max_retry is not None
92+ )
93+ else 0
6094 )
61- if 200 <= raw_response .status <= 299 :
62- try :
63- api_response = json .loads (raw_response .data )
64- except :
65- raise AuthenticationError (http_resp = raw_response )
66- if not api_response .get ("expires_in" ) or not api_response .get (
67- "access_token"
68- ):
69- raise AuthenticationError (http_resp = raw_response )
70- self ._access_expiry_time = datetime .now () + timedelta (
71- seconds = int (api_response .get ("expires_in" ))
95+
96+ min_wait_in_ms = (
97+ self .configuration .retry_params .min_wait_in_ms
98+ if (
99+ self .configuration .retry_params is not None
100+ and self .configuration .retry_params .min_wait_in_ms is not None
101+ )
102+ else 0
103+ )
104+
105+ for attempt in range (max_retry + 1 ):
106+ raw_response = await client .POST (
107+ token_url , headers = headers , post_params = post_params
72108 )
73- self ._access_token = api_response .get ("access_token" )
74- else :
109+
110+ if 500 <= raw_response .status <= 599 or raw_response .status == 429 :
111+ if attempt < max_retry and raw_response .status != 501 :
112+ await asyncio .sleep (jitter (attempt , min_wait_in_ms ))
113+ continue
114+
115+ if 200 <= raw_response .status <= 299 :
116+ try :
117+ api_response = json .loads (raw_response .data )
118+ except :
119+ raise AuthenticationError (http_resp = raw_response )
120+
121+ if api_response .get ("expires_in" ) and api_response .get ("access_token" ):
122+ self ._access_expiry_time = datetime .now () + timedelta (
123+ seconds = int (api_response .get ("expires_in" ))
124+ )
125+ self ._access_token = api_response .get ("access_token" )
126+ break
127+
75128 raise AuthenticationError (http_resp = raw_response )
76129
77130 async def get_authentication_header (self , client ):
0 commit comments