From a9705e173be6fdd87d14da9c5b44167413acfb41 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 23 Oct 2018 12:05:13 -0700 Subject: [PATCH 1/3] Support Ropsten on Infura --- web3/auto/infura.py | 24 --------------------- web3/auto/infura/__init__.py | 13 ++++++++++++ web3/auto/infura/endpoints.py | 39 +++++++++++++++++++++++++++++++++++ web3/auto/infura/ropsten.py | 13 ++++++++++++ web3/providers/auto.py | 4 ++++ 5 files changed, 69 insertions(+), 24 deletions(-) delete mode 100644 web3/auto/infura.py create mode 100644 web3/auto/infura/__init__.py create mode 100644 web3/auto/infura/endpoints.py create mode 100644 web3/auto/infura/ropsten.py diff --git a/web3/auto/infura.py b/web3/auto/infura.py deleted file mode 100644 index 1e85988d46..0000000000 --- a/web3/auto/infura.py +++ /dev/null @@ -1,24 +0,0 @@ -import logging -import os - -from web3 import ( - HTTPProvider, - Web3, -) - -INFURA_MAINNET_BASE_URL = 'https://mainnet.infura.io' - - -def load_infura_url(): - key = os.environ.get('INFURA_API_KEY', '') - if key == '': - logging.getLogger('web3.auto.infura').warning( - "No Infura API Key found. Add environment variable INFURA_API_KEY to ensure continued " - "API access. New keys are available at https://infura.io/signup" - ) - return INFURA_MAINNET_BASE_URL - else: - return "%s/%s" % (INFURA_MAINNET_BASE_URL, key) - - -w3 = Web3(HTTPProvider(load_infura_url())) diff --git a/web3/auto/infura/__init__.py b/web3/auto/infura/__init__.py new file mode 100644 index 0000000000..aa29978adb --- /dev/null +++ b/web3/auto/infura/__init__.py @@ -0,0 +1,13 @@ +from web3 import Web3 +from web3.providers.auto import ( + load_provider_from_uri, +) + +from .endpoints import ( + INFURA_MAINNET_DOMAIN, + build_infura_url, +) + +_infura_url = build_infura_url(INFURA_MAINNET_DOMAIN) + +w3 = Web3(load_provider_from_uri(_infura_url)) diff --git a/web3/auto/infura/endpoints.py b/web3/auto/infura/endpoints.py new file mode 100644 index 0000000000..7840cfa6d5 --- /dev/null +++ b/web3/auto/infura/endpoints.py @@ -0,0 +1,39 @@ +import logging +import os + +from eth_utils import ( + ValidationError, +) + +INFURA_MAINNET_DOMAIN = 'mainnet.infura.io' +INFURA_ROPSTEN_DOMAIN = 'ropsten.infura.io' + +WEBSOCKET_SCHEME = 'wss' +HTTP_SCHEME = 'https' + + +def load_api_key(): + # at web3py v5, drop old variable name INFURA_API_KEY + key = os.environ.get( + 'WEB3_INFURA_API_KEY', + os.environ.get('INFURA_API_KEY', '') + ) + if key == '': + logging.getLogger('web3.auto.infura').warning( + "No Infura API Key found. Add environment variable WEB3_INFURA_API_KEY to ensure " + "continued API access. New keys are available at https://infura.io/register" + ) + return key + + +def build_infura_url(domain): + scheme = os.environ.get('WEB3_INFURA_SCHEME', WEBSOCKET_SCHEME) + + if scheme == WEBSOCKET_SCHEME: + # websockets doesn't use the API key (yet?) + return "%s://%s/ws" % (scheme, domain) + elif scheme == HTTP_SCHEME: + key = load_api_key() + return "%s://%s/%s" % (scheme, domain, key) + else: + raise ValidationError("Cannot connect to Infura with scheme %r" % scheme) diff --git a/web3/auto/infura/ropsten.py b/web3/auto/infura/ropsten.py new file mode 100644 index 0000000000..cde15e757b --- /dev/null +++ b/web3/auto/infura/ropsten.py @@ -0,0 +1,13 @@ +from web3 import Web3 +from web3.providers.auto import ( + load_provider_from_uri, +) + +from .endpoints import ( + INFURA_ROPSTEN_DOMAIN, + build_infura_url, +) + +_infura_url = build_infura_url(INFURA_ROPSTEN_DOMAIN) + +w3 = Web3(load_provider_from_uri(_infura_url)) diff --git a/web3/providers/auto.py b/web3/providers/auto.py index 6bb56a26a5..23079d21bc 100644 --- a/web3/providers/auto.py +++ b/web3/providers/auto.py @@ -21,6 +21,10 @@ def load_provider_from_environment(): if not uri_string: return None + return load_provider_from_uri(uri_string) + + +def load_provider_from_uri(uri_string): uri = urlparse(uri_string) if uri.scheme == 'file': return IPCProvider(uri.path) From 17bf33bb7807f5f7cb1cd1f9a4551109871f816b Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Oct 2018 16:27:00 -0700 Subject: [PATCH 2/3] Add wss scheme to AutoProvider --- web3/providers/auto.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web3/providers/auto.py b/web3/providers/auto.py index 23079d21bc..cd8e109f31 100644 --- a/web3/providers/auto.py +++ b/web3/providers/auto.py @@ -14,6 +14,7 @@ ) HTTP_SCHEMES = {'http', 'https'} +WS_SCHEMES = {'ws', 'wss'} def load_provider_from_environment(): @@ -30,7 +31,7 @@ def load_provider_from_uri(uri_string): return IPCProvider(uri.path) elif uri.scheme in HTTP_SCHEMES: return HTTPProvider(uri_string) - elif uri.scheme == 'ws': + elif uri.scheme in WS_SCHEMES: return WebsocketProvider(uri_string) else: raise NotImplementedError( From e59d8b864bd930aa3be89ab5a07dbc3b940a9d48 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Wed, 24 Oct 2018 16:41:01 -0700 Subject: [PATCH 3/3] Update infura tests for websockets & refactor --- tests/core/providers/test_auto_provider.py | 37 +++++++++++++++------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/tests/core/providers/test_auto_provider.py b/tests/core/providers/test_auto_provider.py index 4e7375166e..e5145a2a6d 100644 --- a/tests/core/providers/test_auto_provider.py +++ b/tests/core/providers/test_auto_provider.py @@ -42,38 +42,44 @@ def test_load_provider_from_env(monkeypatch, uri, expected_type, expected_attrs) assert getattr(provider, attr) == val -def test_web3_auto_infura_empty_key(monkeypatch, caplog): - monkeypatch.setenv('INFURA_API_KEY', '') +@pytest.mark.parametrize('environ_name', ['INFURA_API_KEY', 'WEB3_INFURA_API_KEY']) +def test_web3_auto_infura_empty_key(monkeypatch, caplog, environ_name): + monkeypatch.setenv('WEB3_INFURA_SCHEME', 'https') + monkeypatch.setenv(environ_name, '') importlib.reload(infura) assert len(caplog.record_tuples) == 1 logger, level, msg = caplog.record_tuples[0] - assert 'INFURA_API_KEY' in msg + assert 'WEB3_INFURA_API_KEY' in msg assert level == logging.WARNING w3 = infura.w3 assert isinstance(w3.providers[0], HTTPProvider) - assert getattr(w3.providers[0], 'endpoint_uri') == infura.INFURA_MAINNET_BASE_URL + assert getattr(w3.providers[0], 'endpoint_uri') == 'https://mainnet.infura.io/' -def test_web3_auto_infura_missing_key(monkeypatch, caplog): - monkeypatch.delenv('INFURA_API_KEY', raising=False) +@pytest.mark.parametrize('environ_name', ['INFURA_API_KEY', 'WEB3_INFURA_API_KEY']) +def test_web3_auto_infura_deleted_key(monkeypatch, caplog, environ_name): + monkeypatch.setenv('WEB3_INFURA_SCHEME', 'https') + monkeypatch.delenv(environ_name, raising=False) importlib.reload(infura) assert len(caplog.record_tuples) == 1 logger, level, msg = caplog.record_tuples[0] - assert 'INFURA_API_KEY' in msg + assert 'WEB3_INFURA_API_KEY' in msg assert level == logging.WARNING w3 = infura.w3 assert isinstance(w3.providers[0], HTTPProvider) - assert getattr(w3.providers[0], 'endpoint_uri') == infura.INFURA_MAINNET_BASE_URL + assert getattr(w3.providers[0], 'endpoint_uri') == 'https://mainnet.infura.io/' -def test_web3_auto_infura(monkeypatch, caplog): +@pytest.mark.parametrize('environ_name', ['INFURA_API_KEY', 'WEB3_INFURA_API_KEY']) +def test_web3_auto_infura(monkeypatch, caplog, environ_name): + monkeypatch.setenv('WEB3_INFURA_SCHEME', 'https') API_KEY = 'aoeuhtns' - monkeypatch.setenv('INFURA_API_KEY', API_KEY) - expected_url = '%s/%s' % (infura.INFURA_MAINNET_BASE_URL, API_KEY) + monkeypatch.setenv(environ_name, API_KEY) + expected_url = 'https://%s/%s' % (infura.INFURA_MAINNET_DOMAIN, API_KEY) importlib.reload(infura) assert len(caplog.record_tuples) == 0 @@ -81,3 +87,12 @@ def test_web3_auto_infura(monkeypatch, caplog): w3 = infura.w3 assert isinstance(w3.providers[0], HTTPProvider) assert getattr(w3.providers[0], 'endpoint_uri') == expected_url + + +def test_web3_auto_infura_websocket_default(caplog): + importlib.reload(infura) + assert len(caplog.record_tuples) == 0 + + w3 = infura.w3 + assert isinstance(w3.providers[0], WebsocketProvider) + assert getattr(w3.providers[0], 'endpoint_uri') == 'wss://mainnet.infura.io/ws'