From f5e99a8ca8ed0a084db1f5c023d8d2745da41541 Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 7 Sep 2022 14:04:28 +0200 Subject: [PATCH 1/4] feat(debank): Use pro API. Add keys --- blockapi/test/v2/api/debank/conftest.py | 4 +- blockapi/test/v2/api/debank/test_debank.py | 68 ++++++++++++++++------ blockapi/v2/api/debank.py | 18 ++++-- 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/blockapi/test/v2/api/debank/conftest.py b/blockapi/test/v2/api/debank/conftest.py index e2a883a4..5a236084 100644 --- a/blockapi/test/v2/api/debank/conftest.py +++ b/blockapi/test/v2/api/debank/conftest.py @@ -33,12 +33,12 @@ def protocol_parser(): @pytest.fixture def debank_api(protocol_cache): - return DebankApi(True, protocol_cache) + return DebankApi('0x12345', True, protocol_cache) @pytest.fixture def debank_api_all_off(protocol_cache): - return DebankApi(False, protocol_cache) + return DebankApi('0x12345', False, protocol_cache) @pytest.fixture diff --git a/blockapi/test/v2/api/debank/test_debank.py b/blockapi/test/v2/api/debank/test_debank.py index 842987dd..2c57360d 100644 --- a/blockapi/test/v2/api/debank/test_debank.py +++ b/blockapi/test/v2/api/debank/test_debank.py @@ -9,7 +9,7 @@ def test_build_balance_request_url(debank_api): ) assert ( url - == 'https://openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=True' + == 'https://pro-openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=True' ) @@ -21,13 +21,13 @@ def test_build_balance_request_url_with_is_all_off(debank_api_all_off): ) assert ( url - == 'https://openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=False' + == 'https://pro-openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=False' ) def test_build_protocols_request_url(debank_api): url = debank_api._build_request_url('get_protocols') - assert url == 'https://openapi.debank.com/v1/protocol/list' + assert url == 'https://pro-openapi.debank.com/v1/protocol/list' def test_build_portfolio_request_url(debank_api): @@ -36,7 +36,7 @@ def test_build_portfolio_request_url(debank_api): ) assert ( url - == 'https://openapi.debank.com/v1/user/complex_protocol_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca' + == 'https://pro-openapi.debank.com/v1/user/complex_protocol_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca' ) @@ -45,7 +45,7 @@ def test_error_response_returns_empty_balances( ): protocol_cache.update({}) requests_mock.get( - "https://openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=true", + "https://pro-openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=true", text=error_response_raw, ) parsed_items = debank_api.get_balance("0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca") @@ -63,13 +63,42 @@ def test_error_response_logs_error( ] requests_mock.get( - "https://openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=true", + "https://pro-openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=true", text=error_response_raw, ) _ = debank_api.get_balance("0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca") assert expected_log == caplog.messages +def test_get_balance_has_api_key_header(debank_api, protocol_cache, requests_mock): + req = requests_mock.get( + 'https://pro-openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=True', + text='{}', + ) + protocol_cache.update({}) + debank_api.get_balance("0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca") + assert req.last_request.headers.get('AccessKey') == '0x12345' + + +def test_get_portfolio_has_api_key_header(debank_api, protocol_cache, requests_mock): + req = requests_mock.get( + 'https://pro-openapi.debank.com/v1/user/complex_protocol_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca', + text='{}', + ) + protocol_cache.update({}) + debank_api.get_portfolio("0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca") + assert req.last_request.headers.get('AccessKey') == '0x12345' + + +def test_get_protocol(debank_api, requests_mock): + req = requests_mock.get( + 'https://pro-openapi.debank.com/v1/protocol/list', + text='{}', + ) + debank_api.get_protocols() + assert req.last_request.headers.get('AccessKey') == '0x12345' + + def test_repr_doesnt_fail(debank_api): assert repr(debank_api) == "DebankApi" @@ -78,7 +107,8 @@ def test_debank_parse_protocols( debank_api, yflink_protocol_response_raw, yflink_cache_data, requests_mock ): requests_mock.get( - "https://openapi.debank.com/v1/protocol/list", text=yflink_protocol_response_raw + "https://pro-openapi.debank.com/v1/protocol/list", + text=yflink_protocol_response_raw, ) parsed_items = debank_api.get_protocols() assert parsed_items == yflink_cache_data @@ -91,10 +121,11 @@ def test_get_balance_fetches_protocols( requests_mock, ): requests_mock.get( - "https://openapi.debank.com/v1/protocol/list", text=yflink_protocol_response_raw + "https://pro-openapi.debank.com/v1/protocol/list", + text=yflink_protocol_response_raw, ) requests_mock.get( - "https://openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=true", + "https://pro-openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=true", text=coin_with_protocol_response_raw, ) debank_api._protocol_cache.invalidate() @@ -109,10 +140,11 @@ def test_get_balance_uses_correct_url( requests_mock, ): requests_mock.get( - "https://openapi.debank.com/v1/protocol/list", text=yflink_protocol_response_raw + "https://pro-openapi.debank.com/v1/protocol/list", + text=yflink_protocol_response_raw, ) requests_mock.get( - "https://openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=true", + "https://pro-openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=true", text=coin_with_protocol_response_raw, ) parsed_items = debank_api.get_balance("0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca") @@ -126,10 +158,11 @@ def test_get_balance_with_all_unset_uses_correct_url( requests_mock, ): requests_mock.get( - "https://openapi.debank.com/v1/protocol/list", text=yflink_protocol_response_raw + "https://pro-openapi.debank.com/v1/protocol/list", + text=yflink_protocol_response_raw, ) requests_mock.get( - "https://openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=false", + "https://pro-openapi.debank.com/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=false", text=coin_with_protocol_response_raw, ) parsed_items = debank_api_all_off.get_balance( @@ -142,10 +175,11 @@ def test_get_portfolio_fetches_protocols( debank_api, yflink_protocol_response_raw, portfolio_response_raw, requests_mock ): requests_mock.get( - "https://openapi.debank.com/v1/protocol/list", text=yflink_protocol_response_raw + "https://pro-openapi.debank.com/v1/protocol/list", + text=yflink_protocol_response_raw, ) requests_mock.get( - "https://openapi.debank.com/v1/user/complex_protocol_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca", + "https://pro-openapi.debank.com/v1/user/complex_protocol_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca", text=portfolio_response_raw, ) debank_api._protocol_cache.invalidate() @@ -156,8 +190,8 @@ def test_get_portfolio_fetches_protocols( def test_protocol_cache_is_shared_by_instances(): - one = DebankApi(True) - two = DebankApi(True) + one = DebankApi('0x0', True) + two = DebankApi('0x0', True) assert one._protocol_cache is two._protocol_cache diff --git a/blockapi/v2/api/debank.py b/blockapi/v2/api/debank.py index e9c3a8b5..184e947a 100644 --- a/blockapi/v2/api/debank.py +++ b/blockapi/v2/api/debank.py @@ -398,10 +398,10 @@ def _get_reward_asset_type(asset_type): class DebankApi(BlockchainApi, IBalance, IPortfolio): """ - DeBank OpenApi: https://openapi.debank.com/docs + DeBank OpenApi: https://open.debank.com/ """ - API_BASE_URL = 'https://openapi.debank.com' + API_BASE_URL = 'https://pro-openapi.debank.com' API_BASE_RATE_LIMIT = 0.05 # 20 req / s api_options = ApiOptions( @@ -419,11 +419,15 @@ class DebankApi(BlockchainApi, IBalance, IPortfolio): default_protocol_cache = DebankProtocolCache() def __init__( - self, is_all: bool, protocol_cache: Optional[DebankProtocolCache] = None + self, + api_key: str, + is_all: bool, + protocol_cache: Optional[DebankProtocolCache] = None, ): super().__init__() self._is_all = bool(is_all) + self._headers = {'AccessKey': api_key} self._protocol_cache = protocol_cache or self.default_protocol_cache self._balance_parser = DebankBalanceParser(self._protocol_cache) self._protocol_parser = DebankProtocolParser() @@ -433,14 +437,16 @@ def __init__( def get_balance(self, address: str) -> List[BalanceItem]: self._maybe_update_protocols() - response = self.get('get_balance', address=address, is_all=self._is_all) + response = self.get( + 'get_balance', headers=self._headers, address=address, is_all=self._is_all + ) if self._has_error(response): return [] return self._balance_parser.parse(response) def get_protocols(self) -> Dict[str, Protocol]: - response = self.get('get_protocols') + response = self.get('get_protocols', headers=self._headers) if self._has_error(response): return {} @@ -448,7 +454,7 @@ def get_protocols(self) -> Dict[str, Protocol]: def get_portfolio(self, address: str) -> List[Pool]: self._maybe_update_protocols() - response = self.get('get_portfolio', address=address) + response = self.get('get_portfolio', headers=self._headers, address=address) if self._has_error(response): return [] From 5d658cc94981b0c06d0deac30da6ac22bbbc3299 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 8 Sep 2022 09:27:26 +0200 Subject: [PATCH 2/4] Change dummy key to be more explicit --- blockapi/test/v2/api/debank/conftest.py | 4 ++-- blockapi/test/v2/api/debank/test_debank.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/blockapi/test/v2/api/debank/conftest.py b/blockapi/test/v2/api/debank/conftest.py index 5a236084..95d9722d 100644 --- a/blockapi/test/v2/api/debank/conftest.py +++ b/blockapi/test/v2/api/debank/conftest.py @@ -33,12 +33,12 @@ def protocol_parser(): @pytest.fixture def debank_api(protocol_cache): - return DebankApi('0x12345', True, protocol_cache) + return DebankApi('dummy-key', True, protocol_cache) @pytest.fixture def debank_api_all_off(protocol_cache): - return DebankApi('0x12345', False, protocol_cache) + return DebankApi('dummy-key', False, protocol_cache) @pytest.fixture diff --git a/blockapi/test/v2/api/debank/test_debank.py b/blockapi/test/v2/api/debank/test_debank.py index 2c57360d..6df9708b 100644 --- a/blockapi/test/v2/api/debank/test_debank.py +++ b/blockapi/test/v2/api/debank/test_debank.py @@ -77,7 +77,7 @@ def test_get_balance_has_api_key_header(debank_api, protocol_cache, requests_moc ) protocol_cache.update({}) debank_api.get_balance("0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca") - assert req.last_request.headers.get('AccessKey') == '0x12345' + assert req.last_request.headers.get('AccessKey') == 'dummy-key' def test_get_portfolio_has_api_key_header(debank_api, protocol_cache, requests_mock): @@ -87,7 +87,7 @@ def test_get_portfolio_has_api_key_header(debank_api, protocol_cache, requests_m ) protocol_cache.update({}) debank_api.get_portfolio("0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca") - assert req.last_request.headers.get('AccessKey') == '0x12345' + assert req.last_request.headers.get('AccessKey') == 'dummy-key' def test_get_protocol(debank_api, requests_mock): @@ -96,7 +96,7 @@ def test_get_protocol(debank_api, requests_mock): text='{}', ) debank_api.get_protocols() - assert req.last_request.headers.get('AccessKey') == '0x12345' + assert req.last_request.headers.get('AccessKey') == 'dummy-key' def test_repr_doesnt_fail(debank_api): From 2f73d14982b526112827def17cb5221f1b658a88 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 8 Sep 2022 10:41:40 +0200 Subject: [PATCH 3/4] Change dummy key to be more explicit --- blockapi/test/v2/api/debank/test_debank.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blockapi/test/v2/api/debank/test_debank.py b/blockapi/test/v2/api/debank/test_debank.py index 6df9708b..3e9f46e9 100644 --- a/blockapi/test/v2/api/debank/test_debank.py +++ b/blockapi/test/v2/api/debank/test_debank.py @@ -190,8 +190,8 @@ def test_get_portfolio_fetches_protocols( def test_protocol_cache_is_shared_by_instances(): - one = DebankApi('0x0', True) - two = DebankApi('0x0', True) + one = DebankApi('dummy-key', True) + two = DebankApi('dummy-key', True) assert one._protocol_cache is two._protocol_cache From 1c263b98df98e8792fe2d8d793dfd0aaee69d963 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 9 Sep 2022 08:57:33 +0200 Subject: [PATCH 4/4] feat(debank): Enable proxy --- blockapi/test/v2/api/debank/test_debank.py | 14 ++++++++++++++ blockapi/v2/api/debank.py | 2 ++ 2 files changed, 16 insertions(+) diff --git a/blockapi/test/v2/api/debank/test_debank.py b/blockapi/test/v2/api/debank/test_debank.py index 3e9f46e9..62fe9814 100644 --- a/blockapi/test/v2/api/debank/test_debank.py +++ b/blockapi/test/v2/api/debank/test_debank.py @@ -13,6 +13,20 @@ def test_build_balance_request_url(debank_api): ) +def test_build_balance_request_url_with_custom_url(): + api = DebankApi('dummy-key', False, base_url='https://proxy/') + + url = api._build_request_url( + 'get_balance', + address='0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca', + is_all=True, + ) + assert ( + url + == 'https://proxy/v1/user/token_list?id=0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca&is_all=True' + ) + + def test_build_balance_request_url_with_is_all_off(debank_api_all_off): url = debank_api_all_off._build_request_url( 'get_balance', diff --git a/blockapi/v2/api/debank.py b/blockapi/v2/api/debank.py index 184e947a..464d4f0d 100644 --- a/blockapi/v2/api/debank.py +++ b/blockapi/v2/api/debank.py @@ -423,9 +423,11 @@ def __init__( api_key: str, is_all: bool, protocol_cache: Optional[DebankProtocolCache] = None, + base_url: Optional[str] = None, ): super().__init__() + self.api_options.base_url = base_url or self.API_BASE_URL self._is_all = bool(is_all) self._headers = {'AccessKey': api_key} self._protocol_cache = protocol_cache or self.default_protocol_cache