From 7059846843e3ebdc04b7a6f8c6249128c3942bf4 Mon Sep 17 00:00:00 2001 From: Davide Casale Date: Fri, 26 May 2023 18:48:27 +0200 Subject: [PATCH] Remove support for datetime type and improve typing in several files. --- .../endpoints/rest_authenticated_endpoints.py | 10 +++++--- bfxapi/types/__init__.py | 2 +- bfxapi/types/dataclasses.py | 4 +-- bfxapi/utils/json_encoder.py | 25 +++++++++---------- .../websocket/client/bfx_websocket_inputs.py | 9 +++---- 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/bfxapi/rest/endpoints/rest_authenticated_endpoints.py b/bfxapi/rest/endpoints/rest_authenticated_endpoints.py index db1c37e..acb4757 100644 --- a/bfxapi/rest/endpoints/rest_authenticated_endpoints.py +++ b/bfxapi/rest/endpoints/rest_authenticated_endpoints.py @@ -1,12 +1,12 @@ from typing import Dict, List, Tuple, Union, Literal, Optional + from decimal import Decimal -from datetime import datetime from ..middleware import Middleware from ..enums import Sort, OrderType, FundingOfferType -from ...types import JSON, Notification, \ +from ...types import Notification, \ UserInfo, LoginHistory, BalanceAvailable, \ Order, Position, Trade, \ FundingTrade, OrderTrade, Ledger, \ @@ -22,6 +22,8 @@ from ...types import serializers from ...types.serializers import _Notification +from ...utils.json_encoder import JSON + class RestAuthenticatedEndpoints(Middleware): def get_user_info(self) -> UserInfo: return serializers.UserInfo \ @@ -74,7 +76,7 @@ class RestAuthenticatedEndpoints(Middleware): gid: Optional[int] = None, cid: Optional[int] = None, flags: Optional[int] = 0, - tif: Optional[Union[datetime, str]] = None, + tif: Optional[str] = None, meta: Optional[JSON] = None) -> Notification[Order]: body = { "type": type, "symbol": symbol, "amount": amount, @@ -100,7 +102,7 @@ class RestAuthenticatedEndpoints(Middleware): delta: Optional[Union[Decimal, float, str]] = None, price_aux_limit: Optional[Union[Decimal, float, str]] = None, price_trailing: Optional[Union[Decimal, float, str]] = None, - tif: Optional[Union[datetime, str]] = None) -> Notification[Order]: + tif: Optional[str] = None) -> Notification[Order]: body = { "id": id, "amount": amount, "price": price, "cid": cid, "cid_date": cid_date, "gid": gid, diff --git a/bfxapi/types/__init__.py b/bfxapi/types/__init__.py index ce3ef06..2648d38 100644 --- a/bfxapi/types/__init__.py +++ b/bfxapi/types/__init__.py @@ -1,4 +1,4 @@ -from .dataclasses import JSON, \ +from .dataclasses import \ PlatformStatus, TradingPairTicker, FundingCurrencyTicker, \ TickersHistory, TradingPairTrade, FundingCurrencyTrade, \ TradingPairBook, FundingCurrencyBook, TradingPairRawBook, \ diff --git a/bfxapi/types/dataclasses.py b/bfxapi/types/dataclasses.py index 264de42..4c375e5 100644 --- a/bfxapi/types/dataclasses.py +++ b/bfxapi/types/dataclasses.py @@ -1,11 +1,11 @@ -from typing import Union, Type, \ +from typing import \ List, Dict, Literal, Optional, Any from dataclasses import dataclass from .labeler import _Type, partial, compose -JSON = Union[Dict[str, "JSON"], List["JSON"], bool, int, float, str, Type[None]] +from ..utils.json_encoder import JSON #region Dataclass definitions for types of public use diff --git a/bfxapi/utils/json_encoder.py b/bfxapi/utils/json_encoder.py index 3da4c99..9807480 100644 --- a/bfxapi/utils/json_encoder.py +++ b/bfxapi/utils/json_encoder.py @@ -1,33 +1,32 @@ import json + from decimal import Decimal -from datetime import datetime -from typing import Type, List, Dict, Union, Any +from typing import List, Dict, Union -JSON = Union[Dict[str, "JSON"], List["JSON"], bool, int, float, str, Type[None]] +JSON = Union[Dict[str, "JSON"], List["JSON"], bool, int, float, str, None] + +_CustomJSON = Union[Dict[str, "_CustomJSON"], List["_CustomJSON"], \ + bool, int, float, str, Decimal, None] def _strip(dictionary: Dict) -> Dict: return { key: value for key, value in dictionary.items() if value is not None } -def _convert_data_to_json(data: JSON) -> JSON: +def _convert_data_to_json(data: _CustomJSON) -> JSON: if isinstance(data, bool): return int(data) if isinstance(data, float): return format(Decimal(repr(data)), "f") + if isinstance(data, Decimal): + return format(data, "f") + if isinstance(data, list): return [ _convert_data_to_json(sub_data) for sub_data in data ] if isinstance(data, dict): return _strip({ key: _convert_data_to_json(value) for key, value in data.items() }) + return data class JSONEncoder(json.JSONEncoder): - def encode(self, o: JSON) -> str: + def encode(self, o: _CustomJSON) -> str: return json.JSONEncoder.encode(self, _convert_data_to_json(o)) - - def default(self, o: Any) -> Any: - if isinstance(o, Decimal): - return format(o, "f") - if isinstance(o, datetime): - return str(o) - - return json.JSONEncoder.default(self, o) diff --git a/bfxapi/websocket/client/bfx_websocket_inputs.py b/bfxapi/websocket/client/bfx_websocket_inputs.py index 0725f15..87d730b 100644 --- a/bfxapi/websocket/client/bfx_websocket_inputs.py +++ b/bfxapi/websocket/client/bfx_websocket_inputs.py @@ -5,12 +5,10 @@ if TYPE_CHECKING: from bfxapi.enums import \ OrderType, FundingOfferType - from bfxapi.types import JSON + from bfxapi.utils.json_encoder import JSON from decimal import Decimal - from datetime import datetime - class BfxWebSocketInputs: def __init__(self, handle_websocket_input: Callable[[str, Any], Awaitable[None]]) -> None: self.__handle_websocket_input = handle_websocket_input @@ -28,9 +26,8 @@ class BfxWebSocketInputs: gid: Optional[int] = None, cid: Optional[int] = None, flags: Optional[int] = 0, - tif: Optional[Union["datetime", str]] = None, + tif: Optional[str] = None, meta: Optional["JSON"] = None) -> None: - await self.__handle_websocket_input("on", { "type": type, "symbol": symbol, "amount": amount, "price": price, "lev": lev, "price_trailing": price_trailing, @@ -52,7 +49,7 @@ class BfxWebSocketInputs: delta: Optional[Union["Decimal", float, str]] = None, price_aux_limit: Optional[Union["Decimal", float, str]] = None, price_trailing: Optional[Union["Decimal", float, str]] = None, - tif: Optional[Union["datetime", str]] = None) -> None: + tif: Optional[str] = None) -> None: await self.__handle_websocket_input("ou", { "id": id, "amount": amount, "price": price, "cid": cid, "cid_date": cid_date, "gid": gid,