from django.conf import settings
from web3 import Web3, RPCProvider

from .singleton import Singleton


class Web3Service(metaclass=Singleton):
    """Creates a `web3` instance based on the given `RPCProvider`."""

    def __init__(self, *args, **kwargs):
        """Initializes the `web3` object.

        Args:
            rpc_provider (:obj:`Provider`, optional): Valid `web3` Provider instance.
        """
        rpc_provider = kwargs.pop('rpc_provider', None)
        if not rpc_provider:
            rpc_provider = RPCProvider(
                host=settings.ETHEREUM_NODE_HOST,
                port=settings.ETHEREUM_NODE_PORT,
                ssl=settings.ETHEREUM_NODE_SSL,
                timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
            )
        self.web3 = Web3(rpc_provider)
        super(Web3Service, self).__init__()

from django.conf import settings
from web3 import Web3
try:
    from web3 import HTTPProvider
    RPCProvider = None
except ImportError:
    from web3 import RPCProvider
    HTTPProvider = None

from .singleton import Singleton


class Web3Service(metaclass=Singleton):
    """Creates a `web3` instance based on the given `RPCProvider`."""

    def __init__(self, *args, **kwargs):
        """Initializes the `web3` object.

        Args:
            rpc_provider (:obj:`Provider`, optional): Valid `web3` Provider instance.
        """
        rpc_provider = kwargs.pop('rpc_provider', None)
        if not rpc_provider:
            if HTTPProvider is not None:
                uri = "{scheme}://{host}:{port}".format(
                    host=settings.ETHEREUM_NODE_HOST,
                    port=settings.ETHEREUM_NODE_PORT,
                    scheme="https" if settings.ETHEREUM_NODE_SSL else "http",
                )
                rpc_provider = HTTPProvider(
                    endpoint_uri=uri,
                    timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
                )
            elif RPCProvider is not None:
                rpc_provider = RPCProvider(
                    host=settings.ETHEREUM_NODE_HOST,
                    port=settings.ETHEREUM_NODE_PORT,
                    ssl=settings.ETHEREUM_NODE_SSL,
                    timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
                )
            else:
                raise ValueError("Cannot instantiate any RPC provider")
        self.web3 = Web3(rpc_provider)
        super(Web3Service, self).__init__()

Support for Web3 4.0beta: HTTPProvider
Support for Web3 4.0beta: HTTPProvider

In Web3 3.16 the class is called RPCProvider, but in the
upcoming 4.0 series it's replaced with HTTPProvider.

This commit ensures both versions are supported in this regard.

  from django.conf import settings
+ from web3 import Web3
+ try:
+     from web3 import HTTPProvider
+     RPCProvider = None
+ except ImportError:
- from web3 import Web3, RPCProvider
+     from web3 import RPCProvider
+     HTTPProvider = None
  
  from .singleton import Singleton
  
  
  class Web3Service(metaclass=Singleton):
      """Creates a `web3` instance based on the given `RPCProvider`."""
  
      def __init__(self, *args, **kwargs):
          """Initializes the `web3` object.
  
          Args:
              rpc_provider (:obj:`Provider`, optional): Valid `web3` Provider instance.
          """
          rpc_provider = kwargs.pop('rpc_provider', None)
          if not rpc_provider:
-             rpc_provider = RPCProvider(
+             if HTTPProvider is not None:
+                 uri = "{scheme}://{host}:{port}".format(
-                 host=settings.ETHEREUM_NODE_HOST,
+                     host=settings.ETHEREUM_NODE_HOST,
-                 port=settings.ETHEREUM_NODE_PORT,
+                     port=settings.ETHEREUM_NODE_PORT,
-                 ssl=settings.ETHEREUM_NODE_SSL,
+                     scheme="https" if settings.ETHEREUM_NODE_SSL else "http",
+                 )
+                 rpc_provider = HTTPProvider(
+                     endpoint_uri=uri,
-                 timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
+                     timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
-             )
+                 )
+             elif RPCProvider is not None:
+                 rpc_provider = RPCProvider(
+                     host=settings.ETHEREUM_NODE_HOST,
+                     port=settings.ETHEREUM_NODE_PORT,
+                     ssl=settings.ETHEREUM_NODE_SSL,
+                     timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
+                 )
+             else:
+                 raise ValueError("Cannot instantiate any RPC provider")
          self.web3 = Web3(rpc_provider)
          super(Web3Service, self).__init__()
  
Support for Web3 4.0beta: HTTPProvider
## Code Before:
from django.conf import settings
from web3 import Web3, RPCProvider

from .singleton import Singleton


class Web3Service(metaclass=Singleton):
    """Creates a `web3` instance based on the given `RPCProvider`."""

    def __init__(self, *args, **kwargs):
        """Initializes the `web3` object.

        Args:
            rpc_provider (:obj:`Provider`, optional): Valid `web3` Provider instance.
        """
        rpc_provider = kwargs.pop('rpc_provider', None)
        if not rpc_provider:
            rpc_provider = RPCProvider(
                host=settings.ETHEREUM_NODE_HOST,
                port=settings.ETHEREUM_NODE_PORT,
                ssl=settings.ETHEREUM_NODE_SSL,
                timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
            )
        self.web3 = Web3(rpc_provider)
        super(Web3Service, self).__init__()

## Instruction:
Support for Web3 4.0beta: HTTPProvider
## Code After:
from django.conf import settings
from web3 import Web3
try:
    from web3 import HTTPProvider
    RPCProvider = None
except ImportError:
    from web3 import RPCProvider
    HTTPProvider = None

from .singleton import Singleton


class Web3Service(metaclass=Singleton):
    """Creates a `web3` instance based on the given `RPCProvider`."""

    def __init__(self, *args, **kwargs):
        """Initializes the `web3` object.

        Args:
            rpc_provider (:obj:`Provider`, optional): Valid `web3` Provider instance.
        """
        rpc_provider = kwargs.pop('rpc_provider', None)
        if not rpc_provider:
            if HTTPProvider is not None:
                uri = "{scheme}://{host}:{port}".format(
                    host=settings.ETHEREUM_NODE_HOST,
                    port=settings.ETHEREUM_NODE_PORT,
                    scheme="https" if settings.ETHEREUM_NODE_SSL else "http",
                )
                rpc_provider = HTTPProvider(
                    endpoint_uri=uri,
                    timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
                )
            elif RPCProvider is not None:
                rpc_provider = RPCProvider(
                    host=settings.ETHEREUM_NODE_HOST,
                    port=settings.ETHEREUM_NODE_PORT,
                    ssl=settings.ETHEREUM_NODE_SSL,
                    timeout=getattr(settings, "ETHEREUM_NODE_TIMEOUT", 10)
                )
            else:
                raise ValueError("Cannot instantiate any RPC provider")
        self.web3 = Web3(rpc_provider)
        super(Web3Service, self).__init__()
