Add support for new rest public endpoints (in BfxRestInterface.py, serializers.py and typings.py).

This commit is contained in:
Davide Casale
2022-12-01 17:48:50 +01:00
parent 8e8719e3d7
commit ea6044a5eb
4 changed files with 186 additions and 14 deletions

View File

@@ -1,12 +1,62 @@
import requests
from http import HTTPStatus
from typing import List, Union, Optional
from . import serializers
from .typings import PlatformStatus
from .typings import PlatformStatus, TradingPairTicker, FundingCurrencyTicker, TickerHistory, TradingPairTrade, FundingCurrencyTrade
from .exceptions import RequestParametersError
class BfxRestInterface(object):
def __init__(self, host):
self.host = host
def __GET(self, endpoint, params = None):
data = requests.get(f"{self.host}/{endpoint}", params=params).json()
if data[0] == "error":
if data[1] == 10020:
raise RequestParametersError(f"The request was rejected with the following parameter error: <{data[2]}>")
return data
def platform_status(self) -> PlatformStatus:
return serializers.PlatformStatus.parse(
*requests.get(f"{self.host}/platform/status").json()
)
return serializers.PlatformStatus.parse(*self.__GET("platform/status"))
def tickers(self, symbols: List[str]) -> List[Union[TradingPairTicker, FundingCurrencyTicker]]:
return [
{
"t": serializers.TradingPairTicker.parse,
"f": serializers.FundingCurrencyTicker.parse
}[subdata[0][0]](*subdata)
for subdata in self.__GET("tickers", params={ "symbols": ",".join(symbols) })
]
def ticker(self, symbol: str) -> Union[TradingPairTicker, FundingCurrencyTicker]:
return {
"t": serializers.TradingPairTicker.parse,
"f": serializers.FundingCurrencyTicker.parse
}[symbol[0]](*self.__GET(f"ticker/{symbol}"), skip=["SYMBOL"])
def tickers_hist(self, symbols: List[str], start: Optional[int] = None, end: Optional[int] = None, limit: Optional[int] = None) -> List[TickerHistory]:
params = {
"symbols": ",".join(symbols),
"start": start, "end": end,
"limit": limit
}
return [ serializers.TickerHistory.parse(*subdata) for subdata in self.__GET("tickers/hist", params=params) ]
def trades(self, symbol: str, limit: Optional[int] = None, start: Optional[str] = None, end: Optional[str] = None, sort: Optional[int] = None) -> Union[List[TradingPairTrade], List[FundingCurrencyTicker]]:
params = { "symbol": symbol, "limit": limit, "start": start, "end": end, "sort": sort }
return [
{
"t": serializers.TradingPairTrade.parse,
"f": serializers.FundingCurrencyTrade.parse
}[symbol[0]](*subdata)
for subdata in self.__GET(f"trades/{symbol}/hist", params=params)
]

View File

@@ -1,6 +1,17 @@
__all__ = [
"RequestParametersError"
]
class BfxRestException(Exception):
"""
Base class for all exceptions defined in bfxapi/rest/exceptions.py.
"""
pass
class RequestParametersError(BfxRestException):
"""
This error indicates that there are some invalid parameters sent along with an HTTP request.
"""
pass

View File

