The provider is how web3 talks to the blockchain. Providers take JSON-RPC requests and return the response. This is normally done by submitting the request to an HTTP or IPC socket based server.
Note
web3.py supports one provider per instance. If you have an advanced use case that requires multiple providers, create and configure a new web3 instance per connection.
If you are already happily connected to your Ethereum node, then you can skip the rest of the Providers section.
Most nodes have a variety of ways to connect to them. If you have not decided what kind of node to use, head on over to choosing_node
The most common ways to connect to your node are:
- IPC (uses local filesystem: fastest and most secure)
- Websockets (works remotely, faster than HTTP)
- HTTP (more nodes support it)
If you're not sure how to decide, choose this way:
- If you have the option of running web3.py on the same machine as the node, choose IPC.
- If you must connect to a node on a different computer, use Websockets.
- If your node does not support Websockets, use HTTP.
Most nodes have a way of "turning off" connection options. We recommend turning off all connection options that you are not using. This provides a safer setup: it reduces the number of ways that malicious hackers can try to steal your ether.
Once you have decided how to connect, you specify the details using a Provider. Providers are web3.py classes that are configured for the kind of connection you want.
See:
~web3.providers.ipc.IPCProvider
~web3.providers.websocket.WebsocketProvider
~web3.providers.websocket.WebsocketProviderV2
~web3.providers.rpc.HTTPProvider
~web3.providers.async_rpc.AsyncHTTPProvider
Once you have configured your provider, for example:
from web3 import Web3
my_provider = Web3.IPCProvider('/my/node/ipc/path')
Then you are ready to initialize your Web3 instance, like so:
w3 = Web3(my_provider)
Finally, you are ready to get started with web3.py<first_w3_use>
.
Alternatively, you can set the environment variable WEB3_PROVIDER_URI
before starting your script, and web3 will look for that provider first.
Valid formats for this environment variable are:
file:///path/to/node/rpc-json/file.ipc
http://192.168.1.2:8545
https://node.ontheweb.com
ws://127.0.0.1:8546
To connect to a geth --dev
Proof of Authority instance with defaults:
>>> from web3.auto.gethdev import w3
# confirm that the connection succeeded
>>> w3.is_connected()
True
Web3 ships with the following providers which are appropriate for connecting to local and remote JSON-RPC servers.
Note
WebsocketProviderV2
is currently in beta and our goal is to fully replace WebsocketProvider
with WebsocketProviderV2
in the next major release of web3.py.
Warning
This provider is still in beta. However, it is being actively developed and supported and is expected to be stable in the next major version of web3.py (v7).
The AsyncWeb3
class may be used as a context manager, utilizing the async with
syntax, when connecting via persistent_websocket()
using the WebsocketProviderV2
. This will automatically close the connection when the context manager exits and is the recommended way to initiate a persistent connection to the websocket provider. A similar example, using the websockets
connection as an asynchronous context manager, can be found in the websockets connection docs.
>>> import asyncio
>>> from web3 import AsyncWeb3
>>> from web3.providers import WebsocketProviderV2
>>> LOG = True # toggle debug logging
>>> if LOG:
... import logging
... logger = logging.getLogger("web3.providers.WebsocketProviderV2")
... logger.setLevel(logging.DEBUG)
... logger.addHandler(logging.StreamHandler())
>>> async def ws_v2_subscription_context_manager_example():
... async with AsyncWeb3.persistent_websocket(
... WebsocketProviderV2(f"ws://127.0.0.1:8546")
... ) as w3:
... # subscribe to new block headers
... subscription_id = await w3.eth.subscribe("newHeads")
...
... async for response in w3.ws.listen_to_websocket():
... print(f"{response}\n")
... # handle responses here
...
... if some_condition:
... # unsubscribe from new block headers and break out of
... # iterator
... await w3.eth.unsubscribe(subscription_id)
... break
...
... # still an open connection, make any other requests and get
... # responses via send / receive
... latest_block = await w3.eth.get_block("latest")
... print(f"Latest block: {latest_block}")
...
... # the connection closes automatically when exiting the context
... # manager (the `async with` block)
>>> asyncio.run(ws_v2_subscription_context_manager_example())
The AsyncWeb3
class may also be used as an asynchronous iterator, utilizing the async for
syntax, when connecting via persistent_websocket()
using the WebsocketProviderV2
. This may be used to set up an indefinite websocket connection and reconnect automatically if the connection is lost. A similar example, using the websockets
connection as an asynchronous iterator, can be found in the websockets connection docs.
>>> import asyncio
>>> from web3 import AsyncWeb3
>>> from web3.providers import WebsocketProviderV2
>>> import websockets
>>> async def ws_v2_subscription_iterator_example():
... async for w3 in AsyncWeb3.persistent_websocket(
... WebsocketProviderV2(f"ws://127.0.0.1:8546")
... ):
... try:
... ...
... except websockets.ConnectionClosed:
... continue
>>> asyncio.run(ws_v2_subscription_iterator_example())
If neither of the two init patterns above work for your application, the __await__()
method is defined on the persistent_websocket()
connection in a manner that awaits connecting to the websocket. You may also choose to instantiate and connect via the provider in separate lines. Both of these examples are shown below.
>>> async def ws_v2_alternate_init_example_1():
... # awaiting the persistent connection itself will connect to the websocket
... w3 = await AsyncWeb3.persistent_websocket(WebsocketProviderV2(f"ws://127.0.0.1:8546"))
...
... # some code here
...
... # manual cleanup
... await w3.provider.disconnect()
>>> async def ws_v2_alternate_init_example_2():
... # instantiation and connection via the provider as separate lines
... w3 = AsyncWeb3.persistent_websocket(WebsocketProviderV2(f"ws://127.0.0.1:8546"))
... await w3.provider.connect()
...
... # some code here
...
... # manual cleanup
... await w3.provider.disconnect()
>>> # run the examples:
>>> asyncio.run(ws_v2_alternate_init_example_1)
>>> asyncio.run(ws_v2_alternate_init_example_2)
The WebsocketProviderV2
class uses the ~web3.providers.websocket.request_processor.RequestProcessor
class under the hood to sync up the receiving of responses and response processing for one-to-one and one-to-many request-to-response requests. Refer to the ~web3.providers.websocket.request_processor.RequestProcessor
documentation for details.
When an AsyncWeb3
class is connected to a persistent websocket connection, via the persistent_websocket()
method, it becomes an instance of the _PersistentConnectionWeb3
class. This class has a few additional methods and attributes that are not available on the AsyncWeb3
class.
~web3.providers.auto.AutoProvider
is the default used when initializing web3.Web3
without any providers. There's rarely a reason to use it explicitly.
Warning
Experimental: This provider is experimental. There are still significant gaps in functionality. However it is being actively developed and supported.
Note
To install the needed dependencies to use EthereumTesterProvider, you can install the pip extras package that has the correct interoperable versions of the eth-tester
and py-evm
dependencies needed to do testing: e.g. pip install web3[tester]