From 42f7957e02355bfd46e60d085217bc907e34d0a5 Mon Sep 17 00:00:00 2001 From: Aisling <19312514+aisling11@users.noreply.github.com> Date: Thu, 4 Nov 2021 11:52:22 +0000 Subject: [PATCH] 1.7.0 release (#111) --- CHANGELOG.md | 11 ++++++++ binance/__version__.py | 2 +- binance/api.py | 5 ++-- binance/lib/enums.py | 18 ++++++------- binance/lib/utils.py | 23 +++++++++++++--- binance/spot/__init__.py | 1 + binance/spot/account.py | 17 ++++++++++++ binance/websocket/binance_client_factory.py | 7 ++--- binance/websocket/binance_client_protocol.py | 13 +++++----- binance/websocket/binance_socket_manager.py | 3 ++- docs/source/CHANGELOG.rst | 16 ++++++++++++ docs/source/binance.spot.account.rst | 4 +++ examples/spot/blvt/blvt_info.py | 4 ++- examples/spot/blvt/user_limit_info.py | 4 +-- examples/spot/trade/get_order_rate_limit.py | 15 +++++++++++ examples/spot/trade/new_order_testing.py | 4 +-- tests/spot/market/test_ping.py | 2 +- tests/spot/trade/test_get_order_rate_limit.py | 26 +++++++++++++++++++ tests/test_api.py | 2 ++ 19 files changed, 145 insertions(+), 32 deletions(-) create mode 100644 examples/spot/trade/get_order_rate_limit.py create mode 100644 tests/spot/trade/test_get_order_rate_limit.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 1447c0af..d72b9742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 1.7.0 - 2021-11-4 + +### Updated +- Universal transfer types: + - Added `MAIN_FUNDING`, `FUNDING_MAIN`, `FUNDING_UMFUTURE`, `UMFUTURE_FUNDING`, `MARGIN_FUNDING`, `FUNDING_MARGIN`, `FUNDING_CMFUTURE` and `CMFUTURE_FUNDING` to support transfer assets among funding account and other accounts + - Deleted `MAIN_C2C`, `C2C_MAIN`, `C2C_UMFUTURE`, `C2C_MINING`, `UMFUTURE_C2C`, `MINING_C2C`, `MARGIN_C2C`, `C2C_MARGIN`, `MAIN_PAY` and `PAY_MAIN` as C2C account, Binance Payment, Binance Card and other business accounts are merged into a Funding account and they'll be discontinued on November 04, 2021 08:00 AM UTC +- Util method `config_logging` can now provide date time in UTC and epoch time + +### Added +- New endpoint `GET api/v3/rateLimit/order` to display the user's current order count usage for all intervals + ## 1.6.0 - 2021-09-24 ### Added diff --git a/binance/__version__.py b/binance/__version__.py index e4adfb83..14d9d2f5 100644 --- a/binance/__version__.py +++ b/binance/__version__.py @@ -1 +1 @@ -__version__ = "1.6.0" +__version__ = "1.7.0" diff --git a/binance/api.py b/binance/api.py index ae9fc933..d5adc150 100644 --- a/binance/api.py +++ b/binance/api.py @@ -61,6 +61,7 @@ def __init__( if type(proxies) is dict: self.proxies = proxies + self._logger = logging.getLogger(__name__) return def query(self, url_path, payload=None): @@ -102,7 +103,7 @@ def send_request(self, http_method, url_path, payload=None): if payload is None: payload = {} url = self.base_url + url_path - logging.debug("url: " + url) + self._logger.debug("url: " + url) params = cleanNoneValue( { "url": url, @@ -112,7 +113,7 @@ def send_request(self, http_method, url_path, payload=None): } ) response = self._dispatch_request(http_method)(**params) - logging.debug("raw response from server:" + response.text) + self._logger.debug("raw response from server:" + response.text) self._handle_exception(response) try: diff --git a/binance/lib/enums.py b/binance/lib/enums.py index c089210b..e7d66365 100644 --- a/binance/lib/enums.py +++ b/binance/lib/enums.py @@ -7,17 +7,11 @@ def _generate_next_value_(name, start, count, last_values): class TransferType(AutoName): - MAIN_C2C = auto() MAIN_UMFUTURE = auto() MAIN_CMFUTURE = auto() MAIN_MARGIN = auto() MAIN_MINING = auto() - C2C_MAIN = auto() - C2C_UMFUTURE = auto() - C2C_MINING = auto() - C2C_MARGIN = auto() UMFUTURE_MAIN = auto() - UMFUTURE_C2C = auto() UMFUTURE_MARGIN = auto() CMFUTURE_MAIN = auto() CMFUTURE_MARGIN = auto() @@ -25,13 +19,17 @@ class TransferType(AutoName): MARGIN_UMFUTURE = auto() MARGIN_CMFUTURE = auto() MARGIN_MINING = auto() - MARGIN_C2C = auto() MINING_MAIN = auto() MINING_UMFUTURE = auto() - MINING_C2C = auto() MINING_MARGIN = auto() - MAIN_PAY = auto() - PAY_MAIN = auto() ISOLATEDMARGIN_MARGIN = auto() MARGIN_ISOLATEDMARGIN = auto() ISOLATEDMARGIN_ISOLATEDMARGIN = auto() + MAIN_FUNDING = auto() + FUNDING_MAIN = auto() + FUNDING_UMFUTURE = auto() + UMFUTURE_FUNDING = auto() + MARGIN_FUNDING = auto() + FUNDING_MARGIN = auto() + FUNDING_CMFUTURE = auto() + CMFUTURE_FUNDING = auto() diff --git a/binance/lib/utils.py b/binance/lib/utils.py index 98834f2d..e756e07c 100644 --- a/binance/lib/utils.py +++ b/binance/lib/utils.py @@ -23,7 +23,7 @@ def check_required_parameter(value, name): def check_required_parameters(params): - """validate multiple parameters + """Validate multiple parameters params = [ ['btcusdt', 'symbol'], [10, 'price'] @@ -59,5 +59,22 @@ def convert_list_to_json_array(symbols): return res.replace(" ", "") -def config_logging(logging, logging_devel, log_file=None): - logging.basicConfig(level=logging_devel, filename=log_file) +def config_logging(logging, logging_level, log_file: str = None): + """Configures logging to provide a more detailed log format, which includes date time in UTC and an epoch timestamp in msec + Example: 2021-11-02 19:42:04 UTC 1635882124165 : + + Args: + logging: python logging + logging_level (int/str): For logging to include all messages with log levels >= logging_level. Ex: 10 or "DEBUG" + logging level should be based on https://docs.python.org/3/library/logging.html#logging-levels + Keyword Args: + log_file (str, optional): The filename to pass the logging to a file, instead of using console. Default filemode: "a" + """ + + logging.Formatter.converter = time.gmtime # date time in GMT/UTC + logging.basicConfig( + level=logging_level, + filename=log_file, + format="%(asctime)s%(msecs)03d %(levelname)s %(name)s: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S UTC %s", + ) diff --git a/binance/spot/__init__.py b/binance/spot/__init__.py index 45ce4eb6..3eb4f475 100644 --- a/binance/spot/__init__.py +++ b/binance/spot/__init__.py @@ -36,6 +36,7 @@ def __init__(self, key=None, secret=None, **kwargs): from binance.spot.account import get_oco_open_orders from binance.spot.account import account from binance.spot.account import my_trades + from binance.spot.account import get_order_rate_limit # STREAMS from binance.spot.data_stream import new_listen_key diff --git a/binance/spot/account.py b/binance/spot/account.py index b0a6885d..7ca0f0c0 100644 --- a/binance/spot/account.py +++ b/binance/spot/account.py @@ -357,3 +357,20 @@ def my_trades(self, symbol: str, **kwargs): url_path = "/api/v3/myTrades" payload = {"symbol": symbol, **kwargs} return self.sign_request("GET", url_path, payload) + + +def get_order_rate_limit(self, **kwargs): + """Query Current Order Count Usage (TRADE) + + Displays the user's current order count usage for all intervals. + + GET /api/v3/rateLimit/order + + https://binance-docs.github.io/apidocs/spot/en/#query-current-order-count-usage-trade + + Keyword Args: + recvWindow (int, optional): The value cannot be greater than 60000 + """ + + url_path = "/api/v3/rateLimit/order" + return self.sign_request("GET", url_path, {**kwargs}) diff --git a/binance/websocket/binance_client_factory.py b/binance/websocket/binance_client_factory.py index fc388978..8bada1b7 100644 --- a/binance/websocket/binance_client_factory.py +++ b/binance/websocket/binance_client_factory.py @@ -17,14 +17,15 @@ def __init__(self, *args, payload=None, **kwargs): self.protocol_instance = None self.base_client = None self.payload = payload + self._logger = logging.getLogger(__name__) _reconnect_error_payload = {"e": "error", "m": "Max reconnect retries reached"} def startedConnecting(self, connector): - logging.info("Start to connect....") + self._logger.info("Start to connect....") def clientConnectionFailed(self, connector, reason): - logging.error( + self._logger.error( "Can't connect to server. Reason: {}. Retrying: {}".format( reason, self.retries + 1 ) @@ -34,7 +35,7 @@ def clientConnectionFailed(self, connector, reason): self.callback(self._reconnect_error_payload) def clientConnectionLost(self, connector, reason): - logging.error( + self._logger.error( "Lost connection to Server. Reason: {}. Retrying: {}".format( reason, self.retries + 1 ) diff --git a/binance/websocket/binance_client_protocol.py b/binance/websocket/binance_client_protocol.py index 1416ad17..f100442f 100644 --- a/binance/websocket/binance_client_protocol.py +++ b/binance/websocket/binance_client_protocol.py @@ -8,14 +8,15 @@ def __init__(self, factory, payload=None): super().__init__() self.factory = factory self.payload = payload + self._logger = logging.getLogger(__name__) def onOpen(self): self.factory.protocol_instance = self def onConnect(self, response): - logging.info("Server connected") + self._logger.info("Server connected") if self.payload: - logging.info("Sending message to Server: {}".format(self.payload)) + self._logger.info("Sending message to Server: {}".format(self.payload)) self.sendMessage(self.payload, isBinary=False) # reset the delay after reconnecting self.factory.resetDelay() @@ -30,16 +31,16 @@ def onMessage(self, payload, isBinary): self.factory.callback(payload_obj) def onClose(self, wasClean, code, reason): - logging.warn( + self._logger.warning( "WebSocket connection closed: {0}, code: {1}, clean: {2}, reason: {0}".format( reason, code, wasClean ) ) def onPing(self, payload): - logging.info("Received Ping from server") + self._logger.info("Received Ping from server") self.sendPong() - logging.info("Responded Pong to server") + self._logger.info("Responded Pong to server") def onPong(self, payload): - logging.info("Received Pong from server") + self._logger.info("Received Pong from server") diff --git a/binance/websocket/binance_socket_manager.py b/binance/websocket/binance_socket_manager.py index 0cc4092a..3f6a6a18 100644 --- a/binance/websocket/binance_socket_manager.py +++ b/binance/websocket/binance_socket_manager.py @@ -18,6 +18,7 @@ def __init__(self, stream_url): self.stream_url = stream_url self._conns = {} self._user_callback = None + self._logger = logging.getLogger(__name__) def _start_socket( self, stream_name, payload, callback, is_combined=False, is_live=True @@ -39,7 +40,7 @@ def _start_socket( factory_url = factory_url + "/" + payload_obj["params"] payload = None - logging.info("Connection with URL: {}".format(factory_url)) + self._logger.info("Connection with URL: {}".format(factory_url)) factory = BinanceClientFactory(factory_url, payload=payload) factory.base_client = self diff --git a/docs/source/CHANGELOG.rst b/docs/source/CHANGELOG.rst index 04e42cec..c486c169 100644 --- a/docs/source/CHANGELOG.rst +++ b/docs/source/CHANGELOG.rst @@ -2,6 +2,22 @@ Changelog ========= + +1.7.0 - 2021-11-04 +------------------ + +Updated +^^^^^^^ +* Universal transfer types: + * Added ``MAIN_FUNDING``, ``FUNDING_MAIN``, ``FUNDING_UMFUTURE``, ``UMFUTURE_FUNDING``, ``MARGIN_FUNDING``, ``FUNDING_MARGIN``, ``FUNDING_CMFUTURE`` and ``CMFUTURE_FUNDING`` to support transfer assets among funding account and other accounts + * Deleted ``MAIN_C2C``, ``C2C_MAIN``, ``C2C_UMFUTURE``, ``C2C_MINING``, ``UMFUTURE_C2C``, ``MINING_C2C``, ``MARGIN_C2C``, ``C2C_MARGIN``, ``MAIN_PAY`` and ``PAY_MAIN`` as C2C account, Binance Payment, Binance Card and other business accounts are merged into a Funding account and they'll be discontinued on November 04, 2021 08:00 AM UTC +* Util method ``config_logging`` can now provide date time in UTC and epoch time + +Added +^^^^^ +* New endpoint ``GET api/v3/rateLimit/order`` to display the user's current order count usage for all intervals + + 1.6.0 - 2021-09-24 ------------------ diff --git a/docs/source/binance.spot.account.rst b/docs/source/binance.spot.account.rst index 5c78193f..6a6c7c0a 100644 --- a/docs/source/binance.spot.account.rst +++ b/docs/source/binance.spot.account.rst @@ -57,3 +57,7 @@ Account Information (USER_DATA) Account Trade List (USER_DATA) ------------------------------ .. autofunction:: binance.spot.account.my_trades + +Query Current Order Count Usage (TRADE) +--------------------------------------- +.. autofunction:: binance.spot.account.get_order_rate_limit diff --git a/examples/spot/blvt/blvt_info.py b/examples/spot/blvt/blvt_info.py index f134f4fd..2fabbd08 100644 --- a/examples/spot/blvt/blvt_info.py +++ b/examples/spot/blvt/blvt_info.py @@ -10,4 +10,6 @@ secret = "" client = Client(key, secret) -logging.info(client.blvt_info(tokenName="LINKUP")) + +logger = logging.getLogger(__name__) +logger.info(client.blvt_info(tokenName="LINKUP")) diff --git a/examples/spot/blvt/user_limit_info.py b/examples/spot/blvt/user_limit_info.py index 8c469d0b..c7691e06 100644 --- a/examples/spot/blvt/user_limit_info.py +++ b/examples/spot/blvt/user_limit_info.py @@ -6,8 +6,8 @@ config_logging(logging, logging.DEBUG) -key = "AqUZiEuzIXKf3c7PIOV2LmDCY4PXOWcAyqpVZrpsXnt5x0BQtgNqDNTGrp0JGFEv" -secret = "5ptDHTvuudtkaQttQ1KDxmQyEiPLt0N1XjYRp7jbf7BV7DbTYTvVv8gx9fYtQjpx" +key = "" +secret = "" client = Client(key, secret) logging.info(client.user_limit_info(tokenName="BTCDOWN")) diff --git a/examples/spot/trade/get_order_rate_limit.py b/examples/spot/trade/get_order_rate_limit.py new file mode 100644 index 00000000..04f52f19 --- /dev/null +++ b/examples/spot/trade/get_order_rate_limit.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import logging +from binance.lib.utils import config_logging +from binance.spot import Spot as Client + +config_logging(logging, logging.DEBUG) + +key = "" +secret = "" + +client = Client(key=key, secret=secret, base_url="https://testnet.binance.vision") +logger = logging.getLogger(__name__) + +logger.info(client.get_order_rate_limit()) diff --git a/examples/spot/trade/new_order_testing.py b/examples/spot/trade/new_order_testing.py index 7e63ee81..b23bd8bb 100644 --- a/examples/spot/trade/new_order_testing.py +++ b/examples/spot/trade/new_order_testing.py @@ -16,13 +16,13 @@ "type": "LIMIT", "timeInForce": "GTC", "quantity": 0.002, - "price": 9500, + "price": 49500, } client = Client(key, secret, base_url="https://testnet.binance.vision") try: - response = client.test_new_order(**params) + response = client.new_order_test(**params) logging.info(response) except ClientError as error: logging.error( diff --git a/tests/spot/market/test_ping.py b/tests/spot/market/test_ping.py index 3c3ce541..eb84cb27 100644 --- a/tests/spot/market/test_ping.py +++ b/tests/spot/market/test_ping.py @@ -6,7 +6,7 @@ @mock_http_response(responses.GET, "/api/v3/ping", {}, 200) def test_ping(): - """Tests the API endpoint to get conectivity""" + """Tests the API endpoint to get connectivity""" api = Client() response = api.ping() diff --git a/tests/spot/trade/test_get_order_rate_limit.py b/tests/spot/trade/test_get_order_rate_limit.py new file mode 100644 index 00000000..3f2d9b9b --- /dev/null +++ b/tests/spot/trade/test_get_order_rate_limit.py @@ -0,0 +1,26 @@ +import responses +from tests.util import random_str +from tests.util import mock_http_response +from binance.spot import Spot as Client + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +key = random_str() +secret = random_str() + +client = Client(key, secret) + + +@mock_http_response(responses.GET, "/api/v3/rateLimit/order", mock_item, 200) +def test_get_order_rate_limit(): + """Tests the API endpoint to get current order count usage for all intervals.""" + response = client.get_order_rate_limit() + response.should.equal(mock_item) + + +@mock_http_response( + responses.GET, "/api/v3/rateLimit/order\\?recvWindow=1000", mock_item, 200 +) +def test_get_order_rate_limit_with_recvWindow(): + """Tests the API endpoint to get current order count usage for all intervals.""" + response = client.get_order_rate_limit(recvWindow=1000) + response.should.equal(mock_item) diff --git a/tests/test_api.py b/tests/test_api.py index 4bd67965..c5e8c292 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -6,6 +6,7 @@ from binance.api import API from binance.error import ParameterRequiredError, ServerError from binance.error import ClientError +import logging mock_item = {"key_1": "value_1", "key_2": "value_2"} mock_error_body = "" @@ -39,6 +40,7 @@ def test_API_initial(): "binance-connector/" + __version__ ) client.session.headers.should.have.key("X-MBX-APIKEY").which.should.be.none + client._logger.should.be(logging.getLogger("binance.api")) def test_API_with_extra_parameters():