Skip to content

Commit 955e539

Browse files
committed
Clean up AsyncHTTPProvider instantiation
- Add ``is_async`` flag to base provider classes and appropriately set them to ``True`` or ``False``. - Use these flags to determine whether to load sync or async default middlewares and default modules.
1 parent cc5a9da commit 955e539

File tree

8 files changed

+115
-44
lines changed

8 files changed

+115
-44
lines changed

newsfragments/2736.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Load the ``AsyncHTTPProvider`` with default async middleware and default async modules, just as the ``HTTPProvider``.

tests/core/providers/test_async_http_provider.py

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,80 @@
44
ClientSession,
55
)
66

7+
from web3 import Web3
78
from web3._utils import (
89
request,
910
)
11+
from web3.eth import (
12+
AsyncEth,
13+
)
14+
from web3.geth import (
15+
AsyncGethAdmin,
16+
AsyncGethPersonal,
17+
AsyncGethTxPool,
18+
Geth,
19+
)
20+
from web3.middleware import (
21+
async_buffered_gas_estimate_middleware,
22+
async_gas_price_strategy_middleware,
23+
async_validation_middleware,
24+
)
25+
from web3.net import (
26+
AsyncNet,
27+
)
1028
from web3.providers.async_rpc import (
1129
AsyncHTTPProvider,
1230
)
1331

32+
URI = "http://mynode.local:8545"
33+
34+
35+
def test_no_args():
36+
provider = AsyncHTTPProvider()
37+
w3 = Web3(provider)
38+
assert w3.manager.provider == provider
39+
assert w3.manager.provider.is_async
40+
41+
42+
def test_init_kwargs():
43+
provider = AsyncHTTPProvider(endpoint_uri=URI, request_kwargs={"timeout": 60})
44+
w3 = Web3(provider)
45+
assert w3.manager.provider == provider
46+
47+
48+
def test_web3_with_async_http_provider_has_default_middlewares_and_modules() -> None:
49+
async_w3 = Web3(AsyncHTTPProvider(endpoint_uri="http://mynode.local:8545"))
50+
51+
# assert default modules
52+
53+
assert isinstance(async_w3.eth, AsyncEth)
54+
assert isinstance(async_w3.geth, Geth)
55+
assert isinstance(async_w3.async_net, AsyncNet)
56+
assert isinstance(async_w3.geth.admin, AsyncGethAdmin)
57+
assert isinstance(async_w3.geth.personal, AsyncGethPersonal)
58+
assert isinstance(async_w3.geth.txpool, AsyncGethTxPool)
59+
60+
# assert default middleware
61+
62+
# the following length check should fail and will need to be added to once more
63+
# async middlewares are added to the defaults
64+
assert len(async_w3.middleware_onion.middlewares) == 3
65+
66+
assert (
67+
async_w3.middleware_onion.get("gas_price_strategy")
68+
== async_gas_price_strategy_middleware
69+
)
70+
assert async_w3.middleware_onion.get("validation") == async_validation_middleware
71+
assert (
72+
async_w3.middleware_onion.get("gas_estimate")
73+
== async_buffered_gas_estimate_middleware
74+
)
75+
1476

1577
@pytest.mark.asyncio
1678
async def test_user_provided_session() -> None:
1779
session = ClientSession()
18-
provider = AsyncHTTPProvider(endpoint_uri="http://mynode.local:8545")
80+
provider = AsyncHTTPProvider(endpoint_uri=URI)
1981
cached_session = await provider.cache_async_session(session)
2082
assert len(request._async_session_cache) == 1
2183
assert cached_session == session

tests/core/providers/test_http_provider.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def test_no_args():
2020
provider = HTTPProvider()
2121
w3 = Web3(provider)
2222
assert w3.manager.provider == provider
23+
assert not w3.manager.provider.is_async
2324

2425

2526
def test_init_kwargs():

tests/integration/go_ethereum/test_goethereum_http.py

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,6 @@
1212
from web3._utils.module_testing.go_ethereum_personal_module import (
1313
GoEthereumAsyncPersonalModuleTest,
1414
)
15-
from web3.eth import (
16-
AsyncEth,
17-
)
18-
from web3.geth import (
19-
AsyncGethAdmin,
20-
AsyncGethPersonal,
21-
AsyncGethTxPool,
22-
Geth,
23-
)
24-
from web3.middleware import (
25-
async_buffered_gas_estimate_middleware,
26-
async_gas_price_strategy_middleware,
27-
async_validation_middleware,
28-
)
29-
from web3.net import (
30-
AsyncNet,
31-
)
3215
from web3.providers.async_rpc import (
3316
AsyncHTTPProvider,
3417
)
@@ -142,26 +125,7 @@ class TestGoEthereumTxPoolModuleTest(GoEthereumTxPoolModuleTest):
142125
@pytest_asyncio.fixture(scope="module")
143126
async def async_w3(geth_process, endpoint_uri):
144127
await wait_for_aiohttp(endpoint_uri)
145-
_w3 = Web3(
146-
AsyncHTTPProvider(endpoint_uri),
147-
middlewares=[
148-
async_buffered_gas_estimate_middleware,
149-
async_gas_price_strategy_middleware,
150-
async_validation_middleware,
151-
],
152-
modules={
153-
"eth": AsyncEth,
154-
"async_net": AsyncNet,
155-
"geth": (
156-
Geth,
157-
{
158-
"txpool": (AsyncGethTxPool,),
159-
"personal": (AsyncGethPersonal,),
160-
"admin": (AsyncGethAdmin,),
161-
},
162-
),
163-
},
164-
)
128+
_w3 = Web3(AsyncHTTPProvider(endpoint_uri))
165129
return _w3
166130