@@ -1,4 +1,4 @@
from typing import Generic, TypeVar, Iterable, List, Any
from typing import Generic, TypeVar, Iterable, Optional, List, Any
from . import typings
@@ -7,19 +7,21 @@ from .exceptions import BfxRestException
T = TypeVar("T")
class _Serializer(Generic[T]):
def __init__(self, name: str, labels: List[str]):
self.name, self.__labels = name, labels
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, IGNORE: List[str] = [ "_PLACEHOLDER" ]) -> Iterable[T]:
if len(self.__labels) != len(args):
raise BfxRestException("<self.__labels> and <*args> arguments should contain the same amount of elements.")
def __serialize(self, *args: Any, skip: Optional[List[str]]) -> Iterable[T]:
labels = list(filter(lambda label: label not in (skip or list()), self.__labels))
for index, label in enumerate(self.__labels):
if label not in IGNORE:
if len(labels) != len(args):
raise BfxRestException("<labels> and <*args> arguments should contain the same amount of elements.")
for index, label in enumerate(labels):
if label not in self.__IGNORE:
yield label, args[index]
def parse(self, *values: Any) -> T:
return dict(self.__serialize(*values))
def parse(self, *values: Any, skip: Optional[List[str]] = None) -> T:
return dict(self.__serialize(*values, skip=skip))
#region Serializers definition for Rest Public Endpoints
@@ -27,4 +29,69 @@ PlatformStatus = _Serializer[typings.PlatformStatus]("PlatformStatus", labels=[
"OPERATIVE"
])
TradingPairTicker = _Serializer[typings.TradingPairTicker]("TradingPairTicker", labels=[
"SYMBOL",
"BID",
"BID_SIZE",
"ASK",
"ASK_SIZE",
"DAILY_CHANGE",
"DAILY_CHANGE_RELATIVE",
"LAST_PRICE",
"VOLUME",
"HIGH",
"LOW"
])
FundingCurrencyTicker = _Serializer[typings.FundingCurrencyTicker]("FundingCurrencyTicker", labels=[
"SYMBOL",
"FRR",
"BID",
"BID_PERIOD",
"BID_SIZE",
"ASK",
"ASK_PERIOD",
"ASK_SIZE",
"DAILY_CHANGE",
"DAILY_CHANGE_RELATIVE",
"LAST_PRICE",
"VOLUME",
"HIGH",
"LOW",
"_PLACEHOLDER",
"_PLACEHOLDER",
"FRR_AMOUNT_AVAILABLE"
])
TickerHistory = _Serializer[typings.TickerHistory]("TickerHistory", labels=[
"SYMBOL",
"BID",
"_PLACEHOLDER",
"ASK",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"MTS"
])
TradingPairTrade = _Serializer[typings.TradingPairTrade]("TradingPairTrade", labels=[
"ID",
"MTS",
"AMOUNT",
"PRICE"
])
FundingCurrencyTrade = _Serializer[typings.FundingCurrencyTrade]("FundingCurrencyTrade", labels=[
"ID",
"MTS",
"AMOUNT",
"RATE",
"PERIOD"
])
#endregion

View File

@@ -6,4 +6,48 @@ PlatformStatus = TypedDict("PlatformStatus", {
"OPERATIVE": int
})
TradingPairTicker = TypedDict("TradingPairTicker", {
"SYMBOL": Optional[str],
"BID": float,
"BID_SIZE": float,
"ASK": float,
"ASK_SIZE": float,
"DAILY_CHANGE": float,
"DAILY_CHANGE_RELATIVE": float,
"LAST_PRICE": float,
"VOLUME": float,
"HIGH": float,
"LOW": float
})
FundingCurrencyTicker = TypedDict("FundingCurrencyTicker", {
"SYMBOL": Optional[str],
"FRR": float,
"BID": float,
"BID_PERIOD": int,
"BID_SIZE": float,
"ASK": float,
"ASK_PERIOD": int,
"ASK_SIZE": float,
"DAILY_CHANGE": float,
"DAILY_CHANGE_RELATIVE": float,
"LAST_PRICE": float,
"VOLUME": float,
"HIGH": float,
"LOW": float,
"FRR_AMOUNT_AVAILABLE": float
})
TickerHistory = TypedDict("TickerHistory", {
"SYMBOL": str,
"BID": float,
"ASK": float,
"MTS": int
})
(TradingPairTrade, FundingCurrencyTrade) = (
TypedDict("TradingPairTrade", { "ID": int, "MTS": int, "AMOUNT": float, "PRICE": float }),
TypedDict("FundingCurrencyTrade", { "ID": int, "MTS": int, "AMOUNT": float, "RATE": float, "PERIOD": int })
)
#endregion