diff --git a/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache b/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache index b929d30c133..bc1e8138c38 100644 --- a/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache +++ b/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache @@ -8,11 +8,14 @@ import re import ssl import aiohttp +import aiohttp_retry from {{packageName}}.exceptions import ApiException, ApiValueError RESTResponseType = aiohttp.ClientResponse +ALLOW_RETRY_METHODS = frozenset({'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'TRACE'}) + class RESTResponse(io.IOBase): def __init__(self, resp) -> None: @@ -68,8 +71,24 @@ class RESTClientObject: trust_env=True ) + retries = configuration.retries + if retries is not None: + self.retry_client = aiohttp_retry.RetryClient( + client_session=self.pool_manager, + retry_options=aiohttp_retry.ExponentialRetry( + attempts=retries, + factor=0.0, + start_timeout=0.0, + max_timeout=120.0 + ) + ) + else: + self.retry_client = None + async def close(self): await self.pool_manager.close() + if self.retry_client is not None: + await self.retry_client.close() async def request( self, @@ -168,7 +187,12 @@ class RESTClientObject: declared content type.""" raise ApiException(status=0, reason=msg) - r = await self.pool_manager.request(**args) + if self.retry_client is not None and method in ALLOW_RETRY_METHODS: + pool_manager = self.retry_client + else: + pool_manager = self.pool_manager + + r = await pool_manager.request(**args) return RESTResponse(r) diff --git a/modules/openapi-generator/src/main/resources/python/pyproject.mustache b/modules/openapi-generator/src/main/resources/python/pyproject.mustache index 568fa4ebf94..f4e117c2795 100644 --- a/modules/openapi-generator/src/main/resources/python/pyproject.mustache +++ b/modules/openapi-generator/src/main/resources/python/pyproject.mustache @@ -16,6 +16,7 @@ urllib3 = ">= 1.25.3" python-dateutil = ">=2.8.2" {{#asyncio}} aiohttp = ">= 3.8.4" +aiohttp-retry = ">= 2.8.3" {{/asyncio}} {{#tornado}} tornado = ">=4.2,<5" diff --git a/modules/openapi-generator/src/main/resources/python/requirements.mustache b/modules/openapi-generator/src/main/resources/python/requirements.mustache index 0fa8f6fd14d..5412515b5f4 100644 --- a/modules/openapi-generator/src/main/resources/python/requirements.mustache +++ b/modules/openapi-generator/src/main/resources/python/requirements.mustache @@ -5,6 +5,7 @@ pydantic >= 2 typing-extensions >= 4.7.1 {{#asyncio}} aiohttp >= 3.0.0 +aiohttp-retry >= 2.8.3 {{/asyncio}} {{#hasHttpSignatureMethods}} pycryptodome >= 3.9.0 diff --git a/modules/openapi-generator/src/main/resources/python/setup.mustache b/modules/openapi-generator/src/main/resources/python/setup.mustache index 1468f827370..cb372a5e02e 100644 --- a/modules/openapi-generator/src/main/resources/python/setup.mustache +++ b/modules/openapi-generator/src/main/resources/python/setup.mustache @@ -21,6 +21,7 @@ REQUIRES = [ "python-dateutil", {{#asyncio}} "aiohttp >= 3.0.0", + "aiohttp-retry >= 2.8.3", {{/asyncio}} {{#tornado}} "tornado>=4.2,<5", diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py index 3e669039dab..0d4d999ee59 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py @@ -18,11 +18,14 @@ import re import ssl import aiohttp +import aiohttp_retry from petstore_api.exceptions import ApiException, ApiValueError RESTResponseType = aiohttp.ClientResponse +ALLOW_RETRY_METHODS = frozenset({'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'TRACE'}) + class RESTResponse(io.IOBase): def __init__(self, resp) -> None: @@ -78,8 +81,24 @@ class RESTClientObject: trust_env=True ) + retries = configuration.retries + if retries is not None: + self.retry_client = aiohttp_retry.RetryClient( + client_session=self.pool_manager, + retry_options=aiohttp_retry.ExponentialRetry( + attempts=retries, + factor=0.0, + start_timeout=0.0, + max_timeout=120.0 + ) + ) + else: + self.retry_client = None + async def close(self): await self.pool_manager.close() + if self.retry_client is not None: + await self.retry_client.close() async def request( self, @@ -178,7 +197,12 @@ class RESTClientObject: declared content type.""" raise ApiException(status=0, reason=msg) - r = await self.pool_manager.request(**args) + if self.retry_client is not None and method in ALLOW_RETRY_METHODS: + pool_manager = self.retry_client + else: + pool_manager = self.pool_manager + + r = await pool_manager.request(**args) return RESTResponse(r) diff --git a/samples/openapi3/client/petstore/python-aiohttp/pyproject.toml b/samples/openapi3/client/petstore/python-aiohttp/pyproject.toml index 6747ce2b913..807b7380d91 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/pyproject.toml +++ b/samples/openapi3/client/petstore/python-aiohttp/pyproject.toml @@ -15,6 +15,7 @@ python = "^3.7" urllib3 = ">= 1.25.3" python-dateutil = ">=2.8.2" aiohttp = ">= 3.8.4" +aiohttp-retry = ">= 2.8.3" pem = ">= 19.3.0" pycryptodome = ">= 3.9.0" pydantic = ">=2" diff --git a/samples/openapi3/client/petstore/python-aiohttp/requirements.txt b/samples/openapi3/client/petstore/python-aiohttp/requirements.txt index 870cfc37f34..3564e66b316 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/requirements.txt +++ b/samples/openapi3/client/petstore/python-aiohttp/requirements.txt @@ -4,4 +4,5 @@ urllib3 >= 1.25.3, < 2.1.0 pydantic >= 2 typing-extensions >= 4.7.1 aiohttp >= 3.0.0 +aiohttp-retry >= 2.8.3 pycryptodome >= 3.9.0 diff --git a/samples/openapi3/client/petstore/python-aiohttp/setup.py b/samples/openapi3/client/petstore/python-aiohttp/setup.py index 4c8c7663615..a51834b09ae 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/setup.py +++ b/samples/openapi3/client/petstore/python-aiohttp/setup.py @@ -27,6 +27,7 @@ REQUIRES = [ "urllib3 >= 1.25.3, < 2.1.0", "python-dateutil", "aiohttp >= 3.0.0", + "aiohttp-retry >= 2.8.3", "pem>=19.3.0", "pycryptodome>=3.9.0", "pydantic >= 2",