167131

web3/main.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,13 @@
7474
abi_ens_resolver,
7575
)
7676
from web3.eth import (
77+
AsyncEth,
7778
Eth,
7879
)
7980
from web3.geth import (
81+
AsyncGethAdmin,
82+
AsyncGethPersonal,
83+
AsyncGethTxPool,
8084
Geth,
8185
GethAdmin,
8286
GethMiner,
@@ -126,6 +130,21 @@
126130
from web3._utils.empty import Empty # noqa: F401
127131

128132

133+
def get_async_default_modules() -> Dict[str, Union[Type[Module], Sequence[Any]]]:
134+
return {
135+
"eth": AsyncEth,
136+
"async_net": AsyncNet,
137+
"geth": (
138+
Geth,
139+
{
140+
"admin": AsyncGethAdmin,
141+
"personal": AsyncGethPersonal,
142+
"txpool": AsyncGethTxPool,
143+
},
144+
),
145+
}
146+
147+
129148
def get_default_modules() -> Dict[str, Union[Type[Module], Sequence[Any]]]:
130149
return {
131150
"eth": Eth,
@@ -237,7 +256,10 @@ def __init__(
237256
self.codec = ABICodec(build_default_registry())
238257

239258
if modules is None:
240-
modules = get_default_modules()
259+
if provider and provider.is_async:
260+
modules = get_async_default_modules()
261+
else:
262+
modules = get_default_modules()
241263

242264
self.attach_modules(modules)
243265

web3/manager.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
)
3838
from web3.middleware import (
3939
abi_middleware,
40+
async_buffered_gas_estimate_middleware,
41+
async_gas_price_strategy_middleware,
42+
async_validation_middleware,
4043
attrdict_middleware,
4144
buffered_gas_estimate_middleware,
4245
gas_price_strategy_middleware,
@@ -49,6 +52,7 @@
4952
AutoProvider,
5053
)
5154
from web3.types import ( # noqa: F401
55+
AsyncMiddleware,
5256
Middleware,
5357
MiddlewareOnion,
5458
RPCEndpoint,
@@ -101,16 +105,19 @@ def __init__(
101105
self.w3 = w3
102106
self.pending_requests: Dict[UUID, ThreadWithReturn[RPCResponse]] = {}
103107

104-
if middlewares is None:
105-
middlewares = self.default_middlewares(w3)
106-
107-
self.middleware_onion: MiddlewareOnion = NamedElementOnion(middlewares)
108-
109108
if provider is None:
110109
self.provider = AutoProvider()
111110
else:
112111
self.provider = provider
113112

113+
if middlewares is None:
114+
if self.provider.is_async:
115+
middlewares = self.async_default_middlewares(w3)
116+
else:
117+
middlewares = self.default_middlewares(w3)
118+
119+
self.middleware_onion: MiddlewareOnion = NamedElementOnion(middlewares)
120+
114121
w3: "Web3" = None
115122
_provider = None
116123

@@ -139,6 +146,18 @@ def default_middlewares(w3: "Web3") -> List[Tuple[Middleware, str]]:
139146
(buffered_gas_estimate_middleware, "gas_estimate"),
140147
]
141148

149+
@staticmethod
150+
def async_default_middlewares(w3: "Web3") -> List[Tuple[Middleware, str]]:
151+
"""
152+
List the default middlewares for the request manager.
153+
Leaving ens unspecified will prevent the middleware from resolving names.
154+
"""
155+
return [
156+
(async_gas_price_strategy_middleware, "gas_price_strategy"),
157+
(async_validation_middleware, "validation"),
158+
(async_buffered_gas_estimate_middleware, "gas_estimate"),
159+
]
160+
142161
#
143162
# Provider requests and response
144163
#

web3/providers/async_base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class AsyncBaseProvider:
3939
None,
4040
)
4141

42+
is_async = True
4243
global_ccip_read_enabled: bool = True
4344
ccip_read_max_redirects: int = 4
4445

web3/providers/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class BaseProvider:
3838
None,
3939
)
4040

41+
is_async = False
4142
global_ccip_read_enabled: bool = True
4243
ccip_read_max_redirects: int = 4
4344

0 commit comments

Comments
 (0)