diff --git a/bfxapi/labeler.py b/bfxapi/labeler.py index bcf18c3..4575146 100644 --- a/bfxapi/labeler.py +++ b/bfxapi/labeler.py @@ -8,7 +8,7 @@ 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 - def __serialize(self, *args: Any, skip: Optional[List[str]]) -> Iterable[Tuple[str, Any]]: + def _serialize(self, *args: Any, skip: Optional[List[str]] = None) -> Iterable[Tuple[str, Any]]: labels = list(filter(lambda label: label not in (skip or list()), self.__labels)) if len(labels) > len(args): @@ -19,4 +19,4 @@ class _Serializer(Generic[T]): yield label, args[index] def parse(self, *values: Any, skip: Optional[List[str]] = None) -> T: - return cast(T, dict(self.__serialize(*values, skip=skip))) \ No newline at end of file + return cast(T, dict(self._serialize(*values, skip=skip))) \ No newline at end of file diff --git a/bfxapi/notification.py b/bfxapi/notification.py new file mode 100644 index 0000000..003867b --- /dev/null +++ b/bfxapi/notification.py @@ -0,0 +1,28 @@ +from typing import Dict, Optional, Any, TypedDict, cast + +from .labeler import _Serializer + +class Notification(TypedDict): + MTS: int + TYPE: str + MESSAGE_ID: Optional[int] + NOTIFY_INFO: Dict[str, Any] + CODE: Optional[int] + STATUS: str + TEXT: str + +class _Notification(_Serializer): + __LABELS = [ "MTS", "TYPE", "MESSAGE_ID", "_PLACEHOLDER", "NOTIFY_INFO", "CODE", "STATUS", "TEXT" ] + + def __init__(self, serializer: Optional[_Serializer] = None): + super().__init__("Notification", _Notification.__LABELS, IGNORE = [ "_PLACEHOLDER" ]) + + self.serializer = serializer + + def parse(self, *values: Any) -> Notification: + notification = dict(self._serialize(*values)) + + if self.serializer != None: + notification["NOTIFY_INFO"] = dict(self.serializer._serialize(*notification["NOTIFY_INFO"])) + + return cast(Notification, notification) \ No newline at end of file diff --git a/bfxapi/rest/BfxRestInterface.py b/bfxapi/rest/BfxRestInterface.py index 4eed8b7..daf7c4e 100644 --- a/bfxapi/rest/BfxRestInterface.py +++ b/bfxapi/rest/BfxRestInterface.py @@ -1,5 +1,7 @@ import time, hmac, hashlib, json, requests +from decimal import Decimal +from datetime import datetime from http import HTTPStatus from typing import List, Union, Literal, Optional, Any, cast @@ -10,6 +12,8 @@ from .typings import * from .enums import OrderType, Config, Precision, Sort from .exceptions import ResourceNotFound, RequestParametersError, InvalidAuthenticationCredentials, UnknownGenericError +from .. utils.integers import Int16, Int32, Int45, Int64 + from .. utils.encoder import JSONEncoder class BfxRestInterface(object): @@ -254,7 +258,7 @@ class _RestAuthenticatedEndpoints(_Requests): "flags": flags, "tif": tif, "meta": meta } - return serializers.Notification.parse(*self._POST("auth/w/order/submit", data=data)) + return serializers._Notification(serializer=serializers.Order).parse(*self._POST("auth/w/order/submit", data=data)) def update_order(self, id: Union[Int64, int], amount: Optional[Union[Decimal, str]] = None, price: Optional[Union[Decimal, str]] = None, cid: Optional[Union[Int45, int]] = None, cid_date: Optional[str] = None, gid: Optional[Union[Int32, int]] = None, @@ -267,7 +271,7 @@ class _RestAuthenticatedEndpoints(_Requests): "price_aux_limit": price_aux_limit, "price_trailing": price_trailing, "tif": tif } - return serializers.Notification.parse(*self._POST("auth/w/order/update", data=data)) + return serializers._Notification(serializer=serializers.Order).parse(*self._POST("auth/w/order/update", data=data)) def cancel_order(self, id: Union[Int64, int]) -> Notification: - return serializers.Notification.parse(*self._POST("auth/w/order/cancel", data={ "id": id })) \ No newline at end of file + return serializers._Notification(serializer=serializers.Order).parse(*self._POST("auth/w/order/cancel", data={ "id": id })) \ No newline at end of file diff --git a/bfxapi/rest/serializers.py b/bfxapi/rest/serializers.py index fe7d5a7..3abea89 100644 --- a/bfxapi/rest/serializers.py +++ b/bfxapi/rest/serializers.py @@ -2,6 +2,8 @@ from . import typings from .. labeler import _Serializer +from .. notification import _Notification + #region Serializers definition for Rest Public Endpoints PlatformStatus = _Serializer[typings.PlatformStatus]("PlatformStatus", labels=[ @@ -232,19 +234,4 @@ Order = _Serializer[typings.Order]("Order", labels=[ "META" ]) -#endregion - -#region Serializers definition for Notifications channel - -Notification = _Serializer[typings.Notification]("Notification", labels=[ - "MTS", - "TYPE", - "MESSAGE_ID", - "_PLACEHOLDER", - "NOTIFY_INFO", - "CODE", - "STATUS", - "TEXT" -]) - #endregion \ No newline at end of file diff --git a/bfxapi/rest/typings.py b/bfxapi/rest/typings.py index 468a44e..f99b7c1 100644 --- a/bfxapi/rest/typings.py +++ b/bfxapi/rest/typings.py @@ -1,5 +1,7 @@ from typing import Type, Tuple, List, Dict, TypedDict, Union, Optional, Any +from .. notification import Notification + JSON = Union[Dict[str, "JSON"], List["JSON"], bool, int, float, str, Type[None]] #region Type hinting for Rest Public Endpoints @@ -167,17 +169,4 @@ class Order(TypedDict): ROUTING: str META: JSON -#endregion - -#region Type hinting for Notifications channel - -class Notification(TypedDict): - MTS: int - TYPE: str - MESSAGE_ID: int - NOTIFY_INFO: JSON - CODE: int - STATUS: str - TEXT: str - #endregion \ No newline at end of file