Skip to content

Commit 749ceea

Browse files
committed
fix: spot order list
feat: spot balance subscription chore: sort imports refactor: only optional dataclasses fields have None as default feat: websocket connection with timeout feat: websocket authentication with timeout
1 parent c708107 commit 749ceea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1238
-1302
lines changed

cryptomarket/args.py

Lines changed: 77 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
11
from dataclasses import asdict, dataclass
2-
from email.policy import strict
32
from enum import Enum
4-
import json
5-
from typing import List, Literal
6-
from cryptomarket.dataclasses.aclSettings import ACLSettings
7-
from cryptomarket.dataclasses.order import Order
3+
from typing import Any, Dict, List, Optional
84

95
from cryptomarket.exceptions import ArgumentFormatException
106

117

12-
class CHECKER(str, Enum):
8+
class Checker(str, Enum):
139
@classmethod
1410
def check_value(cls, value):
1511
if value not in cls._value2member_map_:
1612
raise ArgumentFormatException(f'invalid {cls.__name__} argument.', [
1713
item.value for item in cls])
1814

1915

20-
class TRANSFER_TYPE(CHECKER):
16+
class TransferType(Checker):
2117
TO_SUB_ACCOUNT = 'to_sub_account'
2218
FROM_SUB_ACCOUNT = 'from_sub_account'
2319

2420

25-
class CONTINGENCY_TYPE(CHECKER):
21+
class ContingencyType(Checker):
2622
ALL_OR_NONE = "allOrNone"
2723
AON = "allOrNone"
2824
ONE_CANCEL_OTHER = "oneCancelOther"
@@ -33,12 +29,12 @@ class CONTINGENCY_TYPE(CHECKER):
3329
OTOCO = "oneTriggerOneCancelOther"
3430

3531

36-
class SORT(CHECKER):
32+
class Sort(Checker):
3733
ASCENDING = 'ASC'
3834
DESCENDING = 'DESC'
3935

4036

41-
class PERIOD(CHECKER):
37+
class Period(Checker):
4238
_1_MINS = 'M1'
4339
_3_MINS = 'M3'
4440
_5_MINS = 'M5'
@@ -51,12 +47,12 @@ class PERIOD(CHECKER):
5147
_1_MONTHS = '1M'
5248

5349

54-
class SIDE(CHECKER):
50+
class Side(Checker):
5551
BUY = 'buy'
5652
SELL = 'sell'
5753

5854

59-
class ORDER_TYPE(CHECKER):
55+
class OrderType(Checker):
6056
LIMIT = 'limit'
6157
MARKET = 'market'
6258
STOP_LIMIT = 'stopLimit'
@@ -65,49 +61,49 @@ class ORDER_TYPE(CHECKER):
6561
TAKE_PROFIT_MARKET = 'takeProfitMarket'
6662

6763

68-
class TIME_IN_FORCE(CHECKER):
64+
class TimeInForce(Checker):
6965
GTC = 'GTC' # Good till canceled
7066
IOC = 'IOC' # Immediate or cancell
7167
FOK = 'FOK' # Fill or kill
7268
DAY = 'Day' # Good for the day
7369
GTD = 'GDT' # Good till date
7470

7571

76-
class IDENTIFY_BY(CHECKER):
77-
USERNAME = 'username',
72+
class IdentifyBy(Checker):
73+
USERNAME = 'username'
7874
EMAIL = 'email'
7975

8076

81-
class OFFCHAIN(CHECKER):
77+
class Offchain(Checker):
8278
NEVER = 'never'
8379
OPTIONALLY = 'optionally'
8480
REQUIRED = 'required'
8581

8682

87-
class ACCOUNT(CHECKER):
88-
SPOT = 'spot',
83+
class Account(Checker):
84+
SPOT = 'spot'
8985
WALLET = 'wallet'
9086

9187

92-
class TICKER_SPEED(CHECKER):
88+
class TickerSpeed(Checker):
9389
_1_SECOND = '1s'
9490
_3_SECONDS = '3s'
9591

9692

97-
class ORDERBOOK_SPEED(CHECKER):
93+
class OrderbookSpeed(Checker):
9894
_100_MILISECONDS = '100ms'
9995
_500_MILISECONDS = '500ms'
10096
_1000_MILISECONDS = '1000ms'
10197

10298

103-
class TRANSACTION_TYPE(CHECKER):
99+
class TransactionType(Checker):
104100
DEPOSIT = 'DEPOSIT'
105101
WITHDRAW = 'WITHDRAW'
106102
TRANSFER = 'TRANSFER'
107103
SAWAP = 'SAWAP'
108104

