From 1886ba2065534c4b631500b6aa76eb7614c30551 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Tue, 8 Oct 2024 10:16:51 -0400 Subject: [PATCH] feat(PSDK-547): Optional API Debug Logging --- cdp/address.py | 4 +- cdp/cdp.py | 2 +- cdp/cdp_api_client.py | 43 ++++++++++++++++++- cdp/historical_balance.py | 16 ++++--- cdp/transaction.py | 12 +++--- tests/factories/historical_balance_factory.py | 7 +-- tests/test_address.py | 15 ++++--- tests/test_historical_balance.py | 18 ++++---- tests/test_wallet_address.py | 15 +++++-- 9 files changed, 95 insertions(+), 37 deletions(-) diff --git a/cdp/address.py b/cdp/address.py index 90dcdd0..da5a652 100644 --- a/cdp/address.py +++ b/cdp/address.py @@ -114,7 +114,9 @@ def historical_balances(self, asset_id) -> Iterator[HistoricalBalance]: Exception: If there's an error listing the historical balances. """ - return HistoricalBalance.list(network_id=self.network_id, address_id=self.address_id, asset_id=asset_id) + return HistoricalBalance.list( + network_id=self.network_id, address_id=self.address_id, asset_id=asset_id + ) def transactions(self) -> Iterator[Transaction]: """List transactions of the address. diff --git a/cdp/cdp.py b/cdp/cdp.py index 54c3159..2c2f003 100644 --- a/cdp/cdp.py +++ b/cdp/cdp.py @@ -73,7 +73,7 @@ def configure( cls.base_path = base_path cls.max_network_retries = max_network_retries - cdp_client = CdpApiClient(api_key_name, private_key, base_path) + cdp_client = CdpApiClient(api_key_name, private_key, base_path, debugging) cls.api_clients = ApiClients(cdp_client) @classmethod diff --git a/cdp/cdp_api_client.py b/cdp/cdp_api_client.py index 3cd5847..0708007 100644 --- a/cdp/cdp_api_client.py +++ b/cdp/cdp_api_client.py @@ -24,6 +24,7 @@ def __init__( api_key: str, private_key: str, host: str = "https://api.cdp.coinbase.com/platform", + debugging: bool = False, ): """Initialize the CDP API Client. @@ -31,12 +32,44 @@ def __init__( api_key (str): The API key for authentication. private_key (str): The private key for authentication. host (str, optional): The base URL for the API. Defaults to "https://api.cdp.coinbase.com/platform". + debugging (bool): Whether debugging is enabled. """ configuration = Configuration(host=host) super().__init__(configuration) - self.api_key = api_key - self.private_key = private_key + self._api_key = api_key + self._private_key = private_key + self._debugging = debugging + + @property + def api_key(self) -> str: + """The API key for authentication. + + Returns: + str: The API key. + + """ + return self._api_key + + @property + def private_key(self) -> str: + """The private key for authentication. + + Returns: + str: The private key. + + """ + return self._private_key + + @property + def debugging(self) -> str: + """Whether debugging is enabled. + + Returns: + bool: Whether debugging is enabled. + + """ + return self._debugging def call_api( self, @@ -63,6 +96,9 @@ def call_api( RESTResponse """ + if self.debugging is True: + print(f"CDP API REQUEST: {method} {url}") + if header_params is None: header_params = {} @@ -85,6 +121,9 @@ def response_deserialize( ApiResponse[ApiResponseT] """ + if self.debugging is True: + print(f"CDP API RESPONSE: Status: {response_data.status}, Data: {response_data.data}") + try: return super().response_deserialize(response_data, response_types_map) except ApiException as e: diff --git a/cdp/historical_balance.py b/cdp/historical_balance.py index f58c98f..e513e0b 100644 --- a/cdp/historical_balance.py +++ b/cdp/historical_balance.py @@ -43,7 +43,7 @@ def from_model(cls, model: HistoricalBalanceModel) -> "HistoricalBalance": amount=asset.from_atomic_amount(model.amount), asset=asset, block_height=model.block_height, - block_hash=model.block_hash + block_hash=model.block_hash, ) @classmethod @@ -64,12 +64,14 @@ def list(cls, network_id: str, address_id: str, asset_id: str) -> Iterator["Hist """ page = None while True: - response: AddressHistoricalBalanceList = Cdp.api_clients.balance_history.list_address_historical_balance( - network_id=network_id, - address_id=address_id, - asset_id=Asset.primary_denomination(asset_id), - limit=100, - page=page, + response: AddressHistoricalBalanceList = ( + Cdp.api_clients.balance_history.list_address_historical_balance( + network_id=network_id, + address_id=address_id, + asset_id=Asset.primary_denomination(asset_id), + limit=100, + page=page, + ) ) for model in response.data: diff --git a/cdp/transaction.py b/cdp/transaction.py index 46e7f2c..adab0c7 100644 --- a/cdp/transaction.py +++ b/cdp/transaction.py @@ -72,11 +72,13 @@ def list(cls, network_id: str, address_id: str) -> Iterator["Transaction"]: """ page = None while True: - response: AddressTransactionList = Cdp.api_clients.transaction_history.list_address_transactions( - network_id=network_id, - address_id=address_id, - limit=1, - page=page, + response: AddressTransactionList = ( + Cdp.api_clients.transaction_history.list_address_transactions( + network_id=network_id, + address_id=address_id, + limit=1, + page=page, + ) ) for model in response.data: diff --git a/tests/factories/historical_balance_factory.py b/tests/factories/historical_balance_factory.py index aabd4b2..708d733 100644 --- a/tests/factories/historical_balance_factory.py +++ b/tests/factories/historical_balance_factory.py @@ -14,11 +14,12 @@ def _create_historical_balance_model( asset_id="eth", decimals=18, block_hash="0xblockhash", - block_height="12345" + block_height="12345", ): asset_model = asset_model_factory(network_id, asset_id, decimals) return HistoricalBalanceModel( - amount=amount, block_hash=block_hash, block_height=block_height, asset=asset_model) + amount=amount, block_hash=block_hash, block_height=block_height, asset=asset_model + ) return _create_historical_balance_model @@ -33,7 +34,7 @@ def _create_historical_balance( asset_id="eth", decimals=18, block_hash="0xblockhash", - block_height="12345" + block_height="12345", ): asset = asset_factory(network_id=network_id, asset_id=asset_id, decimals=decimals) return HistoricalBalance(amount, asset, block_height, block_hash) diff --git a/tests/test_address.py b/tests/test_address.py index 90a3a48..c605bd8 100644 --- a/tests/test_address.py +++ b/tests/test_address.py @@ -160,13 +160,17 @@ def test_address_balances_api_error(mock_api_clients, address_factory): @patch("cdp.Cdp.api_clients") -def test_address_historical_balances(mock_api_clients, address_factory, historical_balance_model_factory): +def test_address_historical_balances( + mock_api_clients, address_factory, historical_balance_model_factory +): """Test the historical_balances method of an Address.""" address = address_factory() historical_balance_model = historical_balance_model_factory() mock_list_historical_balances = Mock() - mock_list_historical_balances.return_value = Mock(data=[historical_balance_model], has_more=False) + mock_list_historical_balances.return_value = Mock( + data=[historical_balance_model], has_more=False + ) mock_api_clients.balance_history.list_address_historical_balance = mock_list_historical_balances historical_balances = address.historical_balances("eth") @@ -178,7 +182,7 @@ def test_address_historical_balances(mock_api_clients, address_factory, historic address_id=address.address_id, asset_id="eth", limit=100, - page=None + page=None, ) @@ -212,10 +216,7 @@ def test_address_transactions(mock_api_clients, address_factory, transaction_mod assert len(list(transactions)) == 1 assert all(isinstance(t, Transaction) for t in transactions) mock_list_transactions.assert_called_once_with( - network_id=address.network_id, - address_id=address.address_id, - limit=1, - page=None + network_id=address.network_id, address_id=address.address_id, limit=1, page=None ) diff --git a/tests/test_historical_balance.py b/tests/test_historical_balance.py index a50f126..a97295d 100644 --- a/tests/test_historical_balance.py +++ b/tests/test_historical_balance.py @@ -57,19 +57,19 @@ def test_historical_balance_repr(historical_balance_factory): def test_list_historical_balances(mock_api_clients, historical_balance_model_factory): """Test the historical_balances method.""" mock_list_historical_balances = Mock() - mock_list_historical_balances.return_value = Mock(data=[historical_balance_model_factory()], has_more=False) + mock_list_historical_balances.return_value = Mock( + data=[historical_balance_model_factory()], has_more=False + ) mock_api_clients.balance_history.list_address_historical_balance = mock_list_historical_balances - historical_balances = HistoricalBalance.list(network_id="test-network-id", address_id="0xaddressid", asset_id="eth") + historical_balances = HistoricalBalance.list( + network_id="test-network-id", address_id="0xaddressid", asset_id="eth" + ) assert len(list(historical_balances)) == 1 assert all(isinstance(h, HistoricalBalance) for h in historical_balances) mock_list_historical_balances.assert_called_once_with( - network_id="test-network-id", - address_id="0xaddressid", - asset_id="eth", - limit=100, - page=None + network_id="test-network-id", address_id="0xaddressid", asset_id="eth", limit=100, page=None ) @@ -82,5 +82,7 @@ def test_list_historical_balances_error(mock_api_clients): mock_api_clients.balance_history.list_address_historical_balance = mock_list_historical_balances with pytest.raises(ApiError): - historical_balances = HistoricalBalance.list(network_id="test-network-id", address_id="0xaddressid", asset_id="eth") + historical_balances = HistoricalBalance.list( + network_id="test-network-id", address_id="0xaddressid", asset_id="eth" + ) next(historical_balances) diff --git a/tests/test_wallet_address.py b/tests/test_wallet_address.py index d081131..7e522f8 100644 --- a/tests/test_wallet_address.py +++ b/tests/test_wallet_address.py @@ -688,7 +688,9 @@ def test_repr(wallet_address_factory): @patch("cdp.wallet_address.SmartContract") @patch("cdp.Cdp.use_server_signer", False) -def test_wallet_address_deploy_token_total_supply_string(mock_smart_contract, wallet_address_factory): +def test_wallet_address_deploy_token_total_supply_string( + mock_smart_contract, wallet_address_factory +): """Test the deploy_token method of a WalletAddress with a string total_supply.""" wallet_address = wallet_address_factory(key=True) @@ -711,9 +713,12 @@ def test_wallet_address_deploy_token_total_supply_string(mock_smart_contract, wa mock_smart_contract_instance.sign.assert_called_once_with(wallet_address.key) mock_smart_contract_instance.broadcast.assert_called_once() + @patch("cdp.wallet_address.SmartContract") @patch("cdp.Cdp.use_server_signer", False) -def test_wallet_address_deploy_token_total_supply_number(mock_smart_contract, wallet_address_factory): +def test_wallet_address_deploy_token_total_supply_number( + mock_smart_contract, wallet_address_factory +): """Test the deploy_token method of a WalletAddress with a number total_supply.""" wallet_address = wallet_address_factory(key=True) @@ -736,9 +741,12 @@ def test_wallet_address_deploy_token_total_supply_number(mock_smart_contract, wa mock_smart_contract_instance.sign.assert_called_once_with(wallet_address.key) mock_smart_contract_instance.broadcast.assert_called_once() + @patch("cdp.wallet_address.SmartContract") @patch("cdp.Cdp.use_server_signer", False) -def test_wallet_address_deploy_token_total_supply_decimal(mock_smart_contract, wallet_address_factory): +def test_wallet_address_deploy_token_total_supply_decimal( + mock_smart_contract, wallet_address_factory +): """Test the deploy_token method of a WalletAddress with a Decimal total_supply.""" wallet_address = wallet_address_factory(key=True) @@ -761,6 +769,7 @@ def test_wallet_address_deploy_token_total_supply_decimal(mock_smart_contract, w mock_smart_contract_instance.sign.assert_called_once_with(wallet_address.key) mock_smart_contract_instance.broadcast.assert_called_once() + @patch("cdp.wallet_address.SmartContract") @patch("cdp.Cdp.use_server_signer", False) def test_wallet_address_deploy_nft(mock_smart_contract, wallet_address_factory):