diff --git a/README.md b/README.md index e9e70cb..18c085f 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ $ export OSC_REGION= (default: eu-west-2) $ export OSC_MAX_RETRIES= (default: 3) $ export OSC_RETRY_BACKOFF_FACTOR= (default: 1.0) $ export OSC_RETRY_BACKOFF_JITTER= (default: 3.0) +$ export OSC_RETRY_BACKOFF_MAX= (default: 30) ``` ## Credentials files @@ -94,12 +95,13 @@ These options are: - max_retries (integer, default 3) - retry_backoff_factor (float, default 1.0) - retry_backoff_jitter (float, default 3.0) + - retry_backoff_max (float, default 30) Those options correspond to their counterparts in [urllib3](https://urllib3.readthedocs.io/en/stable/reference/urllib3.util.html#urllib3.util.Retry) Example: ```python -gw = Gateway(max_retries=5, retry_backoff_factor=0.5, retry_backoff_jitter=1.0) +gw = Gateway(max_retries=5, retry_backoff_factor=0.5, retry_backoff_jitter=1.0, retry_backoff_max=120) ```` # Example diff --git a/osc_sdk_python/authentication.py b/osc_sdk_python/authentication.py index 9a69ad8..4ac335a 100644 --- a/osc_sdk_python/authentication.py +++ b/osc_sdk_python/authentication.py @@ -48,7 +48,7 @@ def forge_headers_signed(self, uri, request_data): def build_dates(self): '''Return YYYYMMDDTHHmmssZ, YYYYMMDD ''' - t = datetime.datetime.utcnow() + t = datetime.datetime.now(datetime.timezone.utc) return t.strftime('%Y%m%dT%H%M%SZ'), t.strftime('%Y%m%d') def sign(self, key, msg): diff --git a/osc_sdk_python/call.py b/osc_sdk_python/call.py index df15c81..992bcfe 100644 --- a/osc_sdk_python/call.py +++ b/osc_sdk_python/call.py @@ -26,7 +26,8 @@ def __init__(self, logger=None, **kwargs): x509_client_cert=kwargs.pop("x509_client_cert", None), max_retries=kwargs.pop("max_retries", None), retry_backoff_factor=kwargs.pop("retry_backoff_factor", None), - retry_backoff_jitter=kwargs.pop("retry_backoff_jitter", None) + retry_backoff_jitter=kwargs.pop("retry_backoff_jitter", None), + retry_backoff_max=kwargs.pop("retry_backoff_max", None) ) def update_credentials( @@ -42,6 +43,7 @@ def update_credentials( max_retries=None, retry_backoff_factor=None, retry_backoff_jitter=None, + retry_backoff_max=None, ): self.credentials = { "access_key": access_key, @@ -54,6 +56,7 @@ def update_credentials( "max_retries": max_retries, "retry_backoff_factor": retry_backoff_factor, "retry_backoff_jitter": retry_backoff_jitter, + "retry_backoff_max": retry_backoff_max, } def api(self, action, **data): @@ -81,6 +84,7 @@ def api(self, action, **data): credentials.max_retries, credentials.retry_backoff_factor, credentials.retry_backoff_jitter, + credentials.retry_backoff_max, ) if self.logger != None: self.logger.do_log( diff --git a/osc_sdk_python/credentials.py b/osc_sdk_python/credentials.py index 31f0334..2491949 100644 --- a/osc_sdk_python/credentials.py +++ b/osc_sdk_python/credentials.py @@ -8,6 +8,7 @@ MAX_RETRIES = 3 RETRY_BACKOFF_FACTOR = 1 RETRY_BACKOFF_JITTER = 3 +RETRY_BACKOFF_MAX = 30 class Credentials: @@ -24,6 +25,7 @@ def __init__( max_retries=None, retry_backoff_factor=None, retry_backoff_jitter=None, + retry_backoff_max=None, ): self.region = None self.access_key = access_key @@ -35,6 +37,7 @@ def __init__( self.max_retries = max_retries self.retry_backoff_factor = retry_backoff_factor self.retry_backoff_jitter = retry_backoff_jitter + self.retry_backoff_max = retry_backoff_max if profile is None: profile = os.environ.get("OSC_PROFILE") @@ -70,6 +73,8 @@ def __init__( self.retry_backoff_factor = RETRY_BACKOFF_FACTOR if self.retry_backoff_jitter is None: self.retry_backoff_jitter = RETRY_BACKOFF_JITTER + if self.retry_backoff_max is None: + self.retry_backoff_max = RETRY_BACKOFF_MAX self.check_options() @@ -106,6 +111,10 @@ def load_credentials_from_file(self, profile, file_path): if retry_backoff_jitter is not None: self.retry_backoff_jitter = retry_backoff_jitter + retry_backoff_max = profile.get("retry_backoff_max") + if retry_backoff_max is not None: + self.retry_backoff_max = retry_backoff_max + except IOError: pass @@ -128,6 +137,9 @@ def load_credentials_from_env(self): retry_backoff_jitter = os.environ.get("OSC_RETRY_BACKOFF_JITTER") if retry_backoff_jitter is not None: self.retry_backoff_factor = float(retry_backoff_jitter) + retry_backoff_max = os.environ.get("OSC_RETRY_BACKOFF_MAX") + if retry_backoff_max is not None: + self.retry_backoff_factor = float(retry_backoff_max) def check_options(self): if self.access_key is not None or self.secret_key is not None: diff --git a/osc_sdk_python/outscale_gateway.py b/osc_sdk_python/outscale_gateway.py index 0bd260d..43931d6 100644 --- a/osc_sdk_python/outscale_gateway.py +++ b/osc_sdk_python/outscale_gateway.py @@ -1,6 +1,5 @@ import os import sys -import threading from .call import Call from .credentials import Credentials import ruamel.yaml diff --git a/osc_sdk_python/requester.py b/osc_sdk_python/requester.py index e290b5f..09a4030 100644 --- a/osc_sdk_python/requester.py +++ b/osc_sdk_python/requester.py @@ -1,5 +1,4 @@ from requests import Session, HTTPError -from requests import Session from requests.adapters import HTTPAdapter from requests.exceptions import JSONDecodeError from urllib3.util.retry import Retry @@ -16,6 +15,7 @@ def __init__( max_retries=0, backoff_factor=0, backoff_jitter=0, + backoff_max=120, status_forcelist=HTTP_CODE_RETRY, allowed_methods=METHODS_RETRY, ): @@ -26,6 +26,7 @@ def __init__( total=max_retries, backoff_factor=backoff_factor, backoff_jitter=backoff_jitter, + backoff_max=backoff_max, status_forcelist=status_forcelist, allowed_methods=allowed_methods, )