From 0bb9f65a190656d1707f9a0cedf6ee98f5a2c401 Mon Sep 17 00:00:00 2001 From: Davide Casale Date: Mon, 16 Jan 2023 16:30:06 +0100 Subject: [PATCH] Replace SimpleNamespaces with dataclasses. Add base class _Typing in labeler.py to convert dictionaries to dataclasses. Remove SimpleNamespace references. --- bfxapi/labeler.py | 9 +++-- bfxapi/notification.py | 13 +++---- bfxapi/rest/typings.py | 80 ++++++++++++++++++++++++++++-------------- 3 files changed, 66 insertions(+), 36 deletions(-) diff --git a/bfxapi/labeler.py b/bfxapi/labeler.py index 8a5845e..160e054 100644 --- a/bfxapi/labeler.py +++ b/bfxapi/labeler.py @@ -2,10 +2,13 @@ from .exceptions import LabelerSerializerException from typing import Generic, TypeVar, Iterable, Optional, List, Tuple, Any, cast -from types import SimpleNamespace - T = TypeVar("T") +class _Typing(object): + def __init__(self, **kwargs): + for key, value in kwargs.items(): + self.__setattr__(key,value) + class _Serializer(Generic[T]): def __init__(self, name: str, labels: List[str], IGNORE: List[str] = [ "_PLACEHOLDER" ]): self.name, self.__labels, self.__IGNORE = name, labels, IGNORE @@ -21,4 +24,4 @@ class _Serializer(Generic[T]): yield label, args[index] def parse(self, *values: Any, skip: Optional[List[str]] = None) -> T: - return cast(T, SimpleNamespace(**dict(self._serialize(*values, skip=skip)))) \ No newline at end of file + return cast(T, _Typing(**dict(self._serialize(*values, skip=skip)))) \ No newline at end of file diff --git a/bfxapi/notification.py b/bfxapi/notification.py index 413f1b6..b8cdb37 100644 --- a/bfxapi/notification.py +++ b/bfxapi/notification.py @@ -1,12 +1,13 @@ from typing import List, Dict, Union, Optional, Any, TypedDict, Generic, TypeVar, cast -from types import SimpleNamespace +from dataclasses import dataclass -from .labeler import _Serializer +from .labeler import _Typing, _Serializer T = TypeVar("T") -class Notification(SimpleNamespace, Generic[T]): +@dataclass +class Notification(_Typing, Generic[T]): MTS: int TYPE: str MESSAGE_ID: Optional[int] @@ -24,7 +25,7 @@ class _Notification(_Serializer, Generic[T]): self.serializer, self.iterate = serializer, iterate def parse(self, *values: Any, skip: Optional[List[str]] = None) -> Notification[T]: - notification = cast(Notification[T], SimpleNamespace(**dict(self._serialize(*values)))) + notification = cast(Notification[T], _Typing(**dict(self._serialize(*values)))) if isinstance(self.serializer, _Serializer): NOTIFY_INFO = cast(List[Any], notification.NOTIFY_INFO) @@ -33,7 +34,7 @@ class _Notification(_Serializer, Generic[T]): if len(NOTIFY_INFO) == 1 and isinstance(NOTIFY_INFO[0], list): NOTIFY_INFO = NOTIFY_INFO[0] - notification.NOTIFY_INFO = cast(T, SimpleNamespace(**dict(self.serializer._serialize(*NOTIFY_INFO, skip=skip)))) - else: notification.NOTIFY_INFO = cast(T, [ SimpleNamespace(**dict(self.serializer._serialize(*data, skip=skip))) for data in NOTIFY_INFO ]) + notification.NOTIFY_INFO = cast(T, _Typing(**dict(self.serializer._serialize(*NOTIFY_INFO, skip=skip)))) + else: notification.NOTIFY_INFO = cast(T, [ _Typing(**dict(self.serializer._serialize(*data, skip=skip))) for data in NOTIFY_INFO ]) return notification \ No newline at end of file diff --git a/bfxapi/rest/typings.py b/bfxapi/rest/typings.py index 1685b04..ef397a9 100644 --- a/bfxapi/rest/typings.py +++ b/bfxapi/rest/typings.py @@ -1,6 +1,8 @@ from typing import Type, Tuple, List, Dict, TypedDict, Union, Optional, Any -from types import SimpleNamespace +from dataclasses import dataclass + +from .. labeler import _Typing from .. notification import Notification @@ -8,10 +10,12 @@ JSON = Union[Dict[str, "JSON"], List["JSON"], bool, int, float, str, Type[None]] #region Type hinting for Rest Public Endpoints -class PlatformStatus(SimpleNamespace): +@dataclass +class PlatformStatus(_Typing): OPERATIVE: int -class TradingPairTicker(SimpleNamespace): +@dataclass +class TradingPairTicker(_Typing): SYMBOL: Optional[str] BID: float BID_SIZE: float @@ -24,7 +28,8 @@ class TradingPairTicker(SimpleNamespace): HIGH: float LOW: float -class FundingCurrencyTicker(SimpleNamespace): +@dataclass +class FundingCurrencyTicker(_Typing): SYMBOL: Optional[str] FRR: float BID: float @@ -41,52 +46,61 @@ class FundingCurrencyTicker(SimpleNamespace): LOW: float FRR_AMOUNT_AVAILABLE: float -class TickersHistory(SimpleNamespace): +@dataclass +class TickersHistory(_Typing): SYMBOL: str BID: float ASK: float MTS: int -class TradingPairTrade(SimpleNamespace): +@dataclass +class TradingPairTrade(_Typing): ID: int MTS: int AMOUNT: float PRICE: float -class FundingCurrencyTrade(SimpleNamespace): +@dataclass +class FundingCurrencyTrade(_Typing): ID: int MTS: int AMOUNT: float RATE: float PERIOD: int -class TradingPairBook(SimpleNamespace): +@dataclass +class TradingPairBook(_Typing): PRICE: float COUNT: int AMOUNT: float -class FundingCurrencyBook(SimpleNamespace): +@dataclass +class FundingCurrencyBook(_Typing): RATE: float PERIOD: int COUNT: int AMOUNT: float - -class TradingPairRawBook(SimpleNamespace): + +@dataclass +class TradingPairRawBook(_Typing): ORDER_ID: int PRICE: float AMOUNT: float - -class FundingCurrencyRawBook(SimpleNamespace): + +@dataclass +class FundingCurrencyRawBook(_Typing): OFFER_ID: int PERIOD: int RATE: float AMOUNT: float -class Statistic(SimpleNamespace): +@dataclass +class Statistic(_Typing): MTS: int VALUE: float -class Candle(SimpleNamespace): +@dataclass +class Candle(_Typing): MTS: int OPEN: float CLOSE: float @@ -94,7 +108,8 @@ class Candle(SimpleNamespace): LOW: float VOLUME: float -class DerivativesStatus(SimpleNamespace): +@dataclass +class DerivativesStatus(_Typing): KEY: Optional[str] MTS: int DERIV_PRICE: float @@ -109,7 +124,8 @@ class DerivativesStatus(SimpleNamespace): CLAMP_MIN: float CLAMP_MAX: float -class Liquidation(SimpleNamespace): +@dataclass +class Liquidation(_Typing): POS_ID: int MTS: int SYMBOL: str @@ -119,14 +135,16 @@ class Liquidation(SimpleNamespace): IS_MARKET_SOLD: int PRICE_ACQUIRED: float -class Leaderboard(SimpleNamespace): +@dataclass +class Leaderboard(_Typing): MTS: int USERNAME: str RANKING: int VALUE: float TWITTER_HANDLE: Optional[str] -class FundingStatistic(SimpleNamespace): +@dataclass +class FundingStatistic(_Typing): TIMESTAMP: int FRR: float AVG_PERIOD: float @@ -138,7 +156,8 @@ class FundingStatistic(SimpleNamespace): #region Type hinting for Rest Authenticated Endpoints -class Wallet(SimpleNamespace): +@dataclass +class Wallet(_Typing): WALLET_TYPE: str CURRENCY: str BALANCE: float @@ -147,7 +166,8 @@ class Wallet(SimpleNamespace): LAST_CHANGE: str TRADE_DETAILS: JSON -class Order(SimpleNamespace): +@dataclass +class Order(_Typing): ID: int GID: int CID: int @@ -171,7 +191,8 @@ class Order(SimpleNamespace): ROUTING: str META: JSON -class Position(SimpleNamespace): +@dataclass +class Position(_Typing): SYMBOL: str STATUS: str AMOUNT: float @@ -190,7 +211,8 @@ class Position(SimpleNamespace): COLLATERAL_MIN: float META: JSON -class FundingOffer(SimpleNamespace): +@dataclass +class FundingOffer(_Typing): ID: int SYMBOL: str MTS_CREATE: int @@ -206,7 +228,8 @@ class FundingOffer(SimpleNamespace): HIDDEN: int RENEW: bool -class Trade(SimpleNamespace): +@dataclass +class Trade(_Typing): ID: int SYMBOL: str MTS_CREATE: int @@ -220,7 +243,8 @@ class Trade(SimpleNamespace): FEE_CURRENCY: str CID: int -class OrderTrade(SimpleNamespace): +@dataclass +class OrderTrade(_Typing): ID: int SYMBOL: str MTS_CREATE: int @@ -232,7 +256,8 @@ class OrderTrade(SimpleNamespace): FEE_CURRENCY: str CID: int -class Ledger(SimpleNamespace): +@dataclass +class Ledger(_Typing): ID: int CURRENCY: str MTS: int @@ -240,7 +265,8 @@ class Ledger(SimpleNamespace): BALANCE: float description: str -class FundingCredit(SimpleNamespace): +@dataclass +class FundingCredit(_Typing): ID: int SYMBOL: str SIDE: int