109105

110-
class TRANSACTION_SUBTYPE(CHECKER):
106+
class TransactionSubType(Checker):
111107
UNCLASSIFIED = 'UNCLASSIFIED'
112108
BLOCKCHAIN = 'BLOCKCHAIN'
113109
AIRDROP = 'AIRDROP'
@@ -126,41 +122,60 @@ class TRANSACTION_SUBTYPE(CHECKER):
126122
INSTANT_EXCHANGE = 'INSTANT_EXCHANGE'
127123

128124

129-
class TRANSACTION_STATUS(CHECKER):
125+
class TransactionStatus(Checker):
130126
CREATED = 'CREATED'
131127
PENDING = 'PENDING'
132128
FAILED = 'FAILED'
133129
SUCCESS = 'SUCCESS'
134130
ROLLED_BACK = 'ROLLED_BACK'
135131

136132

137-
class SORT_BY(CHECKER):
138-
TIMESTAMP = "timestamp",
133+
class SortBy(Checker):
134+
TIMESTAMP = "timestamp"
139135
CREATED_AT = 'created_at'
140136
ID = 'id'
141137

142138

143-
class DEPTH(CHECKER):
144-
_5 = 'D5',
145-
_10 = 'D10',
146-
_20 = 'D20',
139+
class Depth(Checker):
140+
_5 = 'D5'
141+
_10 = 'D10'
142+
_20 = 'D20'
143+
144+
145+
class SubscriptionMode(Checker):
146+
UPDATES = "updates"
147+
BATCHES = "batches"
147148

148149

149150
@dataclass
150151
class OrderRequest:
151152
symbol: str
152-
side: SIDE
153+
side: Side
153154
quantity: str
154-
client_order_id: str = None
155-
type: ORDER_TYPE = None
156-
time_in_force: TIME_IN_FORCE = None
157-
price: str = None
158-
expire_time: str = None
159-
stop_price: str = None
160-
strict_validate: bool = None
161-
post_only: bool = None
162-
take_rate: str = None
163-
make_rate: str = None
155+
client_order_id: Optional[str] = None
156+
type: Optional[OrderType] = None
157+
time_in_force: Optional[TimeInForce] = None
158+
price: Optional[str] = None
159+
expire_time: Optional[str] = None
160+
stop_price: Optional[str] = None
161+
strict_validate: Optional[bool] = None
162+
post_only: Optional[bool] = None
163+
take_rate: Optional[str] = None
164+
make_rate: Optional[str] = None
165+
166+
167+
@dataclass
168+
class ACLSettings:
169+
sub_account_id: str = None
170+
deposit_address_generation_enabled: bool = None
171+
withdraw_enabled: bool = None
172+
description: str = None
173+
created_at: str = None
174+
updated_at: str = None
175+
176+
177+
def clean_nones(a_dict: Dict[Any, Optional[Any]]) -> Dict[Any, Any]:
178+
return {k: v for k, v in a_dict.items() if v is not None}
164179

165180

166181
class DictBuilder:
@@ -181,7 +196,7 @@ def add_coma_separated_list(self, key, val: List[str]):
181196
self.the_dict[key] = query
182197
return self
183198

184-
def add_coma_separated_list_checking(self, checker: CHECKER, key, val: List[str]):
199+
def add_coma_separated_list_checking(self, checker: Checker, key, val: List[str]):
185200
if val is not None:
186201
for element in val:
187202
checker.check_value(element)
@@ -196,7 +211,7 @@ def add(self, key, val):
196211
self.the_dict[key] = val
197212
return self
198213

199-
def add_cheking(self, checker: CHECKER, key, val):
214+
def add_cheking(self, checker: Checker, key, val):
200215
if val is not None:
201216
checker.check_value(val)
202217
self.the_dict[key] = val
@@ -221,10 +236,10 @@ def symbol(self, val: str):
221236
return self.add("symbol", val)
222237

223238
def period(self, val: str):
224-
return self.add_cheking(PERIOD, 'period', val)
239+
return self.add_cheking(Period, 'period', val)
225240

226241
def sort(self, val: str):
227-
return self.add_cheking(SORT, 'sort', val)
242+
return self.add_cheking(Sort, 'sort', val)
228243

229244
def since(self, val: str):
230245
return self.add("from", val)
@@ -248,10 +263,10 @@ def volume(self, val: str):
248263
return self.add("volume", val)
249264

250265
def side(self, val: str):
251-
return self.add_cheking(SIDE, 'side', val)
266+
return self.add_cheking(Side, 'side', val)
252267

