Skip to content

Commit

Permalink
Refactor APIs to use requests.Session
Browse files Browse the repository at this point in the history
  • Loading branch information
Uxio0 committed Sep 9, 2022
1 parent d5cffe0 commit a0b87ff
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 28 deletions.
32 changes: 19 additions & 13 deletions gnosis/eth/oracles/cowswap.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,23 @@ def get_price(
return 1.0

token_1_decimals = get_decimals(token_address_1, self.ethereum_client)
result = self.api.get_estimated_amount(
token_address_1, token_address_2, OrderKind.SELL, 10**token_1_decimals
)
if "errorType" in result:
error_message = (
f"Cannot get price from CowSwap {result} "
f"for token-1={token_address_1} to token-2={token_address_2}"
try:
result = self.api.get_estimated_amount(
token_address_1, token_address_2, OrderKind.SELL, 10**token_1_decimals
)
logger.warning(error_message)
raise CannotGetPriceFromOracle(error_message)
else:
# Decimals needs to be adjusted
token_2_decimals = get_decimals(token_address_2, self.ethereum_client)
return float(result["amount"]) / 10**token_2_decimals
if "amount" in result:
# Decimals needs to be adjusted
token_2_decimals = get_decimals(token_address_2, self.ethereum_client)
return float(result["amount"]) / 10**token_2_decimals

exception = None
except IOError as exc:
exception = exc
result = {}

error_message = (
f"Cannot get price from CowSwap {result} "
f"for token-1={token_address_1} to token-2={token_address_2}"
)
logger.warning(error_message)
raise CannotGetPriceFromOracle(error_message) from exception
12 changes: 12 additions & 0 deletions gnosis/eth/tests/oracles/test_cowswap.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.test import TestCase

from eth_account import Account
from requests import Session

from ... import EthereumClient
from ...oracles import CannotGetPriceFromOracle, CowswapOracle
Expand Down Expand Up @@ -54,6 +55,17 @@ def test_get_price(self):
)
self.assertAlmostEqual(price, 1.0, delta=0.5)

with mock.patch.object(Session, "get", side_effect=IOError("Connection Error")):
with self.assertRaisesMessage(
CannotGetPriceFromOracle,
f"Cannot get price from CowSwap "
f"{{}} "
f"for token-1={usdc_token_mainnet_address} to token-2={dai_token_mainnet_address}",
):
cowswap_oracle.get_price(
usdc_token_mainnet_address, dai_token_mainnet_address
)

random_token = Account.create().address
with self.assertRaisesMessage(
CannotGetPriceFromOracle,
Expand Down
11 changes: 6 additions & 5 deletions gnosis/protocol/gnosis_protocol_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def __init__(self, ethereum_network: EthereumNetwork):
)
self.domain_separator = self.build_domain_separator(self.network)
self.base_url = self.api_base_urls[self.network]
self.http_session = requests.Session()

@cached_property
def weth_address(self) -> ChecksumAddress:
Expand Down Expand Up @@ -99,7 +100,7 @@ def get_fee(self, order: Order) -> int:
+ f'fee/?sellToken={order["sellToken"]}&buyToken={order["buyToken"]}'
f'&amount={amount}&kind={order["kind"]}'
)
result = requests.get(url).json()
result = self.http_session.get(url).json()
if "amount" in result:
return int(result["amount"])
else:
Expand Down Expand Up @@ -140,7 +141,7 @@ def place_order(
"signingScheme": "ethsign",
"from": Account.from_key(private_key).address,
}
r = requests.post(url, json=data_json)
r = self.http_session.post(url, json=data_json)
if r.ok:
return HexStr(r.json())
else:
Expand All @@ -160,7 +161,7 @@ def get_orders(
the last page has been reached.
"""
url = self.base_url + f"account/{owner}/orders"
r = requests.get(url)
r = self.http_session.get(url)
if r.ok:
return cast(List[Dict[str, Any]], r.json())
else:
Expand All @@ -178,7 +179,7 @@ def get_trades(
elif owner:
url += f"owner={owner}"

r = requests.get(url)
r = self.http_session.get(url)
if r.ok:
return cast(List[TradeResponse], r.json())
else:
Expand All @@ -195,7 +196,7 @@ def get_estimated_amount(
The estimated amount in quote token for either buying or selling amount of baseToken.
"""
url = self.base_url + f"markets/{base_token}-{quote_token}/{kind.name}/{amount}"
r = requests.get(url)
r = self.http_session.get(url)
if r.ok:
return AmountResponse(r.json())
else:
Expand Down
7 changes: 4 additions & 3 deletions gnosis/safe/api/base_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def __init__(
self.base_url = base_url or self.URL_BY_NETWORK.get(network)
if not self.base_url:
raise EthereumNetworkNotSupported(network)
self.http_session = requests.Session()

@classmethod
def from_ethereum_client(cls, ethereum_client: EthereumClient) -> "SafeBaseAPI":
Expand All @@ -43,16 +44,16 @@ def from_ethereum_client(cls, ethereum_client: EthereumClient) -> "SafeBaseAPI":

def _get_request(self, url: str) -> requests.Response:
full_url = urljoin(self.base_url, url)
return requests.get(full_url)
return self.http_session.get(full_url)

def _post_request(self, url: str, payload: Dict) -> requests.Response:
full_url = urljoin(self.base_url, url)
return requests.post(
return self.http_session.post(
full_url, json=payload, headers={"Content-type": "application/json"}
)

def _delete_request(self, url: str, payload: Dict) -> requests.Response:
full_url = urljoin(self.base_url, url)
return requests.delete(
return self.http_session.delete(
full_url, json=payload, headers={"Content-type": "application/json"}
)
10 changes: 3 additions & 7 deletions gnosis/safe/api/transaction_service_api.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import logging
import time
from typing import Any, Dict, List, Optional, Tuple, Union
from urllib.parse import urljoin

import requests
from eth_account.signers.local import LocalAccount
from eth_typing import HexStr
from hexbytes import HexBytes
Expand Down Expand Up @@ -210,10 +208,6 @@ def remove_delegate(
raise SafeAPIException(f"Cannot remove delegate: {response.content}")

def post_transaction(self, safe_tx: SafeTx):
url = urljoin(
self.base_url,
f"/api/v1/safes/{safe_tx.safe_address}/multisig-transactions/",
)
random_sender = "0x0000000000000000000000000000000000000002"
sender = safe_tx.sorted_signers[0] if safe_tx.sorted_signers else random_sender
data = {
Expand All @@ -232,6 +226,8 @@ def post_transaction(self, safe_tx: SafeTx):
"signature": safe_tx.signatures.hex() if safe_tx.signatures else None,
"origin": "Safe-CLI",
}
response = requests.post(url, json=data)
response = self._post_request(
f"/api/v1/safes/{safe_tx.safe_address}/multisig-transactions/", data
)
if not response.ok:
raise SafeAPIException(f"Error posting transaction: {response.content}")

0 comments on commit a0b87ff

Please sign in to comment.