diff --git a/client/python/upbit/authentication.py b/client/python/upbit/authentication.py index d447d57..f1e2270 100644 --- a/client/python/upbit/authentication.py +++ b/client/python/upbit/authentication.py @@ -8,11 +8,11 @@ from bravado.requests_client import Authenticator -MAPPER = 'swg_mapper.json' -QUERY_PARAMS = ['uuids', 'txids', 'identifiers', 'states'] +class APIKeyAuthenticator(Authenticator): + MAPPER = "swg_mapper.json" + QUERY_PARAMS = tuple("uuids", "txids", "identifiers", "states") -class APIKeyAuthenticator(Authenticator): def __init__( self, @@ -23,23 +23,26 @@ def __init__( super(APIKeyAuthenticator, self).__init__(host) - self.host = host + self.host = host self.access_key = access_key self.secret_key = secret_key + def matches(self, url): - return MAPPER not in url + return APIKeyAuthenticator.MAPPER not in url + def apply(self, request): payload = self.generate_payload(request) - request.headers['User-Agent' ] = "ujhin's Upbit SDKs" - request.headers['Accept-Encoding'] = 'gzip, deflate' - request.headers['Accept' ] = '*/*' - request.headers['Connection' ] = 'keep-alive' - request.headers['Authorization' ] = payload + request.headers["User-Agent" ] = "ujhin's Upbit SDKs" + request.headers["Accept-Encoding"] = "gzip, deflate" + request.headers["Accept" ] = "*/*" + request.headers["Connection" ] = "keep-alive" + request.headers["Authorization" ] = payload return request + def generate_payload(self, request): params = request.params data = request.data @@ -57,20 +60,21 @@ def generate_payload(self, request): sha512.update(query.encode()) query_hash = sha512.hexdigest() - payload['query_hash' ] = query_hash - payload['query_hash_alg'] = 'SHA512' + payload["query_hash" ] = query_hash + payload["query_hash_alg"] = "SHA512" jwt_token = jwt.encode(payload, self.secret_key) authorize_token = f"Bearer {jwt_token}" return authorize_token + def generate_query(self, params): query = urlencode({ k: v for k, v in params.items() - if k not in QUERY_PARAMS + if k.lower() not in APIKeyAuthenticator.QUERY_PARAMS }) - for query_param in QUERY_PARAMS: + for query_param in APIKeyAuthenticator.QUERY_PARAMS: if params.get(query_param): param = params.pop(query_param) params[f"{query_param}[]"] = param diff --git a/client/python/upbit/client.py b/client/python/upbit/client.py index 56ced27..0be3a9d 100644 --- a/client/python/upbit/client.py +++ b/client/python/upbit/client.py @@ -31,14 +31,41 @@ def __init__( **kwargs ).SWGClient - self.APIKey = models.APIKey(self.__client) - self.Account = models.Account(self.__client) - self.Candle = models.Candle(self.__client) - self.Deposit = models.Deposit(self.__client) - self.Market = models.Market(self.__client) - self.Order = models.Order(self.__client) - self.Trade = models.Trade(self.__client) - self.Withdraw = models.Withdraw(self.__client) + self.__APIKey = models.APIKey(self.__client) + self.__Account = models.Account(self.__client) + self.__Candle = models.Candle(self.__client) + self.__Deposit = models.Deposit(self.__client) + self.__Market = models.Market(self.__client) + self.__Order = models.Order(self.__client) + self.__Trade = models.Trade(self.__client) + self.__Withdraw = models.Withdraw(self.__client) + + + @property + def APIKey(self): + return self.__APIKey + @property + def Account(self): + return self.__Account + @property + def Candle(self): + return self.__Candle + @property + def Deposit(self): + return self.__Deposit + @property + def Market(self): + return self.__Market + @property + def Order(self): + return self.__Order + @property + def Trade(self): + return self.__Trade + @property + def Withdraw(self): + return self.__Withdraw + def __str__(self): return self.__repr__() diff --git a/client/python/upbit/pkginfo.py b/client/python/upbit/pkginfo.py index 3d298e1..4f599be 100644 --- a/client/python/upbit/pkginfo.py +++ b/client/python/upbit/pkginfo.py @@ -29,7 +29,7 @@ def _get_versions(package_name): PACKAGE_NAME = 'upbit-client' OPEN_API_VERSION = '1.2.2' -CURRENT_VERSION = OPEN_API_VERSION+'.2' +CURRENT_VERSION = OPEN_API_VERSION+'.3' RELEASED_VERSION = _get_versions(PACKAGE_NAME) LATEST_VERSION = RELEASED_VERSION[0] diff --git a/client/python/upbit/websocket.py b/client/python/upbit/websocket.py index a6e3787..6b7f381 100644 --- a/client/python/upbit/websocket.py +++ b/client/python/upbit/websocket.py @@ -6,12 +6,6 @@ from typing import Union, List -WEBSOCKET_URI = "wss://api.upbit.com/websocket/v1" - -FIELD_TYPES = ['ticker', 'trade', 'orderbook'] -FIELD_FORMATS = ['SIMPLE', 'DEFAULT'] - - class UpbitWebSocket: """ Upbit WebSocket Client @@ -26,6 +20,11 @@ class UpbitWebSocket: - Official Support Email: open-api@upbit.com """ + WEBSOCKET_URI = "wss://api.upbit.com/websocket/v1" + FIELD_TYPES = tuple("ticker", "trade", "orderbook") + FIELD_FORMATS = tuple("SIMPLE", "DEFAULT") + + def __init__( self, uri: Union[str] = None, @@ -33,13 +32,14 @@ def __init__( ping_timeout: Union[int, float] = None ): - self.__uri = uri if uri else WEBSOCKET_URI + self.__uri = uri if uri else UpbitWebSocket.WEBSOCKET_URI self.__conn = None self.connect( ping_interval=ping_interval, ping_timeout=ping_timeout ) + @property def URI(self): return self.__uri @@ -56,6 +56,7 @@ def Connection(self): def Connection(self, conn): self.__conn = conn + def connect( self, ping_interval: Union[int, float] = None, @@ -75,14 +76,17 @@ def connect( ping_timeout=ping_timeout ) - async def ping(self): + + async def ping(self, decode: str = "utf8"): """ Client to Server PING """ async with self as conn: - await conn.send('PING') + await conn.send("PING") recv = await conn.recv() - return json.loads(recv) + pong = recv.decode(decode) + return json.loads(pong) + @staticmethod def generate_orderbook_codes( @@ -104,6 +108,7 @@ def generate_orderbook_codes( ] if counts else currencies return codes + @staticmethod def generate_type_field( type: str, @@ -127,8 +132,9 @@ def generate_type_field( field = {} - if type in FIELD_TYPES: - field["type"] = type + t = type.lower() + if t in UpbitWebSocket.FIELD_TYPES: + field["type"] = t else: raise ValueError("'type' is not available") @@ -142,6 +148,7 @@ def generate_type_field( return field + @staticmethod def generate_payload( type_fields: Union[List[dict]], @@ -167,11 +174,12 @@ def generate_payload( payload.extend(type_fields) fmt = format.upper() - fmt = fmt if fmt in FIELD_FORMATS else 'DEFAULT' + fmt = fmt if fmt in UpbitWebSocket.FIELD_FORMATS else "DEFAULT" payload.append({"format": fmt}) return json.dumps(payload) + async def __aenter__(self): return await self.Connection.__aenter__()