253268
def order_type(self, val: str):
254-
return self.add_cheking(ORDER_TYPE, 'type', val)
269+
return self.add_cheking(OrderType, 'type', val)
255270

256271
def quantity(self, val: str):
257272
return self.add("quantity", val)
@@ -263,7 +278,7 @@ def stop_price(self, val: str):
263278
return self.add("stop_price", val)
264279

265280
def time_in_force(self, val: str):
266-
return self.add_cheking(TIME_IN_FORCE, 'time_in_force', val)
281+
return self.add_cheking(TimeInForce, 'time_in_force', val)
267282

268283
def expire_time(self, val: str):
269284
return self.add("expire_time", val)
@@ -311,13 +326,13 @@ def to_currency(self, val: str):
311326
return self.add("to_currency", val)
312327

313328
def source(self, val: str):
314-
return self.add_cheking(ACCOUNT, "source", val)
329+
return self.add_cheking(Account, "source", val)
315330

316331
def destination(self, val: str):
317-
return self.add_cheking(ACCOUNT, "destination", val)
332+
return self.add_cheking(Account, "destination", val)
318333

319334
def identify_by(self, val: str):
320-
return self.add_cheking(IDENTIFY_BY, 'by', val)
335+
return self.add_cheking(IdentifyBy, 'by', val)
321336

322337
def identifier(self, val: str):
323338
return self.add("identifier", val)
@@ -344,7 +359,7 @@ def order_id(self, val: str):
344359
return self.add("order_id", val)
345360

346361
def use_offchain(self, val: str):
347-
return self.add_cheking(OFFCHAIN, 'use_offchain', val)
362+
return self.add_cheking(Offchain, 'use_offchain', val)
348363

349364
def public_comment(self, val: str):
350365
return self.add("public_comment", val)
@@ -353,19 +368,19 @@ def symbols_as_list(self, val: List[str]):
353368
return self.add('symbols', val)
354369

355370
def transaction_type(self, val: List[str]):
356-
return self.add_cheking(TRANSACTION_TYPE, 'type', val)
371+
return self.add_cheking(TransactionType, 'type', val)
357372

358373
def transaction_types(self, val: List[str]):
359-
return self.add_coma_separated_list_checking(TRANSACTION_TYPE, 'types', val)
374+
return self.add_coma_separated_list_checking(TransactionType, 'types', val)
360375

361376
def transaction_subtype(self, val: str):
362-
return self.add_cheking(TRANSACTION_SUBTYPE, 'subtype', val)
377+
return self.add_cheking(TransactionSubType, 'subtype', val)
363378

364379
def transaction_subtypes(self, val: str):
365-
return self.add_coma_separated_list_checking(TRANSACTION_SUBTYPE, 'subtypes', val)
380+
return self.add_coma_separated_list_checking(TransactionSubType, 'subtypes', val)
366381

367382
def transaction_statuses(self, val: str):
368-
return self.add_coma_separated_list_checking(TRANSACTION_STATUS, 'statuses', val)
383+
return self.add_coma_separated_list_checking(TransactionStatus, 'statuses', val)
369384

370385
def id_from(self, val: str):
371386
return self.add('id_from', val)
@@ -378,7 +393,7 @@ def tx_ids(self, val: List[str]):
378393

379394
# TODO: choose one, sort_by or order_by, and make it constant throughout the sdk.
380395
def sort_by(self, val: str):
381-
return self.add_cheking(SORT_BY, 'order_by', val)
396+
return self.add_cheking(SortBy, 'order_by', val)
382397

383398
def base_currency(self, val: str):
384399
return self.add('base_currency', val)
@@ -396,17 +411,20 @@ def order_list_id(self, val: str):
396411
return self.add('order_list_id', val)
397412

398413
def contingency_type(self, val: str):
399-
return self.add_cheking(CONTINGENCY_TYPE, 'contingency_type', val)
414+
return self.add_cheking(ContingencyType, 'contingency_type', val)
400415

401416
def orders(self, val: List[OrderRequest]):
402-
return self.add('orders', json.dumps([asdict(order) for order in val]))
417+
return self.add('orders', [clean_nones(asdict(order)) for order in val])
403418

404419
def sub_account_ids(self, val: List[str]):
405420
return self.add_coma_separated_list('sub_account_ids', val)
406421

407422
def sub_account_id(self, val: str):
408423
return self.add('sub_account_id', val)
409424

425+
def subscription_mode(self, val: str):
426+
return self.add_cheking(SubscriptionMode, 'mode', val)
427+
410428
def type(self, val: str):
411429
return self.add('type', val)
412430

0 commit comments

Comments
 (0)