Skip to content

Latest commit

 

History

History
502 lines (353 loc) · 19.9 KB

providers.rst

File metadata and controls

502 lines (353 loc) · 19.9 KB

Providers

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.

Choosing How to Connect to Your Node

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:

  1. IPC (uses local filesystem: fastest and most secure)
  2. Websockets (works remotely, faster than HTTP)
  3. 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>.

Provider via Environment Variable

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

Auto-initialization Provider Shortcuts

Geth dev Proof of Authority

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

Built In Providers

Web3 ships with the following providers which are appropriate for connecting to local and remote JSON-RPC servers.

HTTPProvider

IPCProvider

WebsocketProvider

Note

WebsocketProviderV2 is currently in beta and our goal is to fully replace WebsocketProvider with WebsocketProviderV2 in the next major release of web3.py.

WebsocketProviderV2 (beta)

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).

Usage

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.

_PersistentConnectionWeb3 via AsyncWeb3.persistent_websocket()

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.

Interacting with the Websocket Connection

AutoProvider

~web3.providers.auto.AutoProvider is the default used when initializing web3.Web3 without any providers. There's rarely a reason to use it explicitly.

AsyncHTTPProvider

EthereumTesterProvider

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]