1

I use:
python3.7,
web3==4.9.2,
Infura and/or own Node.
After web3 was initialized it returns isConnected() response only in first time, after that it freezes.

web3.py:

from web3 import Web3
from web3.gas_strategies.rpc import rpc_gas_price_strategy
from web3.providers.auto import load_provider_from_uri  


class Web3NotAvailableException(Exception):
    def __init__(self, rpc_url):
        self.rpc_url = rpc_url

    def __str__(self):
        return f'WEB3_RPC_URL: {self.rpc_url}'


def get_web3():
    logger.debug('Getting web3 instance')
    if hasattr(get_web3, '_web3_instance'):
        logger.warn('Here 1')
        _web3_instance = getattr(get_web3, '_web3_instance')
    else:
        logger.warn('Here 2')
        _web3_instance = Web3(load_provider_from_uri(settings.WEB3_RPC_URL))
        _web3_instance.eth.setGasPriceStrategy(rpc_gas_price_strategy)
        setattr(get_web3, '_web3_instance', _web3_instance)

    logger.warn('Before isConnected()')
    if not _web3_instance.isConnected():
        logger.warn('Here 3')
        _web3_instance = None
        raise Web3NotAvailableException(settings.WEB3_RPC_URL)

    logger.warn('Finish')
    return _web3_instance

logs:

DEBUG 07/06/2021 16:30:13 | [ web3.py:46 ] Getting web3 instance
WARNING 07/06/2021 16:30:13 | [ web3.py:51 ] Here 2
WARNING 07/06/2021 16:30:13 | [ web3.py:56 ] Before isConnected()
WARNING 07/06/2021 16:30:13 | [ web3.py:62 ] Finish
DEBUG 07/06/2021 16:30:15 | [ web3.py:46 ] Getting web3 instance
WARNING 07/06/2021 16:30:15 | [ web3.py:48 ] Here 1
WARNING 07/06/2021 16:30:15 | [ web3.py:56 ] Before isConnected()

and after that docker container freezes and happen nothing. Although celery should pushes tasks every 30 sec.

But if i use ganache locally everything works.

DEBUG 07/06/2021 16:59:37 | [ web3.py:46 ] Getting web3 instance
WARNING 07/06/2021 16:59:37 | [ web3.py:51 ] Here 2
WARNING 07/06/2021 16:59:37 | [ web3.py:56 ] Before isConnected()
WARNING 07/06/2021 16:59:37 | [ web3.py:62 ] Finish
################################################
DEBUG 07/06/2021 17:00:11 | [ web3.py:46 ] Getting web3 instance
WARNING 07/06/2021 17:00:11 | [ web3.py:48 ] Here 1
WARNING 07/06/2021 17:00:11 | [ web3.py:56 ] Before isConnected()
WARNING 07/06/2021 17:00:11 | [ web3.py:62 ] Finish
################################################
DEBUG 07/06/2021 17:00:41 | [ web3.py:46 ] Getting web3 instance
WARNING 07/06/2021 17:00:41 | [ web3.py:48 ] Here 1
WARNING 07/06/2021 17:00:41 | [ web3.py:56 ] Before isConnected()
WARNING 07/06/2021 17:00:41 | [ web3.py:62 ] Finish

What wrong ?

6
  • 1
    Someone had similar problems and it was related to Celery and async issues. They had to switch to gevent or similar to solve it. I am just remembering this from web3.py Discord chat. Jun 7, 2021 at 19:01
  • 1
    @MikkoOhtamaa , thnx, you've just given me decision )
    – Vadim
    Jun 7, 2021 at 20:12
  • 1
    Don't forget to mark your own answer as correct. Jun 11, 2021 at 9:45
  • 1
    @MikkoOhtamaa , "You can't vote for your own post" if you about it
    – Vadim
    Jun 13, 2021 at 11:04
  • 1
    oh, sorry, now i understand, leave the link here -> meta.stackexchange.com/questions/5234/…
    – Vadim
    Jun 13, 2021 at 18:26

1 Answer 1

1

i moved web3 initialization to settings file, now it it's initialize one time and i get the web3-result already for Celery:

settings/production.py:

from web3 import Web3
from web3.gas_strategies.rpc import rpc_gas_price_strategy
from web3.providers.auto import load_provider_from_uri
from django.conf import settings

from eth_watcher.web3 import Web3NotAvailableException


##################
# different variables here
##################
 
def get_web3():
    _web3_instance = Web3(load_provider_from_uri(settings.WEB3_RPC_URL))
    _web3_instance.eth.setGasPriceStrategy(rpc_gas_price_strategy)

    if not _web3_instance.isConnected():
        _web3_instance = None
        raise Web3NotAvailableException(settings.WEB3_RPC_URL)

    return _web3_instance


W3 = get_web3() 

web3.py:

class Web3NotAvailableException(Exception):
    def __init__(self, rpc_url):
        self.rpc_url = rpc_url

    def __str__(self):
        return f'WEB3_RPC_URL: {self.rpc_url}'


def get_web3():
    return settings.W3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.