We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
http_retry_request_middleware needs to be more graceful and sleep a bit
* Version: 5
* Python: 3.x

### What was wrong?

The current `http_retry_request_middleware` is not graceful and configurable enough.

### How can it be fixed?

The current `exception_retry_middleware`, which is used by `http_retry_request_middleware`, looks like:

```python
def exception_retry_middleware(
    make_request: Callable[[RPCEndpoint, Any], RPCResponse],
    web3: "Web3",
    errors: Collection[Type[BaseException]],
    retries: int = 5,
) -> Callable[[RPCEndpoint, Any], RPCResponse]:
    """
    Creates middleware that retries failed HTTP requests. Is a default
    middleware for HTTPProvider.
    """
    def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
        if check_if_retry_on_failure(method):
            for i in range(retries):
                try:
                    return make_request(method, params)
                # https://github.com/python/mypy/issues/5349
                except errors:  # type: ignore
                    if i < retries - 1:
                        continue
                    else:
                        raise
            return None
        else:
            return make_request(method, params)
    return middleware
```

Possible usual retryable error conditions include 

* Temporary TCP/IP routing errors

* Network card reset

* Firewall reset

* JSON-RPC server restart

Under normal conditions, any of these error conditions may last from fractions of seconds up to a minute. However the current `exception_retry_middleware` has too tight loop without a sleep. It simply bombs the network interface as fast as it can, without backing off.

I recommend making `exception_retry_middleware`, and `http_retry_request_middleware`, configurable so that the library user can pass parameters for timeouts and retry counts.

