aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-04-04 13:02:56 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2018-04-04 13:02:56 +0200
commit7d5da019e51adea12a1ad52e07fc71c1ee1de6ab (patch)
tree6872b4a8f25e276cbc8877a2de9c1caead5a2d81
parent79ac9364372ad0cd99f3d29b7dbc2b79dcc84bf5 (diff)
parent3b60291066e5442ce2980a6c40ea10542f24a910 (diff)
downloadTrader-7d5da019e51adea12a1ad52e07fc71c1ee1de6ab.tar.gz
Trader-7d5da019e51adea12a1ad52e07fc71c1ee1de6ab.tar.zst
Trader-7d5da019e51adea12a1ad52e07fc71c1ee1de6ab.zip
Merge branch 'dev'v1.1.2
-rw-r--r--.gitattributes2
-rw-r--r--ccxt_wrapper.py16
-rw-r--r--market.py3
-rw-r--r--store.py42
-rw-r--r--test.py55
5 files changed, 104 insertions, 14 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..227f825
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
1*.py diff=python
2/store.py export-subst
diff --git a/ccxt_wrapper.py b/ccxt_wrapper.py
index 260d49d..bedf84b 100644
--- a/ccxt_wrapper.py
+++ b/ccxt_wrapper.py
@@ -3,6 +3,8 @@ import decimal
3import time 3import time
4from retry.api import retry_call 4from retry.api import retry_call
5import re 5import re
6from requests.exceptions import RequestException
7from ssl import SSLError
6 8
7def _cw_exchange_sum(self, *args): 9def _cw_exchange_sum(self, *args):
8 return sum([arg for arg in args if isinstance(arg, (float, int, decimal.Decimal))]) 10 return sum([arg for arg in args if isinstance(arg, (float, int, decimal.Decimal))])
@@ -45,10 +47,16 @@ class poloniexE(poloniex):
45 self.session._parent = self 47 self.session._parent = self
46 48
47 def request_wrap(self, *args, **kwargs): 49 def request_wrap(self, *args, **kwargs):
48 r = self.origin_request(*args, **kwargs) 50 try:
49 self._parent._market.report.log_http_request(args[0], 51 r = self.origin_request(*args, **kwargs)
50 args[1], kwargs["data"], kwargs["headers"], r) 52 self._parent._market.report.log_http_request(args[0],
51 return r 53 args[1], kwargs["data"], kwargs["headers"], r)
54 return r
55 except (SSLError, RequestException) as e:
56 self._parent._market.report.log_http_request(args[0],
57 args[1], kwargs["data"], kwargs["headers"], e)
58 raise e
59
52 self.session.request = request_wrap.__get__(self.session, 60 self.session.request = request_wrap.__get__(self.session,
53 self.session.__class__) 61 self.session.__class__)
54 62
diff --git a/market.py b/market.py
index ac3aa14..10d1ad8 100644
--- a/market.py
+++ b/market.py
@@ -28,6 +28,9 @@ class Market:
28 for key in ["user_id", "market_id", "report_path", "pg_config"]: 28 for key in ["user_id", "market_id", "report_path", "pg_config"]:
29 setattr(self, key, kwargs.get(key, None)) 29 setattr(self, key, kwargs.get(key, None))
30 30
31 self.report.log_market(self.args, self.user_id, self.market_id,
32 self.report_path, self.debug)
33
31 @classmethod 34 @classmethod
32 def from_config(cls, config, args, **kwargs): 35 def from_config(cls, config, args, **kwargs):
33 config["apiKey"] = config.pop("key", None) 36 config["apiKey"] = config.pop("key", None)
diff --git a/store.py b/store.py
index b3ada45..3f3718f 100644
--- a/store.py
+++ b/store.py
@@ -176,15 +176,28 @@ class ReportStore:
176 }) 176 })
177 177
178 def log_http_request(self, method, url, body, headers, response): 178 def log_http_request(self, method, url, body, headers, response):
179 self.add_log({ 179 if isinstance(response, Exception):
180 "type": "http_request", 180 self.add_log({
181 "method": method, 181 "type": "http_request",
182 "url": url, 182 "method": method,
183 "body": body, 183 "url": url,
184 "headers": headers, 184 "body": body,
185 "status": response.status_code, 185 "headers": headers,
186 "response": response.text 186 "status": -1,
187 }) 187 "response": None,
188 "error": response.__class__.__name__,
189 "error_message": str(response),
190 })
191 else:
192 self.add_log({
193 "type": "http_request",
194 "method": method,
195 "url": url,
196 "body": body,
197 "headers": headers,
198 "status": response.status_code,
199 "response": response.text
200 })
188 201
189 def log_error(self, action, message=None, exception=None): 202 def log_error(self, action, message=None, exception=None):
190 self.print_log("[Error] {}".format(action)) 203 self.print_log("[Error] {}".format(action))
@@ -209,6 +222,17 @@ class ReportStore:
209 "action": action, 222 "action": action,
210 }) 223 })
211 224
225 def log_market(self, args, user_id, market_id, report_path, debug):
226 self.add_log({
227 "type": "market",
228 "commit": "$Format:%H$",
229 "args": vars(args),
230 "user_id": user_id,
231 "market_id": market_id,
232 "report_path": report_path,
233 "debug": debug,
234 })
235
212class BalanceStore: 236class BalanceStore:
213 def __init__(self, market): 237 def __init__(self, market):
214 self.market = market 238 self.market = market
diff --git a/test.py b/test.py
index a9a80c5..bf679bf 100644
--- a/test.py
+++ b/test.py
@@ -71,7 +71,8 @@ class poloniexETest(unittest.TestCase):
71 super().tearDown() 71 super().tearDown()
72 72
73 def test__init(self): 73 def test__init(self):
74 with mock.patch("market.ccxt.poloniexE.session") as session: 74 with self.subTest("Nominal case"), \
75 mock.patch("market.ccxt.poloniexE.session") as session:
75 session.request.return_value = "response" 76 session.request.return_value = "response"
76 ccxt = market.ccxt.poloniexE() 77 ccxt = market.ccxt.poloniexE()
77 ccxt._market = mock.Mock 78 ccxt._market = mock.Mock
@@ -82,6 +83,21 @@ class poloniexETest(unittest.TestCase):
82 ccxt._market.report.log_http_request.assert_called_with('GET', 'URL', 'data', 83 ccxt._market.report.log_http_request.assert_called_with('GET', 'URL', 'data',
83 'headers', 'response') 84 'headers', 'response')
84 85
86 with self.subTest("Raising"),\
87 mock.patch("market.ccxt.poloniexE.session") as session:
88 session.request.side_effect = market.ccxt.RequestException("Boo")
89
90 ccxt = market.ccxt.poloniexE()
91 ccxt._market = mock.Mock
92 ccxt._market.report = mock.Mock()
93
94 with self.assertRaises(market.ccxt.RequestException, msg="Boo") as cm:
95 ccxt.session.request("GET", "URL", data="data",
96 headers="headers")
97 ccxt._market.report.log_http_request.assert_called_with('GET', 'URL', 'data',
98 'headers', cm.exception)
99
100
85 def test_nanoseconds(self): 101 def test_nanoseconds(self):
86 with mock.patch.object(market.ccxt.time, "time") as time: 102 with mock.patch.object(market.ccxt.time, "time") as time:
87 time.return_value = 123456.7890123456 103 time.return_value = 123456.7890123456
@@ -1181,9 +1197,12 @@ class MarketTest(WebMockTestCase):
1181 with self.subTest(quiet=False): 1197 with self.subTest(quiet=False):
1182 m = market.Market(self.ccxt, self.market_args(quiet=False)) 1198 m = market.Market(self.ccxt, self.market_args(quiet=False))
1183 report_store.assert_called_with(m, verbose_print=True) 1199 report_store.assert_called_with(m, verbose_print=True)
1200 report_store().log_market.assert_called_once()
1201 report_store.reset_mock()
1184 with self.subTest(quiet=True): 1202 with self.subTest(quiet=True):
1185 m = market.Market(self.ccxt, self.market_args(quiet=True)) 1203 m = market.Market(self.ccxt, self.market_args(quiet=True))
1186 report_store.assert_called_with(m, verbose_print=False) 1204 report_store.assert_called_with(m, verbose_print=False)
1205 report_store().log_market.assert_called_once()
1187 1206
1188 @mock.patch("market.ccxt") 1207 @mock.patch("market.ccxt")
1189 def test_from_config(self, ccxt): 1208 def test_from_config(self, ccxt):
@@ -4346,6 +4365,40 @@ class ReportStoreTest(WebMockTestCase):
4346 'response': 'Hey' 4365 'response': 'Hey'
4347 }) 4366 })
4348 4367
4368 add_log.reset_mock()
4369 report_store.log_http_request("method", "url", "body",
4370 "headers", ValueError("Foo"))
4371 add_log.assert_called_once_with({
4372 'type': 'http_request',
4373 'method': 'method',
4374 'url': 'url',
4375 'body': 'body',
4376 'headers': 'headers',
4377 'status': -1,
4378 'response': None,
4379 'error': 'ValueError',
4380 'error_message': 'Foo',
4381 })
4382
4383 @mock.patch.object(market.ReportStore, "add_log")
4384 def test_log_market(self, add_log):
4385 report_store = market.ReportStore(self.m)
4386 class Args:
4387 def __init__(self):
4388 self.debug = True
4389 self.quiet = False
4390
4391 report_store.log_market(Args(), 4, 1, "report", True)
4392 add_log.assert_called_once_with({
4393 "type": "market",
4394 "commit": "$Format:%H$",
4395 "args": { "debug": True, "quiet": False },
4396 "user_id": 4,
4397 "market_id": 1,
4398 "report_path": "report",
4399 "debug": True
4400 })
4401
4349 @mock.patch.object(market.ReportStore, "print_log") 4402 @mock.patch.object(market.ReportStore, "print_log")
4350 @mock.patch.object(market.ReportStore, "add_log") 4403 @mock.patch.object(market.ReportStore, "add_log")
4351 def test_log_error(self, add_log, print_log): 4404 def test_log_error(self, add_log, print_log):