3

我正在尝试在项目中使用 AsyncHTTPProvider,这是我的测试代码:

import asyncio
from web3 import Web3
import asyncio

async def main():
    w3 = Web3(Web3.AsyncHTTPProvider("http://127.0.0.1:8545"))
    coinbase = await w3.eth.coinbase
    print(coinbase)

if __name__ == "__main__":
    asyncio.run(main())

我将 ganache-cli 用于本地提供商。

我在网上找不到任何使用 AsyncHTTPProvider 的人的示例,即使在 web3py github 中我也找不到我能理解的示例(阅读大型库的拉取请求非常乏味)

当我运行此代码时,我收到以下错误:

Traceback (most recent call last):
  File "test.py", line 11, in <module>
    asyncio.run(main())
  File "C:\Program Files\Python37\lib\asyncio\runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "C:\Program Files\Python37\lib\asyncio\base_events.py", line 587, in run_until_complete
    return future.result()
  File "test.py", line 7, in main
    coinbase = await w3.eth.coinbase
  File "D:\Name\Ethereum\FirstProject\env\lib\site-packages\web3\eth.py", line 282, in coinbase
    return self.get_coinbase()
  File "D:\Name\Ethereum\ArbitrageMax\env\lib\site-packages\web3\module.py", line 57, in caller
    result = w3.manager.request_blocking(method_str, params, error_formatters)
  File "D:\Name\Ethereum\FirstProject\env\lib\site-packages\web3\manager.py", line 154, in request_blocking
    response = self._make_request(method, params)
  File "D:\Name\Ethereum\FirstProject\env\lib\site-packages\web3\manager.py", line 133, in _make_request
    return request_func(method, params)
TypeError: 'coroutine' object is not callable
sys:1: RuntimeWarning: coroutine 'AsyncBaseProvider.request_func' was never awaited

查看错误日志,尽管使用了 AsyncHTTPProvider,但仍在使用“w3.manager.request_blocking”,这表明它仍在使用同步 api

我运行了以下代码以确保 web3 对象的提供程序实际上是异步的:

import asyncio
from web3 import Web3
import asyncio

async def main():
    w3 = Web3(Web3.AsyncHTTPProvider("http://127.0.0.1:8545"))
    print(type(w3.provider))
    # coinbase = await w3.eth.coinbase
    # print(coinbase)

if __name__ == "__main__":
    asyncio.run(main())

输出:

<class 'web3.providers.async_rpc.AsyncHTTPProvider'>

查看 web3py 存储库的测试,似乎我做的一切都是正确的,因为测试与 w3.eth 异步 api 交互的方式与我尝试的方式相同:

class AsyncEthModuleTest:    
    ... # other tests

    # test of get balance which involves awaiting coinbase
    @pytest.mark.asyncio
    async def test_eth_get_balance(self, async_w3: "Web3") -> None:
        coinbase = await async_w3.eth.coinbase  # type: ignore

        with pytest.raises(InvalidAddress):
            await async_w3.eth.get_balance(  # type: ignore
                ChecksumAddress(HexAddress(HexStr(coinbase.lower())))
            )

        balance = await async_w3.eth.get_balance(coinbase)  # type: ignore

        assert is_integer(balance)
        assert balance >= 0

链接到添加测试的拉取请求(问题#2056)

唯一的问题是我无法弄清楚“async_w3”对象的声明在哪里

我开始我的项目的 web3 版本是:web3==5.20.1 我更新到最新版本,看看它是否能解决问题(web3==5.23.0),不,仍然是同样的旧错误

4

1 回答 1

7

我在 web3 github 上得到了答案:

这是创建提供程序的正确语法(虽然我还没有测试过)

from web3 import Web3
from web3.eth import AsyncEth

w3 = Web3(Web3.AsyncHTTPProvider("http://127.0.0.1:8545"), modules={'eth': (AsyncEth,)}, middlewares=[])

如果将来有人发现这个问题:请记住,到目前为止,异步是一项正在进行的工作。将来可能会发生变化,您需要检查文档

支持的中间件

于 2021-08-29T11:00:23.807 回答