Outside the scope of this issue is to make this to work with WebSocket connections and rebuild the provider on-demand. [web3.js does this.](https://github.com/ChainSafe/web3.js/releases/tag/v1.2.8). 




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `web3/middleware/exception_retry_request.py`
Content:
```
1 import asyncio
2 from typing import (
3     TYPE_CHECKING,
4     Any,
5     Callable,
6     Collection,
7     Optional,
8     Type,
9 )
10 
11 import aiohttp
12 from requests.exceptions import (
13     ConnectionError,
14     HTTPError,
15     Timeout,
16     TooManyRedirects,
17 )
18 
19 from web3.types import (
20     AsyncMiddlewareCoroutine,
21     RPCEndpoint,
22     RPCResponse,
23 )
24 
25 if TYPE_CHECKING:
26     from web3 import (  # noqa: F401
27         AsyncWeb3,
28         Web3,
29     )
30 
31 whitelist = [
32     "admin",
33     "miner",
34     "net",
35     "txpool",
36     "testing",
37     "evm",
38     "eth_protocolVersion",
39     "eth_syncing",
40     "eth_coinbase",
41     "eth_mining",
42     "eth_hashrate",
43     "eth_chainId",
44     "eth_gasPrice",
45     "eth_accounts",
46     "eth_blockNumber",
47     "eth_getBalance",
48     "eth_getStorageAt",
49     "eth_getProof",
50     "eth_getCode",
51     "eth_getBlockByNumber",
52     "eth_getBlockByHash",
53     "eth_getBlockTransactionCountByNumber",
54     "eth_getBlockTransactionCountByHash",
55     "eth_getUncleCountByBlockNumber",
56     "eth_getUncleCountByBlockHash",
57     "eth_getTransactionByHash",
58     "eth_getTransactionByBlockHashAndIndex",
59     "eth_getTransactionByBlockNumberAndIndex",
60     "eth_getTransactionReceipt",
61     "eth_getTransactionCount",
62     "eth_getRawTransactionByHash",
63     "eth_call",
64     "eth_estimateGas",
65     "eth_maxPriorityFeePerGas",
66     "eth_newBlockFilter",
67     "eth_newPendingTransactionFilter",
68     "eth_newFilter",
69     "eth_getFilterChanges",
70     "eth_getFilterLogs",
71     "eth_getLogs",
72     "eth_uninstallFilter",
73     "eth_getCompilers",
74     "eth_getWork",
75     "eth_sign",
76     "eth_signTypedData",
77     "eth_sendRawTransaction",
78     "personal_importRawKey",
79     "personal_newAccount",
80     "personal_listAccounts",
81     "personal_listWallets",
82     "personal_lockAccount",
83     "personal_unlockAccount",
84     "personal_ecRecover",
85     "personal_sign",
86     "personal_signTypedData",
87 ]
88 
89 
90 def check_if_retry_on_failure(method: RPCEndpoint) -> bool:
91     root = method.split("_")[0]
92     if root in whitelist:
93         return True
94     elif method in whitelist:
95         return True
96     else:
97         return False
98 
99 
100 def exception_retry_middleware(
101     make_request: Callable[[RPCEndpoint, Any], RPCResponse],
102     _w3: "Web3",
103     errors: Collection[Type[BaseException]],
104     retries: int = 5,
105 ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
106     """
107     Creates middleware that retries failed HTTP requests. Is a default
108     middleware for HTTPProvider.
109     """
110 
111     def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:
112         if check_if_retry_on_failure(method):
113             for i in range(retries):
114                 try:
115                     return make_request(method, params)
116                 except tuple(errors):
117                     if i < retries - 1:
118                         continue
119                     else:
120                         raise
121             return None
122         else:
123             return make_request(method, params)
124 
125     return middleware
126 
127 
128 def http_retry_request_middleware(
129     make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
130 ) -> Callable[[RPCEndpoint, Any], Any]:
131     return exception_retry_middleware(
132         make_request, w3, (ConnectionError, HTTPError, Timeout, TooManyRedirects)
133     )
134 
135 
136 async def async_exception_retry_middleware(
137     make_request: Callable[[RPCEndpoint, Any], Any],
138     _async_w3: "AsyncWeb3",
139     errors: Collection[Type[BaseException]],
140     retries: int = 5,
141     backoff_factor: float = 0.3,
142 ) -> AsyncMiddlewareCoroutine:
143     """
144     Creates middleware that retries failed HTTP requests.
145     Is a default middleware for AsyncHTTPProvider.
146     """
147 
148     async def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:
149         if check_if_retry_on_failure(method):
150             for i in range(retries):
151                 try:
152                     return await make_request(method, params)
153                 except tuple(errors):
154                     if i < retries - 1:
155                         await asyncio.sleep(backoff_factor)
156                         continue
157                     else:
158                         raise
159             return None
160         else:
161             return await make_request(method, params)
162 
163     return middleware
164 
165 
166 async def async_http_retry_request_middleware(
167     make_request: Callable[[RPCEndpoint, Any], Any], async_w3: "AsyncWeb3"
168 ) -> Callable[[RPCEndpoint, Any], Any]:
169     return await async_exception_retry_middleware(
170         make_request,
171         async_w3,
172         (TimeoutError, aiohttp.ClientError),
173     )
174
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/web3/middleware/exception_retry_request.py b/web3/middleware/exception_retry_request.py
--- a/web3/middleware/exception_retry_request.py
+++ b/web3/middleware/exception_retry_request.py
@@ -1,9 +1,11 @@
 import asyncio
+import time
 from typing import (
     TYPE_CHECKING,
     Any,
     Callable,
     Collection,
+    List,
     Optional,
     Type,
 )
@@ -28,7 +30,7 @@
         Web3,
     )
 
-whitelist = [
+DEFAULT_ALLOWLIST = [
     "admin",
     "miner",
     "net",
@@ -87,11 +89,16 @@
 ]
 
 
-def check_if_retry_on_failure(method: RPCEndpoint) -> bool:
+def check_if_retry_on_failure(
+    method: str, allow_list: Optional[List[str]] = None
+) -> bool:
+    if allow_list is None:
+        allow_list = DEFAULT_ALLOWLIST
+
     root = method.split("_")[0]
-    if root in whitelist:
+    if root in allow_list:
         return True
-    elif method in whitelist:
+    elif method in allow_list:
         return True
     else:
         return False
@@ -102,6 +109,8 @@
     _w3: "Web3",
     errors: Collection[Type[BaseException]],
     retries: int = 5,
+    backoff_factor: float = 0.3,
+    allow_list: Optional[List[str]] = None,
 ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
     """
     Creates middleware that retries failed HTTP requests. Is a default
@@ -109,12 +118,13 @@
     """
 
     def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:
-        if check_if_retry_on_failure(method):
+        if check_if_retry_on_failure(method, allow_list):
             for i in range(retries):
                 try:
                     return make_request(method, params)
                 except tuple(errors):
                     if i < retries - 1:
+                        time.sleep(backoff_factor)
                         continue
                     else:
                         raise
@@ -133,12 +143,16 @@
     )
 
 
+# -- async -- #
+
+
 async def async_exception_retry_middleware(
     make_request: Callable[[RPCEndpoint, Any], Any],
     _async_w3: "AsyncWeb3",
     errors: Collection[Type[BaseException]],
     retries: int = 5,
     backoff_factor: float = 0.3,
+    allow_list: Optional[List[str]] = None,
 ) -> AsyncMiddlewareCoroutine:
     """
     Creates middleware that retries failed HTTP requests.
@@ -146,7 +160,7 @@
     """
 
     async def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:
-        if check_if_retry_on_failure(method):
+        if check_if_retry_on_failure(method, allow_list):
             for i in range(retries):
                 try:
                     return await make_request(method, params)

{"golden_diff": "diff --git a/web3/middleware/exception_retry_request.py b/web3/middleware/exception_retry_request.py\n--- a/web3/middleware/exception_retry_request.py\n+++ b/web3/middleware/exception_retry_request.py\n@@ -1,9 +1,11 @@\n import asyncio\n+import time\n from typing import (\n     TYPE_CHECKING,\n     Any,\n     Callable,\n     Collection,\n+    List,\n     Optional,\n     Type,\n )\n@@ -28,7 +30,7 @@\n         Web3,\n     )\n \n-whitelist = [\n+DEFAULT_ALLOWLIST = [\n     \"admin\",\n     \"miner\",\n     \"net\",\n@@ -87,11 +89,16 @@\n ]\n \n \n-def check_if_retry_on_failure(method: RPCEndpoint) -> bool:\n+def check_if_retry_on_failure(\n+    method: str, allow_list: Optional[List[str]] = None\n+) -> bool:\n+    if allow_list is None:\n+        allow_list = DEFAULT_ALLOWLIST\n+\n     root = method.split(\"_\")[0]\n-    if root in whitelist:\n+    if root in allow_list:\n         return True\n-    elif method in whitelist:\n+    elif method in allow_list:\n         return True\n     else:\n         return False\n@@ -102,6 +109,8 @@\n     _w3: \"Web3\",\n     errors: Collection[Type[BaseException]],\n     retries: int = 5,\n+    backoff_factor: float = 0.3,\n+    allow_list: Optional[List[str]] = None,\n ) -> Callable[[RPCEndpoint, Any], RPCResponse]:\n     \"\"\"\n     Creates middleware that retries failed HTTP requests. Is a default\n@@ -109,12 +118,13 @@\n     \"\"\"\n \n     def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:\n-        if check_if_retry_on_failure(method):\n+        if check_if_retry_on_failure(method, allow_list):\n             for i in range(retries):\n                 try:\n                     return make_request(method, params)\n                 except tuple(errors):\n                     if i < retries - 1:\n+                        time.sleep(backoff_factor)\n                         continue\n                     else:\n                         raise\n@@ -133,12 +143,16 @@\n     )\n \n \n+# -- async -- #\n+\n+\n async def async_exception_retry_middleware(\n     make_request: Callable[[RPCEndpoint, Any], Any],\n     _async_w3: \"AsyncWeb3\",\n     errors: Collection[Type[BaseException]],\n     retries: int = 5,\n     backoff_factor: float = 0.3,\n+    allow_list: Optional[List[str]] = None,\n ) -> AsyncMiddlewareCoroutine:\n     \"\"\"\n     Creates middleware that retries failed HTTP requests.\n@@ -146,7 +160,7 @@\n     \"\"\"\n \n     async def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:\n-        if check_if_retry_on_failure(method):\n+        if check_if_retry_on_failure(method, allow_list):\n             for i in range(retries):\n                 try:\n                     return await make_request(method, params)\n", "issue": "http_retry_request_middleware needs to be more graceful and sleep a bit\n* Version: 5\r\n* Python: 3.x\r\n\r\n### What was wrong?\r\n\r\nThe current `http_retry_request_middleware` is not graceful and configurable enough.\r\n\r\n### How can it be fixed?\r\n\r\nThe current `exception_retry_middleware`, which is used by `http_retry_request_middleware`, looks like:\r\n\r\n```python\r\ndef exception_retry_middleware(\r\n    make_request: Callable[[RPCEndpoint, Any], RPCResponse],\r\n    web3: \"Web3\",\r\n    errors: Collection[Type[BaseException]],\r\n    retries: int = 5,\r\n) -> Callable[[RPCEndpoint, Any], RPCResponse]:\r\n    \"\"\"\r\n    Creates middleware that retries failed HTTP requests. Is a default\r\n    middleware for HTTPProvider.\r\n    \"\"\"\r\n    def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:\r\n        if check_if_retry_on_failure(method):\r\n            for i in range(retries):\r\n                try:\r\n                    return make_request(method, params)\r\n                # https://github.com/python/mypy/issues/5349\r\n                except errors:  # type: ignore\r\n                    if i < retries - 1:\r\n                        continue\r\n                    else:\r\n                        raise\r\n            return None\r\n        else:\r\n            return make_request(method, params)\r\n    return middleware\r\n```\r\n\r\nPossible usual retryable error conditions include \r\n\r\n* Temporary TCP/IP routing errors\r\n\r\n* Network card reset\r\n\r\n* Firewall reset\r\n\r\n* JSON-RPC server restart\r\n\r\nUnder normal conditions, any of these error conditions may last from fractions of seconds up to a minute. However the current `exception_retry_middleware` has too tight loop without a sleep. It simply bombs the network interface as fast as it can, without backing off.\r\n\r\nI recommend making `exception_retry_middleware`, and `http_retry_request_middleware`, configurable so that the library user can pass parameters for timeouts and retry counts.\r\n\r\nOutside the scope of this issue is to make this to work with WebSocket connections and rebuild the provider on-demand. [web3.js does this.](https://github.com/ChainSafe/web3.js/releases/tag/v1.2.8). \r\n\r\n\r\n\n", "before_files": [{"content": "import asyncio\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Callable,\n    Collection,\n    Optional,\n    Type,\n)\n\nimport aiohttp\nfrom requests.exceptions import (\n    ConnectionError,\n    HTTPError,\n    Timeout,\n    TooManyRedirects,\n)\n\nfrom web3.types import (\n    AsyncMiddlewareCoroutine,\n    RPCEndpoint,\n    RPCResponse,\n)\n\nif TYPE_CHECKING:\n    from web3 import (  # noqa: F401\n        AsyncWeb3,\n        Web3,\n    )\n\nwhitelist = [\n    \"admin\",\n    \"miner\",\n    \"net\",\n    \"txpool\",\n    \"testing\",\n    \"evm\",\n    \"eth_protocolVersion\",\n    \"eth_syncing\",\n    \"eth_coinbase\",\n    \"eth_mining\",\n    \"eth_hashrate\",\n    \"eth_chainId\",\n    \"eth_gasPrice\",\n    \"eth_accounts\",\n    \"eth_blockNumber\",\n    \"eth_getBalance\",\n    \"eth_getStorageAt\",\n    \"eth_getProof\",\n    \"eth_getCode\",\n    \"eth_getBlockByNumber\",\n    \"eth_getBlockByHash\",\n    \"eth_getBlockTransactionCountByNumber\",\n    \"eth_getBlockTransactionCountByHash\",\n    \"eth_getUncleCountByBlockNumber\",\n    \"eth_getUncleCountByBlockHash\",\n    \"eth_getTransactionByHash\",\n    \"eth_getTransactionByBlockHashAndIndex\",\n    \"eth_getTransactionByBlockNumberAndIndex\",\n    \"eth_getTransactionReceipt\",\n    \"eth_getTransactionCount\",\n    \"eth_getRawTransactionByHash\",\n    \"eth_call\",\n    \"eth_estimateGas\",\n    \"eth_maxPriorityFeePerGas\",\n    \"eth_newBlockFilter\",\n    \"eth_newPendingTransactionFilter\",\n    \"eth_newFilter\",\n    \"eth_getFilterChanges\",\n    \"eth_getFilterLogs\",\n    \"eth_getLogs\",\n    \"eth_uninstallFilter\",\n    \"eth_getCompilers\",\n    \"eth_getWork\",\n    \"eth_sign\",\n    \"eth_signTypedData\",\n    \"eth_sendRawTransaction\",\n    \"personal_importRawKey\",\n    \"personal_newAccount\",\n    \"personal_listAccounts\",\n    \"personal_listWallets\",\n    \"personal_lockAccount\",\n    \"personal_unlockAccount\",\n    \"personal_ecRecover\",\n    \"personal_sign\",\n    \"personal_signTypedData\",\n]\n\n\ndef check_if_retry_on_failure(method: RPCEndpoint) -> bool:\n    root = method.split(\"_\")[0]\n    if root in whitelist:\n        return True\n    elif method in whitelist:\n        return True\n    else:\n        return False\n\n\ndef exception_retry_middleware(\n    make_request: Callable[[RPCEndpoint, Any], RPCResponse],\n    _w3: \"Web3\",\n    errors: Collection[Type[BaseException]],\n    retries: int = 5,\n) -> Callable[[RPCEndpoint, Any], RPCResponse]:\n    \"\"\"\n    Creates middleware that retries failed HTTP requests. Is a default\n    middleware for HTTPProvider.\n    \"\"\"\n\n    def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:\n        if check_if_retry_on_failure(method):\n            for i in range(retries):\n                try:\n                    return make_request(method, params)\n                except tuple(errors):\n                    if i < retries - 1:\n                        continue\n                    else:\n                        raise\n            return None\n        else:\n            return make_request(method, params)\n\n    return middleware\n\n\ndef http_retry_request_middleware(\n    make_request: Callable[[RPCEndpoint, Any], Any], w3: \"Web3\"\n) -> Callable[[RPCEndpoint, Any], Any]:\n    return exception_retry_middleware(\n        make_request, w3, (ConnectionError, HTTPError, Timeout, TooManyRedirects)\n    )\n\n\nasync def async_exception_retry_middleware(\n    make_request: Callable[[RPCEndpoint, Any], Any],\n    _async_w3: \"AsyncWeb3\",\n    errors: Collection[Type[BaseException]],\n    retries: int = 5,\n    backoff_factor: float = 0.3,\n) -> AsyncMiddlewareCoroutine:\n    \"\"\"\n    Creates middleware that retries failed HTTP requests.\n    Is a default middleware for AsyncHTTPProvider.\n    \"\"\"\n\n    async def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:\n        if check_if_retry_on_failure(method):\n            for i in range(retries):\n                try:\n                    return await make_request(method, params)\n                except tuple(errors):\n                    if i < retries - 1:\n                        await asyncio.sleep(backoff_factor)\n                        continue\n                    else:\n                        raise\n            return None\n        else:\n            return await make_request(method, params)\n\n    return middleware\n\n\nasync def async_http_retry_request_middleware(\n    make_request: Callable[[RPCEndpoint, Any], Any], async_w3: \"AsyncWeb3\"\n) -> Callable[[RPCEndpoint, Any], Any]:\n    return await async_exception_retry_middleware(\n        make_request,\n        async_w3,\n        (TimeoutError, aiohttp.ClientError),\n    )\n", "path": "web3/middleware/exception_retry_request.py"}], "after_files": [{"content": "import asyncio\nimport time\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Callable,\n    Collection,\n    List,\n    Optional,\n    Type,\n)\n\nimport aiohttp\nfrom requests.exceptions import (\n    ConnectionError,\n    HTTPError,\n    Timeout,\n    TooManyRedirects,\n)\n\nfrom web3.types import (\n    AsyncMiddlewareCoroutine,\n    RPCEndpoint,\n    RPCResponse,\n)\n\nif TYPE_CHECKING:\n    from web3 import (  # noqa: F401\n        AsyncWeb3,\n        Web3,\n    )\n\nDEFAULT_ALLOWLIST = [\n    \"admin\",\n    \"miner\",\n    \"net\",\n    \"txpool\",\n    \"testing\",\n    \"evm\",\n    \"eth_protocolVersion\",\n    \"eth_syncing\",\n    \"eth_coinbase\",\n    \"eth_mining\",\n    \"eth_hashrate\",\n    \"eth_chainId\",\n    \"eth_gasPrice\",\n    \"eth_accounts\",\n    \"eth_blockNumber\",\n    \"eth_getBalance\",\n    \"eth_getStorageAt\",\n    \"eth_getProof\",\n    \"eth_getCode\",\n    \"eth_getBlockByNumber\",\n    \"eth_getBlockByHash\",\n    \"eth_getBlockTransactionCountByNumber\",\n    \"eth_getBlockTransactionCountByHash\",\n    \"eth_getUncleCountByBlockNumber\",\n    \"eth_getUncleCountByBlockHash\",\n    \"eth_getTransactionByHash\",\n    \"eth_getTransactionByBlockHashAndIndex\",\n    \"eth_getTransactionByBlockNumberAndIndex\",\n    \"eth_getTransactionReceipt\",\n    \"eth_getTransactionCount\",\n    \"eth_getRawTransactionByHash\",\n    \"eth_call\",\n    \"eth_estimateGas\",\n    \"eth_maxPriorityFeePerGas\",\n    \"eth_newBlockFilter\",\n    \"eth_newPendingTransactionFilter\",\n    \"eth_newFilter\",\n    \"eth_getFilterChanges\",\n    \"eth_getFilterLogs\",\n    \"eth_getLogs\",\n    \"eth_uninstallFilter\",\n    \"eth_getCompilers\",\n    \"eth_getWork\",\n    \"eth_sign\",\n    \"eth_signTypedData\",\n    \"eth_sendRawTransaction\",\n    \"personal_importRawKey\",\n    \"personal_newAccount\",\n    \"personal_listAccounts\",\n    \"personal_listWallets\",\n    \"personal_lockAccount\",\n    \"personal_unlockAccount\",\n    \"personal_ecRecover\",\n    \"personal_sign\",\n    \"personal_signTypedData\",\n]\n\n\ndef check_if_retry_on_failure(\n    method: str, allow_list: Optional[List[str]] = None\n) -> bool:\n    if allow_list is None:\n        allow_list = DEFAULT_ALLOWLIST\n\n    root = method.split(\"_\")[0]\n    if root in allow_list:\n        return True\n    elif method in allow_list:\n        return True\n    else:\n        return False\n\n\ndef exception_retry_middleware(\n    make_request: Callable[[RPCEndpoint, Any], RPCResponse],\n    _w3: \"Web3\",\n    errors: Collection[Type[BaseException]],\n    retries: int = 5,\n    backoff_factor: float = 0.3,\n    allow_list: Optional[List[str]] = None,\n) -> Callable[[RPCEndpoint, Any], RPCResponse]:\n    \"\"\"\n    Creates middleware that retries failed HTTP requests. Is a default\n    middleware for HTTPProvider.\n    \"\"\"\n\n    def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:\n        if check_if_retry_on_failure(method, allow_list):\n            for i in range(retries):\n                try:\n                    return make_request(method, params)\n                except tuple(errors):\n                    if i < retries - 1:\n                        time.sleep(backoff_factor)\n                        continue\n                    else:\n                        raise\n            return None\n        else:\n            return make_request(method, params)\n\n    return middleware\n\n\ndef http_retry_request_middleware(\n    make_request: Callable[[RPCEndpoint, Any], Any], w3: \"Web3\"\n) -> Callable[[RPCEndpoint, Any], Any]:\n    return exception_retry_middleware(\n        make_request, w3, (ConnectionError, HTTPError, Timeout, TooManyRedirects)\n    )\n\n\n# -- async -- #\n\n\nasync def async_exception_retry_middleware(\n    make_request: Callable[[RPCEndpoint, Any], Any],\n    _async_w3: \"AsyncWeb3\",\n    errors: Collection[Type[BaseException]],\n    retries: int = 5,\n    backoff_factor: float = 0.3,\n    allow_list: Optional[List[str]] = None,\n) -> AsyncMiddlewareCoroutine:\n    \"\"\"\n    Creates middleware that retries failed HTTP requests.\n    Is a default middleware for AsyncHTTPProvider.\n    \"\"\"\n\n    async def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:\n        if check_if_retry_on_failure(method, allow_list):\n            for i in range(retries):\n                try:\n                    return await make_request(method, params)\n                except tuple(errors):\n                    if i < retries - 1:\n                        await asyncio.sleep(backoff_factor)\n                        continue\n                    else:\n                        raise\n            return None\n        else:\n            return await make_request(method, params)\n\n    return middleware\n\n\nasync def async_http_retry_request_middleware(\n    make_request: Callable[[RPCEndpoint, Any], Any], async_w3: \"AsyncWeb3\"\n) -> Callable[[RPCEndpoint, Any], Any]:\n    return await async_exception_retry_middleware(\n        make_request,\n        async_w3,\n        (TimeoutError, aiohttp.ClientError),\n    )\n", "path": "web3/middleware/exception_retry_request.py"}]}