Skip to content

Commit

Permalink
Merge pull request #11 from Authress/add-automatic-retries
Browse files Browse the repository at this point in the history
Add automatic retries to connection request issues. fix #10
  • Loading branch information
wparad authored Dec 26, 2023
2 parents 95dcffc + eadc1c1 commit 69c3369
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 19 deletions.
49 changes: 41 additions & 8 deletions authress/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@
import re
import tempfile
import jwt
import math
import time

from urllib.parse import quote

from authress.api_response import ApiResponse
from authress.api import service_client_token_provider
import authress.models
from authress import rest
from authress.exceptions import ApiValueError, ApiException
from authress.exceptions import ApiValueError, ApiException, ServiceException

additional_retries = 5
retry_delay_milliseconds = 20


class HttpClient(object):
Expand Down Expand Up @@ -189,19 +194,13 @@ def __call_api(
collection_formats)
url += "?" + url_query

try:
# perform request and return response
response_data = self.request(
response_data = self.request_with_retries(
method, url,
query_params=query_params,
headers=header_params,
post_params=post_params, body=body,
_preload_content=_preload_content,
_request_timeout=_request_timeout)
except ApiException as e:
if e.body:
e.body = e.body.decode('utf-8')
raise e

self.last_response = response_data

Expand Down Expand Up @@ -407,6 +406,40 @@ def call_api(self, resource_path, method,
_request_timeout,
_host, _request_auth))

def request_with_retries(self, method, url, query_params=None, headers=None,
post_params=None, body=None, _preload_content=True,
_request_timeout=None):
"""Wrapper for automatically handling retries."""

last_exception = None
for iteration in range(0, additional_retries + 1):
try:
# perform request and return response
response_data = self.request(
method, url,
query_params=query_params,
headers=headers,
post_params=post_params, body=body,
_preload_content=_preload_content,
_request_timeout=_request_timeout)
return response_data
except ServiceException as e:
if e.body:
e.body = e.body.decode('utf-8')
last_exception = e
except ApiException as e:
if e.body:
e.body = e.body.decode('utf-8')
raise e

if iteration == additional_retries:
break

time.sleep(retry_delay_milliseconds / 1000 * math.pow(2, iteration))

raise last_exception


def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None, _preload_content=True,
_request_timeout=None):
Expand Down
11 changes: 7 additions & 4 deletions authress/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ def request(self, method, url, query_params=None, headers=None,
msg = """Cannot prepare a request message for provided
arguments. Please check that your arguments match
declared content type."""
raise ApiException(status=0, reason=msg)
# For `GET`, `HEAD`
raise ServiceException(status=0, reason=msg)
# For `GET`, `HEAD`, `QUERY`
else:
r = self.pool_manager.request(method, url,
fields={},
Expand All @@ -174,7 +174,10 @@ def request(self, method, url, query_params=None, headers=None,
headers=headers)
except urllib3.exceptions.SSLError as e:
msg = "{0}\n{1}".format(type(e).__name__, str(e))
raise ApiException(status=0, reason=msg)
raise ServiceException(status=0, reason=msg)
except Exception as e:
msg = "{0}\n{1}".format(type(e).__name__, str(e))
raise ServiceException(status=0, reason=msg)

if _preload_content:
r = RESTResponse(r)
Expand All @@ -198,7 +201,7 @@ def request(self, method, url, query_params=None, headers=None,
if 500 <= r.status <= 599:
raise ServiceException(http_resp=r)

raise ApiException(http_resp=r)
raise ServiceException(http_resp=r)

return r

Expand Down
18 changes: 11 additions & 7 deletions contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,28 @@ podman stop $CID && podman rm $CID

### Common review items
* [ ] Inputs to Constructor are (string: authress_api_url, string: service_client_access_key)
* [ ] authress_api_url should sanitize https:// prefix and remove trailing `/`s
* [ ] Add authentication to the configuration class.
* [ ] Change configuration class name to be `AuthressSettings`
* Specify all the inputs to be consistent across languages
* [ ] constructors for classes should only have relevant input properties, for instances `links` are not required.
* [ ] Update documentation
* [x] constructors for classes should only have relevant input properties, for instances `links` are not required.
* [x] Update documentation
* Make sure markdown is valid
* Remove unnecessary links
* Add first class examples to readme.md + api documentation
* [ ] Url encode all url inputs, frequently the generator doesn't do that
* Find failed UserId, RoleId, TenantId, GroupId, Action properties and convert them to strings
* [ ] Remove any unnecessary validations from object and parameter injection, often there are some even when properties are allowed to be null
* [ ] The service client code to generate a JWT from private key needs to be added
* [ ] Add UnauthorizedError type to the authorizeUser function
* [ ] GET query parameters should be an object
* [ ] Top level tags from the API should accessible from the base class: `authressClient.accessRecords.getRecords(...)`
* [ ] Automatic Retry
* [ ] Automatic fallback to cache
* [x] Top level tags from the API should accessible from the base class: `authressClient.accessRecords.getRecords(...)`
* [x] Automatic Retry
* [x] Automatic fallback to cache
* [ ] `OptimisticPerformanceHandler` - Automatic fallback to cache on timeout reached
* [ ] In memory caching for authorization checks - memoize
* [ ] Unsigned int for all limits
* [ ] Update Documentation for the API
* [x] readonly properties are never specified as required for request bodies
* [x] Update Documentation for the API
* [ ] Validate all enums are enums and can be null when they should be.
* [x] Remove LocalHost from the docs
* [ ] Tests

0 comments on commit 69c3369

Please sign in to comment.