From 6b9447f6b45f0f62f1bf129a371569588f42496a Mon Sep 17 00:00:00 2001 From: Pablo Date: Tue, 18 Feb 2025 01:07:33 -0600 Subject: [PATCH 1/9] add timeout to jobs --- .github/workflows/python-app.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 2b0012d20..658baafff 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -16,6 +16,7 @@ permissions: jobs: lint: runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: actions/checkout@v4 - name: Set up Python @@ -33,6 +34,7 @@ jobs: build: needs: lint runs-on: ubuntu-22.04 + timeout-minutes: 20 env: PROXY: "http://51.83.140.52:16301" TEST_TESTNET: "true" @@ -74,6 +76,7 @@ jobs: needs: build if: ${{ always() }} runs-on: ubuntu-latest + timeout-minutes: 5 steps: - name: Coveralls Finished uses: coverallsapp/github-action@v2 From 6713486ea8c95b60e14a58ff59e4502d30baffb4 Mon Sep 17 00:00:00 2001 From: Pablo Date: Sun, 20 Apr 2025 23:46:03 -0400 Subject: [PATCH 2/9] feat: use session logon for ws api --- binance/async_client.py | 51 +++++++++++++++++++++++++++ binance/base_client.py | 2 ++ binance/client.py | 49 +++++++++++++++++++++++++ binance/ws/streams.py | 20 +++++++++++ binance/ws/threaded_stream.py | 2 ++ binance/ws/websocket_api.py | 2 +- tests/conftest.py | 10 +++--- tests/test_async_client_ws_api.py | 47 ++++++++++-------------- tests/test_client_ws_api.py | 16 +++++++++ tests/test_streams.py | 37 ++++++++++--------- tests/test_threaded_socket_manager.py | 24 +++++++++++++ 11 files changed, 210 insertions(+), 50 deletions(-) diff --git a/binance/async_client.py b/binance/async_client.py index 335a197e8..6da2078d1 100644 --- a/binance/async_client.py +++ b/binance/async_client.py @@ -3396,6 +3396,57 @@ async def create_oco_order(self, **params): # WebSocket API methods ############################################################ + async def ws_logon(self, **params): + """Authenticate WebSocket connection using the provided API key. + https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/authentication-requests + + :returns: WS response + .. code-block:: python + { + "apiKey": "vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A", + "authorizedSince": 1649729878532, + "connectedSince": 1649729873021, + "returnRateLimits": false, + "serverTime": 1649729878630, + "userDataStream": false + } + """ + return await self._ws_api_request("session.logon", True, params) + + async def ws_user_data_stream_subscribe(self, **params): + """Subscribe to the User Data Stream in the current WebSocket connection. + https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-data-stream-requests#subscribe-to-user-data-stream-user_stream + + Note: + - This method requires an authenticated WebSocket connection using Ed25519 keys. Please use ws_logon first. + - To check the subscription status, use ws_session_status, see the userDataStream flag. + - User Data Stream events are available in both JSON and SBE sessions. + + :returns: WS response + .. code-block:: python + { + "id": "d3df8a21-98ea-4fe0-8f4e-0fcea5d418b7", + "status": 200, + "result": {} + } + """ + return await self._ws_api_request("userDataStream.subscribe", True, params) + + async def ws_user_data_stream_unsubscribe(self, **params): + """Stop listening to the User Data Stream in the current WebSocket connection. + https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-data-stream-requests#unsubscribe-from-user-data-stream-user_stream + + :returns: WS response + .. code-block:: python + { + "id": "d3df8a21-98ea-4fe0-8f4e-0fcea5d418b7", + "status": 200, + "result": {} + } + """ + return await self._ws_api_request("userDataStream.unsubscribe", False, params) + + async def ws_create_test_order(self, **params): """Test new order creation and signature/recvWindow long. Creates and validates a new order but does not send it into the matching engine. https://binance-docs.github.io/apidocs/websocket_api/en/#test-new-order-trade diff --git a/binance/base_client.py b/binance/base_client.py index b0d78a0a4..074298ab4 100644 --- a/binance/base_client.py +++ b/binance/base_client.py @@ -405,6 +405,8 @@ async def _ws_api_request(self, method: str, signed: bool, params: dict): payload["params"] = self._sign_ws_params( params, self._generate_ws_api_signature ) + if method == "userDataStream.subscribe": + del payload["params"] return await self.ws_api.request(id, payload) def _ws_api_request_sync(self, method: str, signed: bool, params: dict): diff --git a/binance/client.py b/binance/client.py index 206417e77..25da25698 100755 --- a/binance/client.py +++ b/binance/client.py @@ -10898,6 +10898,55 @@ def __del__(self): ############################################################ # WebSocket API methods ############################################################ + def ws_logon(self, **params): + """Authenticate WebSocket connection using the provided API key. + https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/authentication-requests + + :returns: WS response + .. code-block:: python + { + "apiKey": "vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A", + "authorizedSince": 1649729878532, + "connectedSince": 1649729873021, + "returnRateLimits": false, + "serverTime": 1649729878630, + "userDataStream": false + } + """ + return self._ws_api_request_sync("session.logon", True, params) + + def ws_user_data_stream_subscribe(self, **params): + """Subscribe to the User Data Stream in the current WebSocket connection. + https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-data-stream-requests#subscribe-to-user-data-stream-user_stream + + Note: + - This method requires an authenticated WebSocket connection using Ed25519 keys. Please use ws_logon first. + - To check the subscription status, use ws_session_status, see the userDataStream flag. + - User Data Stream events are available in both JSON and SBE sessions. + + :returns: WS response + .. code-block:: python + { + "id": "d3df8a21-98ea-4fe0-8f4e-0fcea5d418b7", + "status": 200, + "result": {} + } + """ + return self._ws_api_request_sync("userDataStream.subscribe", True, params) + + def ws_user_data_stream_unsubscribe(self, **params): + """Stop listening to the User Data Stream in the current WebSocket connection. + https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-data-stream-requests#unsubscribe-from-user-data-stream-user_stream + + :returns: WS response + .. code-block:: python + { + "id": "d3df8a21-98ea-4fe0-8f4e-0fcea5d418b7", + "status": 200, + "result": {} + } + """ + return self._ws_api_request_sync("userDataStream.unsubscribe", False, params) def ws_create_test_order(self, **params): """Test new order creation and signature/recvWindow long. Creates and validates a new order but does not send it into the matching engine. diff --git a/binance/ws/streams.py b/binance/ws/streams.py index aed867bcb..70b4c0b75 100755 --- a/binance/ws/streams.py +++ b/binance/ws/streams.py @@ -1,4 +1,5 @@ import asyncio +import threading import time from enum import Enum from typing import Optional, List, Dict, Callable, Any @@ -13,7 +14,9 @@ from binance.enums import FuturesType from binance.enums import ContractType from binance.helpers import get_loop +import logging +logger = logging.getLogger(__name__) class BinanceSocketType(str, Enum): SPOT = "Spot" @@ -907,6 +910,21 @@ def user_socket(self): stream_url = self.STREAM_URL if self.testnet: stream_url = self.STREAM_TESTNET_URL + client = self._client + if client.PRIVATE_KEY and not client._is_rsa: + async def setup_ws(): + try: + res = await client.ws_logon() + logger.debug("Logged on: %s", res) + res = await client.ws_user_data_stream_subscribe() + logger.debug("Subscribed to user data stream: %s", res) + except Exception as e: + logger.error("Error setting up user data stream: %s", e) + self._client.loop.call_soon_threadsafe( + asyncio.create_task, setup_ws() + ) + # TODO: Fix to wait for setup_ws to complete + return client.ws_api return self._get_account_socket("user", stream_url=stream_url) def futures_user_socket(self): @@ -1211,6 +1229,7 @@ def __init__( https_proxy: Optional[str] = None, loop: Optional[asyncio.AbstractEventLoop] = None, max_queue_size: int = 100, + private_key: Optional[str] = None, ): super().__init__( api_key, @@ -1221,6 +1240,7 @@ def __init__( session_params, https_proxy, loop, + private_key, ) self._bsm: Optional[BinanceSocketManager] = None self._max_queue_size = max_queue_size diff --git a/binance/ws/threaded_stream.py b/binance/ws/threaded_stream.py index 5f43fe969..d3be41b58 100755 --- a/binance/ws/threaded_stream.py +++ b/binance/ws/threaded_stream.py @@ -18,6 +18,7 @@ def __init__( session_params: Optional[Dict[str, Any]] = None, https_proxy: Optional[str] = None, _loop: Optional[asyncio.AbstractEventLoop] = None, + private_key: Optional[str] = None, ): """Initialise the BinanceSocketManager""" super().__init__() @@ -34,6 +35,7 @@ def __init__( "testnet": testnet, "session_params": session_params, "https_proxy": https_proxy, + "private_key": private_key, } async def _before_socket_listener_start(self): ... diff --git a/binance/ws/websocket_api.py b/binance/ws/websocket_api.py index 8542b62db..be066dc83 100644 --- a/binance/ws/websocket_api.py +++ b/binance/ws/websocket_api.py @@ -40,7 +40,7 @@ def _handle_message(self, msg): elif exception is not None: raise exception else: - self._log.warning(f"WS api receieved unknown message: {parsed_msg}") + return parsed_msg async def _ensure_ws_connection(self) -> None: """Ensure WebSocket connection is established and ready diff --git a/tests/conftest.py b/tests/conftest.py index ca4550e5d..740f08f0e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,8 +21,10 @@ futures_api_key = os.getenv("TEST_FUTURES_API_KEY") futures_api_secret = os.getenv("TEST_FUTURES_API_SECRET") testnet = os.getenv("TEST_TESTNET", "true").lower() == "true" -api_key = "u4L8MG2DbshTfTzkx2Xm7NfsHHigvafxeC29HrExEmah1P8JhxXkoOu6KntLICUc" -api_secret = "hBZEqhZUUS6YZkk7AIckjJ3iLjrgEFr5CRtFPp5gjzkrHKKC9DAv4OH25PlT6yq5" +# api_key = "u4L8MG2DbshTfTzkx2Xm7NfsHHigvafxeC29HrExEmah1P8JhxXkoOu6KntLICUc" +# api_secret = "hBZEqhZUUS6YZkk7AIckjJ3iLjrgEFr5CRtFPp5gjzkrHKKC9DAv4OH25PlT6yq5" +api_key = "c5CTLgB3lqajkoN7OD28RG5sLOsVLeK4o0Ca9kT64mV6F8mKMwFeAB7uBJFRL8pG" +api_secret = "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIMwY1k3A4awroEHcfCdrn/Azan+ZgJqGhlNep3/Bud3e\n-----END PRIVATE KEY-----" testnet = True futures_api_key = "227719da8d8499e8d3461587d19f259c0b39c2b462a77c9b748a6119abd74401" futures_api_secret = "b14b935f9cfacc5dec829008733c40da0588051f29a44625c34967b45c11d73c" @@ -46,7 +48,7 @@ def setup_logging(): @pytest.fixture(scope="function") def client(): - return Client(api_key, api_secret, {"proxies": proxies}, testnet=testnet) + return Client(api_key, api_secret, {"proxies": proxies}, testnet=testnet, private_key=api_secret) @pytest.fixture(scope="function") @@ -63,7 +65,7 @@ def futuresClient(): @pytest.fixture(scope="function") def clientAsync(): - return AsyncClient(api_key, api_secret, https_proxy=proxy, testnet=testnet) + return AsyncClient(api_key, api_secret, https_proxy=proxy, testnet=testnet, private_key=api_secret) @pytest.fixture(scope="function") diff --git a/tests/test_async_client_ws_api.py b/tests/test_async_client_ws_api.py index c72a8e7da..bc9038d5e 100644 --- a/tests/test_async_client_ws_api.py +++ b/tests/test_async_client_ws_api.py @@ -1,76 +1,65 @@ +import sys import pytest +pytestmark = [pytest.mark.asyncio(), pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+")] -@pytest.mark.asyncio() async def test_ws_get_order_book(clientAsync): await clientAsync.ws_get_order_book(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_recent_trades(clientAsync): await clientAsync.ws_get_recent_trades(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_historical_trades(clientAsync): await clientAsync.ws_get_historical_trades(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_aggregate_trades(clientAsync): await clientAsync.ws_get_aggregate_trades(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_klines(clientAsync): await clientAsync.ws_get_klines(symbol="BTCUSDT", interval="1m") - -@pytest.mark.asyncio() async def test_ws_get_uiKlines(clientAsync): await clientAsync.ws_get_uiKlines(symbol="BTCUSDT", interval="1m") - -@pytest.mark.asyncio() async def test_ws_get_avg_price(clientAsync): await clientAsync.ws_get_avg_price(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_ticker(clientAsync): await clientAsync.ws_get_ticker(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_trading_day_ticker(clientAsync): await clientAsync.ws_get_trading_day_ticker(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_symbol_ticker_window(clientAsync): await clientAsync.ws_get_symbol_ticker_window(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_symbol_ticker(clientAsync): await clientAsync.ws_get_symbol_ticker(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_get_orderbook_ticker(clientAsync): await clientAsync.ws_get_orderbook_ticker(symbol="BTCUSDT") - -@pytest.mark.asyncio() async def test_ws_ping(clientAsync): await clientAsync.ws_ping() - -@pytest.mark.asyncio() async def test_ws_get_time(clientAsync): await clientAsync.ws_get_time() - -@pytest.mark.asyncio() async def test_ws_get_exchange_info(clientAsync): await clientAsync.ws_get_exchange_info(symbol="BTCUSDT") + +async def test_ws_logon(clientAsync): + res = await clientAsync.ws_logon() + apiKey = res.get("apiKey") + assert apiKey + +async def test_ws_user_data_stream_subscribe(clientAsync): + """Test subscribing to user data stream""" + await clientAsync.ws_logon() + await clientAsync.ws_user_data_stream_subscribe() + +async def test_ws_user_data_stream_unsubscribe(clientAsync): + """Test unsubscribing from user data stream""" + await clientAsync.ws_logon() + await clientAsync.ws_user_data_stream_subscribe() + await clientAsync.ws_user_data_stream_unsubscribe() diff --git a/tests/test_client_ws_api.py b/tests/test_client_ws_api.py index 4982e1206..7e0364744 100644 --- a/tests/test_client_ws_api.py +++ b/tests/test_client_ws_api.py @@ -64,6 +64,22 @@ def test_ws_get_exchange_info(client): client.ws_get_exchange_info(symbol="BTCUSDT") +def test_ws_logon(client): + res = client.ws_logon() + apiKey = res.get("apiKey") + assert apiKey + +def test_ws_user_data_stream_subscribe(client): + """Test subscribing to user data stream""" + client.ws_logon() + client.ws_user_data_stream_subscribe() + +def test_ws_user_data_stream_unsubscribe(client): + """Test unsubscribing from user data stream""" + client.ws_logon() + client.ws_user_data_stream_subscribe() + client.ws_user_data_stream_unsubscribe() + def test_ws_time_microseconds(): micro_client = Client( api_key, diff --git a/tests/test_streams.py b/tests/test_streams.py index a2ab66348..df0980c70 100644 --- a/tests/test_streams.py +++ b/tests/test_streams.py @@ -1,13 +1,14 @@ +import logging import sys from binance import BinanceSocketManager import pytest +import asyncio from binance.async_client import AsyncClient from .conftest import proxy, api_key, api_secret, testnet +pytestmark = [pytest.mark.asyncio, pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+")] -@pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") -@pytest.mark.asyncio async def test_socket_stopped_on_aexit(clientAsync): bm = BinanceSocketManager(clientAsync) ts1 = bm.trade_socket("BNBBTC") @@ -18,8 +19,6 @@ async def test_socket_stopped_on_aexit(clientAsync): assert ts2 is not ts1, "socket should be removed from _conn on exit" await clientAsync.close_connection() -@pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") -@pytest.mark.asyncio async def test_socket_stopped_on_aexit_futures(futuresClientAsync): bm = BinanceSocketManager(futuresClientAsync) ts1 = bm.futures_user_socket() @@ -28,9 +27,6 @@ async def test_socket_stopped_on_aexit_futures(futuresClientAsync): assert bm._conns == {}, "socket should be removed from _conn on exit" await futuresClientAsync.close_connection() - -@pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") -@pytest.mark.asyncio async def test_socket_spot_market_time_unit_microseconds(): clientAsync = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MICROSECOND" @@ -42,9 +38,6 @@ async def test_socket_spot_market_time_unit_microseconds(): assert len(str(trade["E"])) >= 16, "Time should be in microseconds (16+ digits)" await clientAsync.close_connection() - -@pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") -@pytest.mark.asyncio async def test_socket_spot_market_time_unit_milliseconds(): clientAsync = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MILLISECOND" @@ -56,9 +49,6 @@ async def test_socket_spot_market_time_unit_milliseconds(): assert len(str(trade["E"])) == 13, "Time should be in milliseconds (13 digits)" await clientAsync.close_connection() - -@pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") -@pytest.mark.asyncio async def test_socket_spot_user_data_time_unit_microseconds(): clientAsync = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MICROSECOND" @@ -73,9 +63,6 @@ async def test_socket_spot_user_data_time_unit_microseconds(): assert len(str(trade["E"])) >= 16, "Time should be in microseconds (16+ digits)" await clientAsync.close_connection() - -@pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") -@pytest.mark.asyncio async def test_socket_spot_user_data_time_unit_milliseconds(): clientAsync = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MILLISECOND" @@ -89,3 +76,21 @@ async def test_socket_spot_user_data_time_unit_milliseconds(): trade = await ts1.recv() assert len(str(trade["E"])) == 13, "Time should be in milliseconds (13 digits)" await clientAsync.close_connection() + +async def test_ws_api_socket_spot_user_data_time_unit_milliseconds(): + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + clientAsync = AsyncClient( + api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MILLISECOND", private_key=api_secret + ) + bm = BinanceSocketManager(clientAsync) + ts1 = bm.user_socket() + await asyncio.sleep(5) # TODO: Fix to wait for setup_ws to complete and remove + async with ts1: + await clientAsync.create_order( + symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 + ) + trade = await ts1.recv() + event = trade.get("event") + assert event.get("e") == 'executionReport' + await clientAsync.close_connection() diff --git a/tests/test_threaded_socket_manager.py b/tests/test_threaded_socket_manager.py index d76f30cec..8cfd0b49f 100644 --- a/tests/test_threaded_socket_manager.py +++ b/tests/test_threaded_socket_manager.py @@ -189,3 +189,27 @@ def test_no_internet_connection(): logger.debug("Cleaning up test_no_internet_connection") twm.stop() time.sleep(2) + +def test_threaded_user_socket_manager(client): + logger.debug("Starting test_threaded_socket_manager") + global twm + twm = ThreadedWebsocketManager(api_key, api_secret, https_proxy=proxy, testnet=True, private_key=api_secret) + + + def handle_socket_message(msg): + logger.debug("Received message: %s", msg) + twm.stop() + + try: + logger.debug("Starting ThreadedWebsocketManager") + twm.start() + twm.start_user_socket(callback=handle_socket_message) + time.sleep(20) + client.create_order( + symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 + ) + twm.join() + finally: + logger.debug("Cleaning up test_threaded_socket_manager") + twm.stop() + time.sleep(2) From 66ab37a90f7813c293882ebb36f2c5e2e457e28c Mon Sep 17 00:00:00 2001 From: Pablo Date: Sun, 11 May 2025 17:43:39 +0200 Subject: [PATCH 3/9] chore: update testnet urls --- binance/base_client.py | 2 +- binance/ws/streams.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/binance/base_client.py b/binance/base_client.py index b0d78a0a4..53ee964b8 100644 --- a/binance/base_client.py +++ b/binance/base_client.py @@ -36,7 +36,7 @@ class BaseClient: OPTIONS_TESTNET_URL = "https://testnet.binanceops.{}/eapi" PAPI_URL = "https://papi.binance.{}/papi" WS_API_URL = "wss://ws-api.binance.{}/ws-api/v3" - WS_API_TESTNET_URL = "wss://testnet.binance.vision/ws-api/v3" + WS_API_TESTNET_URL = "wss://ws-api.testnet.binance.vision/ws-api/v3" WS_FUTURES_URL = "wss://ws-fapi.binance.{}/ws-fapi/v1" WS_FUTURES_TESTNET_URL = "wss://testnet.binancefuture.com/ws-fapi/v1" PUBLIC_API_VERSION = "v1" diff --git a/binance/ws/streams.py b/binance/ws/streams.py index aed867bcb..b1aa71487 100755 --- a/binance/ws/streams.py +++ b/binance/ws/streams.py @@ -25,7 +25,7 @@ class BinanceSocketType(str, Enum): class BinanceSocketManager: STREAM_URL = "wss://stream.binance.{}:9443/" - STREAM_TESTNET_URL = "wss://testnet.binance.vision/" + STREAM_TESTNET_URL = "wss://stream.testnet.binance.vision/ws" FSTREAM_URL = "wss://fstream.binance.{}/" FSTREAM_TESTNET_URL = "wss://stream.binancefuture.com/" DSTREAM_URL = "wss://dstream.binance.{}/" From 323c753daa461ce717d28a537d30a3ab7065870d Mon Sep 17 00:00:00 2001 From: Pablo Date: Sun, 11 May 2025 17:50:36 +0200 Subject: [PATCH 4/9] url fix --- binance/ws/streams.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binance/ws/streams.py b/binance/ws/streams.py index b1aa71487..8c73d8c7b 100755 --- a/binance/ws/streams.py +++ b/binance/ws/streams.py @@ -25,7 +25,7 @@ class BinanceSocketType(str, Enum): class BinanceSocketManager: STREAM_URL = "wss://stream.binance.{}:9443/" - STREAM_TESTNET_URL = "wss://stream.testnet.binance.vision/ws" + STREAM_TESTNET_URL = "wss://stream.testnet.binance.vision/" FSTREAM_URL = "wss://fstream.binance.{}/" FSTREAM_TESTNET_URL = "wss://stream.binancefuture.com/" DSTREAM_URL = "wss://dstream.binance.{}/" From ea89084cfdb37d5b41faecece256c213810dd0e2 Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 12 May 2025 00:44:06 +0200 Subject: [PATCH 5/9] cleanup client --- tests/conftest.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index ca4550e5d..76e49ceaf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ import pytest +import pytest_asyncio from binance.client import Client from binance.async_client import AsyncClient import os @@ -61,21 +62,27 @@ def futuresClient(): ) -@pytest.fixture(scope="function") -def clientAsync(): - return AsyncClient(api_key, api_secret, https_proxy=proxy, testnet=testnet) +@pytest_asyncio.fixture(scope="function") +async def clientAsync(): + client = AsyncClient(api_key, api_secret, https_proxy=proxy, testnet=testnet) + yield client + await client.close_connection() -@pytest.fixture(scope="function") -def futuresClientAsync(): - return AsyncClient( +@pytest_asyncio.fixture(scope="function") +async def futuresClientAsync(): + client = AsyncClient( futures_api_key, futures_api_secret, https_proxy=proxy, testnet=testnet ) + yield client + await client.close_connection() -@pytest.fixture(scope="function") -def liveClientAsync(): - return AsyncClient(api_key, api_secret, https_proxy=proxy, testnet=False) +@pytest_asyncio.fixture(scope="function") +async def liveClientAsync(): + client = AsyncClient(api_key, api_secret, https_proxy=proxy, testnet=False) + yield client + await client.close_connection() @pytest.fixture(scope="function") def manager(): From f9e7a3b522974e76f6aa36f2ab14b99b320e3083 Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 12 May 2025 00:55:41 +0200 Subject: [PATCH 6/9] edit event loop in test --- tests/conftest.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 76e49ceaf..b0eeab246 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -90,16 +90,20 @@ def manager(): api_key="test_key", api_secret="test_secret", https_proxy=proxy, testnet=True ) -@pytest.fixture(autouse=True, scope="function") -def event_loop(): +@pytest_asyncio.fixture(autouse=True, scope="function") +async def event_loop(): """Create new event loop for each test""" loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) yield loop # Clean up pending tasks pending = asyncio.all_tasks(loop) for task in pending: task.cancel() - loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True)) + # Wait for all tasks to complete + await asyncio.gather(*pending, return_exceptions=True) + # Run the loop one more time to ensure all cleanup is done + await asyncio.sleep(0) loop.close() From 9f4caae1a27c841dc575c8ec64c83bdd4dae0391 Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 12 May 2025 01:23:00 +0200 Subject: [PATCH 7/9] increase timeout --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 658baafff..07c4b531c 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -34,7 +34,7 @@ jobs: build: needs: lint runs-on: ubuntu-22.04 - timeout-minutes: 20 + timeout-minutes: 40 env: PROXY: "http://51.83.140.52:16301" TEST_TESTNET: "true" From 84295755ab1331357ef18cf98e6ef87e52cbcdc8 Mon Sep 17 00:00:00 2001 From: Pablo Date: Sun, 18 May 2025 22:28:58 +0200 Subject: [PATCH 8/9] fix tests --- tests/conftest.py | 10 +- tests/test_async_client.py | 134 ++++++---------- tests/test_async_client_futures.py | 114 +------------- tests/test_async_client_margin.py | 144 ------------------ tests/test_async_client_options.py | 27 ---- tests/test_async_client_ws_api.py | 15 -- .../test_async_client_ws_futures_requests.py | 8 +- tests/test_client_futures.py | 12 +- tests/test_client_ws_futures_requests.py | 4 +- tests/test_threaded_stream.py | 2 +- 10 files changed, 69 insertions(+), 401 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index b0eeab246..76e49ceaf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -90,20 +90,16 @@ def manager(): api_key="test_key", api_secret="test_secret", https_proxy=proxy, testnet=True ) -@pytest_asyncio.fixture(autouse=True, scope="function") -async def event_loop(): +@pytest.fixture(autouse=True, scope="function") +def event_loop(): """Create new event loop for each test""" loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) yield loop # Clean up pending tasks pending = asyncio.all_tasks(loop) for task in pending: task.cancel() - # Wait for all tasks to complete - await asyncio.gather(*pending, return_exceptions=True) - # Run the loop one more time to ensure all cleanup is done - await asyncio.sleep(0) + loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True)) loop.close() diff --git a/tests/test_async_client.py b/tests/test_async_client.py index 66f072b32..fab9806b0 100644 --- a/tests/test_async_client.py +++ b/tests/test_async_client.py @@ -18,117 +18,94 @@ async def test_clientAsync_initialization(clientAsync): @pytest.mark.skip(reason="Endpoint not documented") async def test_get_products(clientAsync): await clientAsync.get_products() - + async def test_get_exchange_info(clientAsync): await clientAsync.get_exchange_info() - - + async def test_get_symbol_info(clientAsync): await clientAsync.get_symbol_info("BTCUSDT") - + async def test_ping(clientAsync): await clientAsync.ping() - - + async def test_get_server_time(clientAsync): await clientAsync.get_server_time() - - + async def test_get_all_tickers(clientAsync): await clientAsync.get_all_tickers() - async def test_get_orderbook_tickers(clientAsync): await clientAsync.get_orderbook_tickers() - - + async def test_get_order_book(clientAsync): await clientAsync.get_order_book(symbol="BTCUSDT") - - + async def test_get_recent_trades(clientAsync): await clientAsync.get_recent_trades(symbol="BTCUSDT") async def test_get_historical_trades(clientAsync): await clientAsync.get_historical_trades(symbol="BTCUSDT") - + async def test_get_aggregate_trades(clientAsync): await clientAsync.get_aggregate_trades(symbol="BTCUSDT") - - + async def test_get_klines(clientAsync): await clientAsync.get_klines(symbol="BTCUSDT", interval="1d") - - + async def test_get_uiklines(clientAsync): await clientAsync.get_ui_klines(symbol="BTCUSDT", interval="1d") - - + async def test_futures_mark_price_klines(clientAsync): await clientAsync.futures_mark_price_klines(symbol="BTCUSDT", interval="1h") - - + async def test_futures_index_price_klines(clientAsync): await clientAsync.futures_index_price_klines(pair="BTCUSDT", interval="1h") - - + async def test_futures_premium_index_klines(clientAsync): await clientAsync.futures_premium_index_klines(symbol="BTCUSDT", interval="1h") - - + @pytest.mark.skip(reason="network error") async def test_futures_coin_premium_index_klines(clientAsync): await clientAsync.futures_coin_premium_index_klines(symbol="BTCUSD", interval="1h") - - + async def test_get_avg_price(clientAsync): await clientAsync.get_avg_price(symbol="BTCUSDT") - - + async def test_get_ticker(clientAsync): await clientAsync.get_ticker(symbol="BTCUSDT") - - + async def test_get_symbol_ticker(clientAsync): await clientAsync.get_symbol_ticker(symbol="BTCUSDT") - - + async def test_get_orderbook_ticker(clientAsync): await clientAsync.get_orderbook_ticker(symbol="BTCUSDT") - - + async def test_get_account(clientAsync): await clientAsync.get_account() - - + async def test_get_asset_balance(clientAsync): await clientAsync.get_asset_balance(asset="BTC") - - + async def test_get_asset_balance_no_asset_provided(clientAsync): await clientAsync.get_asset_balance() - - + async def test_get_my_trades(clientAsync): await clientAsync.get_my_trades(symbol="BTCUSDT") - - + async def test_get_system_status(clientAsync): await clientAsync.get_system_status() - - + # User Stream Endpoints async def test_stream_get_listen_key_and_close(clientAsync): listen_key = await clientAsync.stream_get_listen_key() await clientAsync.stream_close(listen_key) - - + # Quoting interface endpoints @@ -139,76 +116,62 @@ async def test_stream_get_listen_key_and_close(clientAsync): async def test_ws_get_order_book(clientAsync): await clientAsync.ws_get_order_book(symbol="BTCUSDT") - - + async def test_ws_get_recent_trades(clientAsync): await clientAsync.ws_get_recent_trades(symbol="BTCUSDT") - - + async def test_ws_get_historical_trades(clientAsync): await clientAsync.ws_get_historical_trades(symbol="BTCUSDT") - - + async def test_ws_get_aggregate_trades(clientAsync): await clientAsync.ws_get_aggregate_trades(symbol="BTCUSDT") - - + async def test_ws_get_klines(clientAsync): await clientAsync.ws_get_klines(symbol="BTCUSDT", interval="1m") - - + async def test_ws_get_uiKlines(clientAsync): await clientAsync.ws_get_uiKlines(symbol="BTCUSDT", interval="1m") - - + async def test_ws_get_avg_price(clientAsync): await clientAsync.ws_get_avg_price(symbol="BTCUSDT") - - + async def test_ws_get_ticker(clientAsync): ticker = await clientAsync.ws_get_ticker(symbol="BTCUSDT") - - + async def test_ws_get_trading_day_ticker(clientAsync): await clientAsync.ws_get_trading_day_ticker(symbol="BTCUSDT") - - + async def test_ws_get_symbol_ticker_window(clientAsync): await clientAsync.ws_get_symbol_ticker_window(symbol="BTCUSDT") - - + async def test_ws_get_symbol_ticker(clientAsync): await clientAsync.ws_get_symbol_ticker(symbol="BTCUSDT") - - + async def test_ws_get_orderbook_ticker(clientAsync): await clientAsync.ws_get_orderbook_ticker(symbol="BTCUSDT") - - + async def test_ws_ping(clientAsync): await clientAsync.ws_ping() - - + async def test_ws_get_time(clientAsync): await clientAsync.ws_get_time() - - + async def test_ws_get_exchange_info(clientAsync): await clientAsync.ws_get_exchange_info(symbol="BTCUSDT") - + @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_next_hourly_interest_rate(clientAsync): await clientAsync.margin_next_hourly_interest_rate( assets="BTC", isIsolated="FALSE" ) - + @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_interest_history(clientAsync): await clientAsync.margin_interest_history( asset="BTC", ) - + @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_borrow_repay(clientAsync): await clientAsync.margin_borrow_repay( @@ -218,27 +181,26 @@ async def test_margin_borrow_repay(clientAsync): symbol="BTCUSDT", type="BORROW" ) - + @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_get_borrow_repay_records(clientAsync): await clientAsync.margin_get_borrow_repay_records( asset="BTC", isolatedSymbol="BTCUSDT", ) - + @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_interest_rate_history(clientAsync): await clientAsync.margin_interest_rate_history( asset="BTC", ) - + @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_max_borrowable(clientAsync): await clientAsync.margin_max_borrowable( asset="BTC", ) - - + async def test_time_unit_microseconds(): micro_client = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MICROSECOND" @@ -247,7 +209,7 @@ async def test_time_unit_microseconds(): assert len(str(micro_trades[0]["time"])) >= 16, ( "Time should be in microseconds (16+ digits)" ) - + await micro_client.close_connection() async def test_time_unit_milloseconds(): milli_client = AsyncClient( @@ -257,6 +219,7 @@ async def test_time_unit_milloseconds(): assert len(str(milli_trades[0]["time"])) == 13, ( "Time should be in milliseconds (13 digits)" ) + await milli_client.close_connection() async def test_handle_response(clientAsync): @@ -295,3 +258,4 @@ async def test_handle_response(clientAsync): mock_response._body = b'error message' with pytest.raises(BinanceAPIException): await clientAsync._handle_response(mock_response) + \ No newline at end of file diff --git a/tests/test_async_client_futures.py b/tests/test_async_client_futures.py index 866e33cd6..b02d564f3 100644 --- a/tests/test_async_client_futures.py +++ b/tests/test_async_client_futures.py @@ -6,194 +6,155 @@ pytestmark = [pytest.mark.futures, pytest.mark.asyncio] - async def test_futures_ping(futuresClientAsync): await futuresClientAsync.futures_ping() - async def test_futures_time(futuresClientAsync): await futuresClientAsync.futures_time() - - async def test_futures_exchange_info(futuresClientAsync): await futuresClientAsync.futures_exchange_info() - async def test_futures_order_book(futuresClientAsync): order_book = await futuresClientAsync.futures_order_book(symbol="BTCUSDT") assert_ob(order_book) - async def test_futures_recent_trades(futuresClientAsync): await futuresClientAsync.futures_recent_trades(symbol="BTCUSDT") - async def test_futures_historical_trades(futuresClientAsync): await futuresClientAsync.futures_historical_trades(symbol="BTCUSDT") - async def test_futures_aggregate_trades(futuresClientAsync): await futuresClientAsync.futures_aggregate_trades(symbol="BTCUSDT") - async def test_futures_klines(futuresClientAsync): await futuresClientAsync.futures_klines(symbol="BTCUSDT", interval="1h") - async def test_futures_continous_klines(futuresClientAsync): await futuresClientAsync.futures_continous_klines( pair="BTCUSDT", contractType="PERPETUAL", interval="1h" ) - async def test_futures_historical_klines(futuresClientAsync): await futuresClientAsync.futures_historical_klines( symbol="BTCUSDT", interval="1h", start_str=datetime.now().strftime("%Y-%m-%d") ) - async def test_futures_historical_klines_generator(futuresClientAsync): await futuresClientAsync.futures_historical_klines_generator( symbol="BTCUSDT", interval="1h", start_str=datetime.now().strftime("%Y-%m-%d") ) - async def test_futures_mark_price(futuresClientAsync): await futuresClientAsync.futures_mark_price() - async def test_futures_funding_rate(futuresClientAsync): await futuresClientAsync.futures_funding_rate() - @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_top_longshort_account_ratio(futuresClientAsync): await futuresClientAsync.futures_top_longshort_account_ratio( symbol="BTCUSDT", period="5m" ) - @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_top_longshort_position_ratio(futuresClientAsync): await futuresClientAsync.futures_top_longshort_position_ratio( symbol="BTCUSDT", period="5m" ) - @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_global_longshort_ratio(futuresClientAsync): await futuresClientAsync.futures_global_longshort_ratio( symbol="BTCUSDT", period="5m" ) - @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_taker_longshort_ratio(futuresClientAsync): await futuresClientAsync.futures_taker_longshort_ratio( symbol="BTCUSDT", period="5m" ) - async def test_futures_ticker(futuresClientAsync): await futuresClientAsync.futures_ticker() - async def test_futures_symbol_ticker(futuresClientAsync): await futuresClientAsync.futures_symbol_ticker() - async def test_futures_orderbook_ticker(futuresClientAsync): await futuresClientAsync.futures_orderbook_ticker() - async def test_futures_index_index_price_constituents(futuresClientAsync): await futuresClientAsync.futures_index_price_constituents(symbol="BTCUSD") - async def test_futures_liquidation_orders(futuresClientAsync): await futuresClientAsync.futures_liquidation_orders() - async def test_futures_api_trading_status(futuresClientAsync): await futuresClientAsync.futures_api_trading_status() - async def test_futures_commission_rate(futuresClientAsync): await futuresClientAsync.futures_commission_rate(symbol="BTCUSDT") - async def test_futures_adl_quantile_estimate(futuresClientAsync): await futuresClientAsync.futures_adl_quantile_estimate() - async def test_futures_open_interest(futuresClientAsync): await futuresClientAsync.futures_open_interest(symbol="BTCUSDT") - async def test_futures_index_info(futuresClientAsync): await futuresClientAsync.futures_index_info() - @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_open_interest_hist(futuresClientAsync): await futuresClientAsync.futures_open_interest_hist(symbol="BTCUSDT", period="5m") - async def test_futures_leverage_bracket(futuresClientAsync): await futuresClientAsync.futures_leverage_bracket() - @pytest.mark.skip(reason="Not implemented") async def test_futures_account_transfer(futuresClientAsync): await futuresClientAsync.futures_account_transfer() - @pytest.mark.skip(reason="Not implemented") async def test_transfer_history(client): client.transfer_history() - @pytest.mark.skip(reason="Not implemented") async def test_futures_loan_borrow_history(futuresClientAsync): await futuresClientAsync.futures_loan_borrow_history() - @pytest.mark.skip(reason="Not implemented") async def test_futures_loan_repay_history(futuresClientAsync): await futuresClientAsync.futures_loan_repay_history() - @pytest.mark.skip(reason="Not implemented") async def test_futures_loan_wallet(futuresClientAsync): await futuresClientAsync.futures_loan_wallet() - @pytest.mark.skip(reason="Not implemented") async def test_futures_cross_collateral_adjust_history(futuresClientAsync): await futuresClientAsync.futures_cross_collateral_adjust_history() - @pytest.mark.skip(reason="Not implemented") async def test_futures_cross_collateral_liquidation_history(futuresClientAsync): await futuresClientAsync.futures_cross_collateral_liquidation_history() - @pytest.mark.skip(reason="Not implemented") async def test_futures_loan_interest_history(futuresClientAsync): await futuresClientAsync.futures_loan_interest_history() - async def test_futures_create_get_edit_cancel_order(futuresClientAsync): ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_order( symbol=ticker["symbol"], - side="BUY", + side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, - price=str(round(float(ticker["lastPrice"]) - 1)), + price=str(round(float(ticker["lastPrice"]) + 1)), ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.futures_modify_order( @@ -212,7 +173,6 @@ async def test_futures_create_get_edit_cancel_order(futuresClientAsync): orderid=order["orderId"], symbol=order["symbol"] ) - async def test_futures_create_test_order(futuresClientAsync): ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") @@ -226,7 +186,6 @@ async def test_futures_create_test_order(futuresClientAsync): price=str(round(float(ticker["lastPrice"]) - 1, 0)), ) - async def test_futures_place_batch_order_and_cancel(futuresClientAsync): ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") @@ -270,38 +229,30 @@ async def test_futures_place_batch_order_and_cancel(futuresClientAsync): for order in cancelled_orders: assert_contract_order(futuresClientAsync, order) - async def test_futures_get_open_orders(futuresClientAsync): await futuresClientAsync.futures_get_open_orders() - async def test_futures_get_all_orders(futuresClientAsync): orders = futuresClientAsync.futures_get_all_orders() print(orders) - async def test_futures_cancel_all_open_orders(futuresClientAsync): await futuresClientAsync.futures_cancel_all_open_orders(symbol="LTCUSDT") - async def test_futures_countdown_cancel_all(futuresClientAsync): await futuresClientAsync.futures_countdown_cancel_all( symbol="LTCUSDT", countdownTime=10 ) - async def test_futures_account_balance(futuresClientAsync): await futuresClientAsync.futures_account_balance() - async def test_futures_account(futuresClientAsync): await futuresClientAsync.futures_account() - async def test_futures_change_leverage(futuresClientAsync): await futuresClientAsync.futures_change_leverage(symbol="LTCUSDT", leverage=10) - async def test_futures_change_margin_type(futuresClientAsync): try: await futuresClientAsync.futures_change_margin_type( @@ -312,25 +263,20 @@ async def test_futures_change_margin_type(futuresClientAsync): symbol="XRPUSDT", marginType="ISOLATED" ) - async def test_futures_position_margin_history(futuresClientAsync): position = await futuresClientAsync.futures_position_margin_history( symbol="LTCUSDT" ) - async def test_futures_position_information(futuresClientAsync): await futuresClientAsync.futures_position_information() - async def test_futures_account_trades(futuresClientAsync): await futuresClientAsync.futures_account_trades() - async def test_futures_income_history(futuresClientAsync): await futuresClientAsync.futures_income_history() - async def close_all_futures_positions(futuresClientAsync): # Get all open positions positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") @@ -352,7 +298,6 @@ async def close_all_futures_positions(futuresClientAsync): except Exception as e: print(f"Failed to close position for {symbol}: {e}") - @pytest.mark.skip(reason="Not implemented") async def test_futures_get_and_change_position_mode(futuresClientAsync): mode = await futuresClientAsync.futures_get_position_mode() @@ -360,129 +305,101 @@ async def test_futures_get_and_change_position_mode(futuresClientAsync): dualSidePosition=not mode["dualSidePosition"] ) - @pytest.mark.skip(reason="Not implemented") async def test_futures_change_multi_assets_mode(futuresClientAsync): await futuresClientAsync.futures_change_multi_assets_mode() - async def test_futures_get_multi_assets_mode(futuresClientAsync): await futuresClientAsync.futures_get_multi_assets_mode() - async def test_futures_stream_get_listen_key(futuresClientAsync): await futuresClientAsync.futures_stream_get_listen_key() - @pytest.mark.skip(reason="Not implemented") async def test_futures_stream_close(futuresClientAsync): await futuresClientAsync.futures_stream_close() - # new methods async def test_futures_account_config(futuresClientAsync): await futuresClientAsync.futures_account_config() - async def test_futures_symbol_config(futuresClientAsync): await futuresClientAsync.futures_symbol_config() - # COIN Futures API async def test_futures_coin_ping(futuresClientAsync): await futuresClientAsync.futures_coin_ping() - async def test_futures_coin_time(futuresClientAsync): await futuresClientAsync.futures_coin_time() - async def test_futures_coin_exchange_info(futuresClientAsync): await futuresClientAsync.futures_coin_exchange_info() - async def test_futures_coin_order_book(futuresClientAsync): order_book = await futuresClientAsync.futures_coin_order_book(symbol="BTCUSD_PERP") assert_ob(order_book) - async def test_futures_coin_recent_trades(futuresClientAsync): await futuresClientAsync.futures_coin_recent_trades(symbol="BTCUSD_PERP") - async def test_futures_coin_historical_trades(futuresClientAsync): await futuresClientAsync.futures_coin_historical_trades(symbol="BTCUSD_PERP") - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_aggregate_trades(futuresClientAsync): await futuresClientAsync.futures_coin_aggregate_trades(symbol="BTCUSD_PERP") - async def test_futures_coin_klines(futuresClientAsync): await futuresClientAsync.futures_coin_klines(symbol="BTCUSD_PERP", interval="1h") - async def test_futures_coin_continous_klines(futuresClientAsync): await futuresClientAsync.futures_coin_continous_klines( pair="BTCUSD", contractType="PERPETUAL", interval="1h" ) - async def test_futures_coin_index_price_klines(futuresClientAsync): await futuresClientAsync.futures_coin_index_price_klines( - pair="BTCUSD", interval="1h" + pair="BTCUSD", interval="1m" ) - async def test_futures_coin_mark_price_klines(futuresClientAsync): await futuresClientAsync.futures_coin_mark_price_klines( - symbol="BTCUSD_PERP", interval="1h" + symbol="BTCUSD_PERP", interval="1m" ) - async def test_futures_coin_mark_price(futuresClientAsync): await futuresClientAsync.futures_coin_mark_price() - async def test_futures_coin_funding_rate(futuresClientAsync): await futuresClientAsync.futures_coin_funding_rate(symbol="BTCUSD_PERP") - async def test_futures_coin_ticker(futuresClientAsync): await futuresClientAsync.futures_coin_ticker() - async def test_futures_coin_symbol_ticker(futuresClientAsync): await futuresClientAsync.futures_coin_symbol_ticker() - async def test_futures_coin_orderbook_ticker(futuresClientAsync): await futuresClientAsync.futures_coin_orderbook_ticker() - async def test_futures_coin_index_index_price_constituents(futuresClientAsync): await futuresClientAsync.futures_coin_index_price_constituents(symbol="BTCUSD") - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_liquidation_orders(futuresClientAsync): await futuresClientAsync.futures_coin_liquidation_orders() - async def test_futures_coin_open_interest(futuresClientAsync): await futuresClientAsync.futures_coin_open_interest(symbol="BTCUSD_PERP") - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_open_interest_hist(futuresClientAsync): await futuresClientAsync.futures_coin_open_interest_hist(symbol="BTCUSD_PERP") - async def test_futures_coin_leverage_bracket(futuresClientAsync): await futuresClientAsync.futures_coin_leverage_bracket() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_create_order(futuresClientAsync): positions = await futuresClientAsync.futures_coin_position_information() @@ -512,111 +429,88 @@ async def test_futures_coin_create_order(futuresClientAsync): orderid=order["orderId"], symbol=order["symbol"] ) - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_place_batch_order(futuresClientAsync): await futuresClientAsync.futures_coin_place_batch_order() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_get_order(futuresClientAsync): await futuresClientAsync.futures_coin_get_order() - async def test_futures_coin_get_open_orders(futuresClientAsync): await futuresClientAsync.futures_coin_get_open_orders() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_get_all_orders(futuresClientAsync): await futuresClientAsync.futures_coin_get_all_orders() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_cancel_order(futuresClientAsync): await futuresClientAsync.futures_coin_cancel_order() - async def test_futures_coin_cancel_all_open_orders(futuresClientAsync): await futuresClientAsync.futures_coin_cancel_all_open_orders(symbol="BTCUSD_PERP") - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_cancel_orders(futuresClientAsync): await futuresClientAsync.futures_coin_cancel_orders() - async def test_futures_coin_account_balance(futuresClientAsync): await futuresClientAsync.futures_coin_account_balance() - async def test_futures_coin_account(futuresClientAsync): await futuresClientAsync.futures_coin_account() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_change_leverage(futuresClientAsync): await futuresClientAsync.futures_coin_change_leverage(symbol="XRPUSDT", leverage=10) - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_change_margin_type(futuresClientAsync): await futuresClientAsync.futures_coin_change_margin_type() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_change_position_margin(futuresClientAsync): await futuresClientAsync.futures_coin_change_position_margin() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_position_margin_history(futuresClientAsync): await futuresClientAsync.futures_coin_position_margin_history() - async def test_futures_coin_position_information(futuresClientAsync): await futuresClientAsync.futures_coin_position_information() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_account_trades(futuresClientAsync): await futuresClientAsync.futures_coin_account_trades() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_income_history(futuresClientAsync): await futuresClientAsync.futures_coin_income_history() - @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_change_position_mode(futuresClientAsync): await futuresClientAsync.futures_coin_change_position_mode() - async def test_futures_coin_get_position_mode(futuresClientAsync): await futuresClientAsync.futures_coin_get_position_mode() - async def test_futures_coin_stream_close(futuresClientAsync): listen_key = await futuresClientAsync.futures_coin_stream_get_listen_key() await futuresClientAsync.futures_coin_stream_close(listenKey=listen_key) - @pytest.mark.skip(reason="No sandbox support") async def test_futures_coin_account_order_history_download(futuresClientAsync): await futuresClientAsync.futures_coin_account_order_download() - @pytest.mark.skip(reason="No sandbox support") async def test_futures_coin_account_order_download_id(futuresClientAsync): await futuresClientAsync.futures_coin_account_order_download_link(downloadId="123") - @pytest.mark.skip(reason="No sandbox support") async def test_futures_coin_account_trade_history_download(futuresClientAsync): await futuresClientAsync.futures_coin_account_trade_history_download() - @pytest.mark.skip(reason="No sandbox support") async def test_futures_coin_account_trade_download_id(futuresClientAsync): await futuresClientAsync.futures_coin_account_trade_history_download_link( diff --git a/tests/test_async_client_margin.py b/tests/test_async_client_margin.py index 38019bc41..a13f7c099 100644 --- a/tests/test_async_client_margin.py +++ b/tests/test_async_client_margin.py @@ -1,562 +1,418 @@ import pytest - pytestmark = [pytest.mark.margin, pytest.mark.asyncio] - async def test_margin__get_account_status(asyncClient): await asyncClient.get_account_status() - async def test_margin_get_account_api_trading_status(asyncClient): await asyncClient.get_account_api_trading_status() - async def test_margin_get_account_api_permissions(asyncClient): await asyncClient.get_account_api_permissions() - async def test_margin_get_dust_assets(asyncClient): await asyncClient.get_dust_assets() - async def test_margin_get_dust_log(asyncClient): await asyncClient.test_get_dust_log() - async def test_margin_transfer_dust(asyncClient): await asyncClient.transfer_dust() - async def test_margin_get_asset_dividend_history(asyncClient): await asyncClient.get_asset_dividend_history() - async def test_margin_make_universal_transfer(asyncClient): await asyncClient.make_universal_transfer() - async def test_margin_query_universal_transfer_history(asyncClient): await asyncClient.query_universal_transfer_history() - async def test_margin_get_trade_fee(asyncClient): await asyncClient.get_trade_fee() - async def test_margin_get_asset_details(asyncClient): await asyncClient.get_asset_details() - async def test_margin_get_spot_delist_schedule(asyncClient): await asyncClient.get_spot_delist_schedule() - # Withdraw Endpoints - async def test_margin_withdraw(asyncClient): await asyncClient.withdraw() - async def test_margin_get_deposit_history(asyncClient): await asyncClient.get_deposit_history() - async def test_margin_get_withdraw_history(asyncClient): await asyncClient.get_withdraw_history() - async def test_margin_get_withdraw_history_id(asyncClient): await asyncClient.get_withdraw_history_id() - async def test_margin_get_deposit_address(asyncClient): await asyncClient.get_deposit_address() - # Margin Trading Endpoints - async def test_margin_get_margin_account(asyncClient): await asyncClient.get_margin_account() - async def test_margin_get_isolated_margin_account(asyncClient): await asyncClient.get_isolated_margin_account() - async def test_margin_enable_isolated_margin_account(asyncClient): await asyncClient.enable_isolated_margin_account() - async def test_margin_disable_isolated_margin_account(asyncClient): await asyncClient.disable_isolated_margin_account() - async def test_margin_get_enabled_isolated_margin_account_limit(asyncClient): await asyncClient.get_enabled_isolated_margin_account_limit() - async def test_margin_get_margin_dustlog(asyncClient): await asyncClient.get_margin_dustlog() - async def test_margin_get_margin_dust_assets(asyncClient): await asyncClient.get_margin_dust_assets() - async def test_margin_transfer_margin_dust(asyncClient): await asyncClient.transfer_margin_dust() - async def test_margin_get_cross_margin_collateral_ratio(asyncClient): await asyncClient.get_cross_margin_collateral_ratio() - async def test_margin_get_small_liability_exchange_assets(asyncClient): await asyncClient.get_small_liability_exchange_assets() - async def test_margin_exchange_small_liability_assets(asyncClient): await asyncClient.exchange_small_liability_assets() - async def test_margin_get_small_liability_exchange_history(asyncClient): await asyncClient.get_small_liability_exchange_history() - async def test_margin_get_future_hourly_interest_rate(asyncClient): await asyncClient.get_future_hourly_interest_rate() - async def test_margin_get_margin_capital_flow(asyncClient): await asyncClient.get_margin_capital_flow() - async def test_margin_get_margin_asset(asyncClient): await asyncClient.get_margin_asset() - async def test_margin_get_margin_symbol(asyncClient): await asyncClient.get_margin_symbol() - async def test_margin_get_margin_all_assets(asyncClient): await asyncClient.get_margin_all_assets() - async def test_margin_get_margin_all_pairs(asyncClient): await asyncClient.get_margin_all_pairs() - async def test_margin_create_isolated_margin_account(asyncClient): await asyncClient.create_isolated_margin_account() - async def test_margin_get_isolated_margin_symbol(asyncClient): await asyncClient.get_isolated_margin_symbol() - async def test_margin_get_all_isolated_margin_symbols(asyncClient): await asyncClient.get_all_isolated_margin_symbols() - async def test_margin_get_isolated_margin_fee_data(asyncClient): await asyncClient.get_isolated_margin_fee_data() - async def test_margin_get_isolated_margin_tier_data(asyncClient): await asyncClient.get_isolated_margin_tier_data() - async def test_margin_margin_manual_liquidation(asyncClient): await asyncClient.margin_manual_liquidation() - async def test_margin_toggle_bnb_burn_spot_margin(asyncClient): await asyncClient.toggle_bnb_burn_spot_margin() - async def test_margin_get_bnb_burn_spot_margin(asyncClient): await asyncClient.get_bnb_burn_spot_margin() - async def test_margin_get_margin_price_index(asyncClient): await asyncClient.get_margin_price_index() - async def test_margin_transfer_margin_to_spot(asyncClient): await asyncClient.transfer_margin_to_spot() - async def test_margin_transfer_spot_to_margin(asyncClient): await asyncClient.transfer_spot_to_margin() - async def test_margin_transfer_isolated_margin_to_spot(asyncClient): await asyncClient.transfer_isolated_margin_to_spot() - async def test_margin_transfer_spot_to_isolated_margin(asyncClient): await asyncClient.transfer_spot_to_isolated_margin() - async def test_margin_get_isolated_margin_tranfer_history(asyncClient): await asyncClient.get_isolated_margin_tranfer_history() - async def test_margin_create_margin_loan(asyncClient): await asyncClient.create_margin_loan() - async def test_margin_repay_margin_loan(asyncClient): await asyncClient.repay_margin_loan() - async def create_margin_ordertest_(asyncClient): await asyncClient.create_margin_order() - async def test_margin_cancel_margin_order(asyncClient): await asyncClient.cancel_margin_order() - async def test_margin_set_margin_max_leverage(asyncClient): await asyncClient.set_margin_max_leverage() - async def test_margin_get_margin_transfer_history(asyncClient): await asyncClient.get_margin_transfer_history() - async def test_margin_get_margin_loan_details(asyncClient): await asyncClient.get_margin_loan_details() - async def test_margin_get_margin_repay_details(asyncClient): await asyncClient.get_margin_repay_details() - async def test_margin_get_cross_margin_data(asyncClient): await asyncClient.get_cross_margin_data() - async def test_margin_get_margin_interest_history(asyncClient): await asyncClient.get_margin_interest_history() - async def test_margin_get_margin_force_liquidation_rec(asyncClient): await asyncClient.get_margin_force_liquidation_rec() - async def test_margin_get_margin_order(asyncClient): await asyncClient.get_margin_order() - async def test_margin_get_open_margin_orders(asyncClient): await asyncClient.get_open_margin_orders() - async def test_margin_get_all_margin_orders(asyncClient): await asyncClient.get_all_margin_orders() - async def test_margin_get_margin_trades(asyncClient): await asyncClient.get_margin_trades() - async def test_margin_get_max_margin_loan(asyncClient): await asyncClient.get_max_margin_loan() - async def test_margin_get_max_margin_transfer(asyncClient): await asyncClient.get_max_margin_transfer() - async def test_margin_get_margin_delist_schedule(asyncClient): await asyncClient.get_margin_delist_schedule() - # Margin OCO - async def test_margin_create_margin_oco_order(asyncClient): await asyncClient.create_margin_oco_order() - async def test_margin_cancel_margin_oco_order(asyncClient): await asyncClient.cancel_margin_oco_order() - async def test_margin_get_margin_oco_order(asyncClient): await asyncClient.get_margin_oco_order() - async def test_margin_get_open_margin_oco_orders(asyncClient): await asyncClient.get_open_margin_oco_orders() - # Cross-margin - async def test_margin_margin_stream_get_listen_key(asyncClient): await asyncClient.margin_stream_get_listen_key() - async def test_margin_margin_stream_close(asyncClient): await asyncClient.margin_stream_close() - # Isolated margin - async def test_margin_isolated_margin_stream_get_listen_key(asyncClient): await asyncClient.isolated_margin_stream_get_listen_key() - async def test_margin_isolated_margin_stream_close(asyncClient): await asyncClient.isolated_margin_stream_close() - # Simple Earn Endpoints - async def test_margin_get_simple_earn_flexible_product_list(asyncClient): await asyncClient.get_simple_earn_flexible_product_list() - async def test_margin_get_simple_earn_locked_product_list(asyncClient): await asyncClient.get_simple_earn_locked_product_list() - async def test_margin_subscribe_simple_earn_flexible_product(asyncClient): await asyncClient.subscribe_simple_earn_flexible_product() - async def test_margin_subscribe_simple_earn_locked_product(asyncClient): await asyncClient.subscribe_simple_earn_locked_product() - async def test_margin_redeem_simple_earn_flexible_product(asyncClient): await asyncClient.redeem_simple_earn_flexible_product() - async def test_margin_redeem_simple_earn_locked_product(asyncClient): await asyncClient.redeem_simple_earn_locked_product() - async def test_margin_get_simple_earn_flexible_product_position(asyncClient): await asyncClient.get_simple_earn_flexible_product_position() - async def test_margin_get_simple_earn_locked_product_position(asyncClient): await asyncClient.get_simple_earn_locked_product_position() - async def test_margin_get_simple_earn_account(asyncClient): await asyncClient.get_simple_earn_account() - # Lending Endpoints - async def test_margin_get_fixed_activity_project_list(asyncClient): await asyncClient.get_fixed_activity_project_list() - async def test_margin_change_fixed_activity_to_daily_position(asyncClient): await asyncClient.change_fixed_activity_to_daily_position() - # Staking Endpoints - async def test_margin_get_staking_product_list(asyncClient): await asyncClient.get_staking_product_list() - async def test_margin_purchase_staking_product(asyncClient): await asyncClient.purchase_staking_product() - async def test_margin_redeem_staking_product(asyncClient): await asyncClient.redeem_staking_product() - async def test_margin_get_staking_position(asyncClient): await asyncClient.get_staking_position() - async def test_margin_get_staking_purchase_history(asyncClient): await asyncClient.get_staking_purchase_history() - async def test_margin_set_auto_staking(asyncClient): await asyncClient.set_auto_staking() - async def test_margin_get_personal_left_quota(asyncClient): await asyncClient.get_personal_left_quota() - # US Staking Endpoints - async def test_margin_get_staking_asset_us(asyncClient): await asyncClient.get_staking_asset_us() - async def test_margin_stake_asset_us(asyncClient): await asyncClient.stake_asset_us() - async def test_margin_unstake_asset_us(asyncClient): await asyncClient.unstake_asset_us() - async def test_margin_get_staking_balance_us(asyncClient): await asyncClient.get_staking_balance_us() - async def test_margin_get_staking_history_us(asyncClient): await asyncClient.get_staking_history_us() - async def test_margin_get_staking_rewards_history_us(asyncClient): await asyncClient.get_staking_rewards_history_us() - # Sub Accounts - async def test_margin_get_sub_account_list(asyncClient): await asyncClient.get_sub_account_list() - async def test_margin_get_sub_account_transfer_history(asyncClient): await asyncClient.get_sub_account_transfer_history() - async def test_margin_get_sub_account_futures_transfer_history(asyncClient): await asyncClient.get_sub_account_futures_transfer_history() - async def test_margin_create_sub_account_futures_transfer(asyncClient): await asyncClient.create_sub_account_futures_transfer() - async def test_margin_get_sub_account_assets(asyncClient): await asyncClient.get_sub_account_assets() - async def test_margin_query_subaccount_spot_summary(asyncClient): await asyncClient.query_subaccount_spot_summary() - async def test_margin_get_subaccount_deposit_address(asyncClient): await asyncClient.get_subaccount_deposit_address() - async def test_margin_get_subaccount_deposit_history(asyncClient): await asyncClient.get_subaccount_deposit_history() - async def test_margin_get_subaccount_futures_margin_status(asyncClient): await asyncClient.get_subaccount_futures_margin_status() - async def test_margin_enable_subaccount_margin(asyncClient): await asyncClient.enable_subaccount_margin() - async def test_margin_get_subaccount_margin_details(asyncClient): await asyncClient.get_subaccount_margin_details() - async def test_margin_get_subaccount_margin_summary(asyncClient): await asyncClient.get_subaccount_margin_summary() - async def test_margin_enable_subaccount_futures(asyncClient): await asyncClient.enable_subaccount_futures() - async def test_margin_get_subaccount_futures_details(asyncClient): await asyncClient.get_subaccount_futures_details() - async def test_margin_get_subaccount_futures_summary(asyncClient): await asyncClient.get_subaccount_futures_summary() - async def test_margin_get_subaccount_futures_positionrisk(asyncClient): await asyncClient.get_subaccount_futures_positionrisk() - async def test_margin_make_subaccount_futures_transfer(asyncClient): await asyncClient.make_subaccount_futures_transfer() - async def test_margin_make_subaccount_margin_transfer(asyncClient): await asyncClient.make_subaccount_margin_transfer() - async def test_margin_make_subaccount_to_subaccount_transfer(asyncClient): await asyncClient.make_subaccount_to_subaccount_transfer() - async def test_margin_make_subaccount_to_master_transfer(asyncClient): await asyncClient.make_subaccount_to_master_transfer() - async def test_margin_get_subaccount_transfer_history(asyncClient): await asyncClient.get_subaccount_transfer_history() - async def test_margin_make_subaccount_universal_transfer(asyncClient): await asyncClient.make_subaccount_universal_transfer() - async def test_margin_get_universal_transfer_history(asyncClient): await asyncClient.get_universal_transfer_history() - # Fiat Endpoints - async def test_margin_get_fiat_deposit_withdraw_history(asyncClient): await asyncClient.get_fiat_deposit_withdraw_history() - async def test_margin_get_fiat_payments_history(asyncClient): await asyncClient.get_fiat_payments_history() - # C2C Endpoints - async def test_margin_get_c2c_trade_history(asyncClient): await asyncClient.get_c2c_trade_history() - # Pay Endpoints - async def test_margin_get_pay_trade_history(asyncClient): await asyncClient.get_pay_trade_history() - # Convert Endpoints - async def test_margin_get_convert_trade_history(asyncClient): await asyncClient.get_convert_trade_history() - async def test_margin_convert_request_quote(asyncClient): await asyncClient.convert_request_quote() - async def test_margin_convert_accept_quote(asyncClient): await asyncClient.convert_accept_quote() diff --git a/tests/test_async_client_options.py b/tests/test_async_client_options.py index d78287ebb..51211253e 100644 --- a/tests/test_async_client_options.py +++ b/tests/test_async_client_options.py @@ -1,123 +1,96 @@ import pytest - pytestmark = [pytest.mark.options, pytest.mark.asyncio] - @pytest.fixture def options_symbol(liveClient): prices = liveClient.options_price() return prices[0]["symbol"] - async def test_options_ping(liveClientAsync): await liveClientAsync.options_ping() - async def test_options_time(liveClientAsync): await liveClientAsync.options_time() - @pytest.mark.skip(reason="Not implemented") async def test_options_info(liveClientAsync): await liveClientAsync.options_info() - async def test_options_exchange_info(liveClientAsync): await liveClientAsync.options_exchange_info() - async def test_options_index_price(liveClientAsync): await liveClientAsync.options_index_price(underlying="BTCUSDT") - async def test_options_price(liveClientAsync): prices = await liveClientAsync.options_price() - async def test_options_mark_price(liveClientAsync): await liveClientAsync.options_mark_price() - async def test_options_order_book(liveClientAsync, options_symbol): await liveClientAsync.options_order_book(symbol=options_symbol) - async def test_options_klines(liveClientAsync, options_symbol): await liveClientAsync.options_klines(symbol=options_symbol, interval="1m") - async def test_options_recent_trades(liveClientAsync, options_symbol): await liveClientAsync.options_recent_trades(symbol=options_symbol) - async def test_options_historical_trades(liveClientAsync, options_symbol): await liveClientAsync.options_historical_trades(symbol=options_symbol) - # Account and trading interface endpoints - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_account_info(liveClientAsync): await liveClientAsync.options_account_info() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_funds_transfer(liveClientAsync): await liveClientAsync.options_funds_transfer() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_positions(liveClientAsync): await liveClientAsync.options_positions() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_bill(liveClientAsync): await liveClientAsync.options_bill() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_place_order(liveClientAsync): await liveClientAsync.options_place_order() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_test_options_place_batch_order(liveClientAsync): await liveClientAsync.test_options_place_batch_order() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_cancel_order(liveClientAsync): await liveClientAsync.options_cancel_order() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_cancel_batch_order(liveClientAsync): await liveClientAsync.options_cancel_batch_order() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_cancel_all_orders(liveClientAsync): await liveClientAsync.options_cancel_all_orders() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_query_order(liveClientAsync): await liveClientAsync.options_query_order() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_query_pending_orders(liveClientAsync): await liveClientAsync.options_query_pending_orders() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_query_order_history(liveClientAsync): await liveClientAsync.options_query_order_history() - @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_user_trades(liveClientAsync): await liveClientAsync.options_user_trades() diff --git a/tests/test_async_client_ws_api.py b/tests/test_async_client_ws_api.py index c72a8e7da..8475c17ec 100644 --- a/tests/test_async_client_ws_api.py +++ b/tests/test_async_client_ws_api.py @@ -1,76 +1,61 @@ import pytest - @pytest.mark.asyncio() async def test_ws_get_order_book(clientAsync): await clientAsync.ws_get_order_book(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_recent_trades(clientAsync): await clientAsync.ws_get_recent_trades(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_historical_trades(clientAsync): await clientAsync.ws_get_historical_trades(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_aggregate_trades(clientAsync): await clientAsync.ws_get_aggregate_trades(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_klines(clientAsync): await clientAsync.ws_get_klines(symbol="BTCUSDT", interval="1m") - @pytest.mark.asyncio() async def test_ws_get_uiKlines(clientAsync): await clientAsync.ws_get_uiKlines(symbol="BTCUSDT", interval="1m") - @pytest.mark.asyncio() async def test_ws_get_avg_price(clientAsync): await clientAsync.ws_get_avg_price(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_ticker(clientAsync): await clientAsync.ws_get_ticker(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_trading_day_ticker(clientAsync): await clientAsync.ws_get_trading_day_ticker(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_symbol_ticker_window(clientAsync): await clientAsync.ws_get_symbol_ticker_window(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_symbol_ticker(clientAsync): await clientAsync.ws_get_symbol_ticker(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_get_orderbook_ticker(clientAsync): await clientAsync.ws_get_orderbook_ticker(symbol="BTCUSDT") - @pytest.mark.asyncio() async def test_ws_ping(clientAsync): await clientAsync.ws_ping() - @pytest.mark.asyncio() async def test_ws_get_time(clientAsync): await clientAsync.ws_get_time() - @pytest.mark.asyncio() async def test_ws_get_exchange_info(clientAsync): await clientAsync.ws_get_exchange_info(symbol="BTCUSDT") diff --git a/tests/test_async_client_ws_futures_requests.py b/tests/test_async_client_ws_futures_requests.py index 54bb4aeb4..db976aec3 100644 --- a/tests/test_async_client_ws_futures_requests.py +++ b/tests/test_async_client_ws_futures_requests.py @@ -63,12 +63,12 @@ async def test_ws_futures_create_get_edit_cancel_order_with_orjson(futuresClient ) order = await futuresClientAsync.ws_futures_create_order( symbol=ticker["symbol"], - side="BUY", + side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, - price=str(float(ticker["bidPrice"]) - 2), + price=str(float(ticker["bidPrice"]) + 2), ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.ws_futures_edit_order( @@ -96,12 +96,12 @@ async def test_ws_futures_create_get_edit_cancel_order_without_orjson(futuresCli ) order = await futuresClientAsync.ws_futures_create_order( symbol=ticker["symbol"], - side="BUY", + side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, - price=str(float(ticker["bidPrice"]) - 2), + price=str(float(ticker["bidPrice"]) + 2), ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.ws_futures_edit_order( diff --git a/tests/test_client_futures.py b/tests/test_client_futures.py index 64ba1e0b3..9d270b4ed 100644 --- a/tests/test_client_futures.py +++ b/tests/test_client_futures.py @@ -192,12 +192,12 @@ def test_futures_create_get_edit_cancel_order(futuresClient): positions = futuresClient.futures_position_information(symbol="LTCUSDT") order = futuresClient.futures_create_order( symbol=ticker["symbol"], - side="BUY", + side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, - price=str(round(float(ticker["lastPrice"]) - 1)), + price=str(round(float(ticker["lastPrice"]) + 2)), ) assert_contract_order(futuresClient, order) order = futuresClient.futures_modify_order( @@ -238,18 +238,18 @@ def test_futures_place_batch_order_and_cancel(futuresClient): batchOrders=[ { "symbol": ticker["symbol"], - "side": "BUY", + "side": "SELL", "positionSide": positions[0]["positionSide"], "type": "LIMIT", "timeInForce": "GTC", "quantity": "0.1", - "price": str(round(float(ticker["lastPrice"]) - 1, 0)), + "price": str(round(float(ticker["lastPrice"]) + 2, 0)), }, { "symbol": ticker["symbol"], "type": "LIMIT", - "side": "BUY", - "price": str(round(float(ticker["lastPrice"]) - 1, 0)), + "side": "SELL", + "price": str(round(float(ticker["lastPrice"]) + 2, 0)), "positionSide": positions[0]["positionSide"], "timeInForce": "GTC", "quantity": "0.1", diff --git a/tests/test_client_ws_futures_requests.py b/tests/test_client_ws_futures_requests.py index 488b55ddf..eb29fe0e6 100644 --- a/tests/test_client_ws_futures_requests.py +++ b/tests/test_client_ws_futures_requests.py @@ -27,12 +27,12 @@ def test_ws_futures_create_get_edit_cancel_order(futuresClient): positions = futuresClient.ws_futures_v2_account_position(symbol="LTCUSDT") order = futuresClient.ws_futures_create_order( symbol=ticker["symbol"], - side="BUY", + side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, - price=str(round(float(ticker["bidPrice"]) - 2)), + price=str(round(float(ticker["bidPrice"]) + 2)), ) assert_contract_order(futuresClient, order) order = futuresClient.ws_futures_edit_order( diff --git a/tests/test_threaded_stream.py b/tests/test_threaded_stream.py index 0752b7b5e..2d726934a 100644 --- a/tests/test_threaded_stream.py +++ b/tests/test_threaded_stream.py @@ -47,7 +47,7 @@ async def test_initialization(): "tld": "com", "testnet": True, "session_params": {"trust_env": True}, - "https_proxy": None + "https_proxy": None, } From 7180a6a1b79f04b629d05acf146743da5d10563d Mon Sep 17 00:00:00 2001 From: Pablo Date: Sun, 18 May 2025 23:19:06 +0200 Subject: [PATCH 9/9] fix test --- tests/test_async_client_futures.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_async_client_futures.py b/tests/test_async_client_futures.py index b02d564f3..d8d83504b 100644 --- a/tests/test_async_client_futures.py +++ b/tests/test_async_client_futures.py @@ -193,18 +193,18 @@ async def test_futures_place_batch_order_and_cancel(futuresClientAsync): batchOrders=[ { "positionSide": positions[0]["positionSide"], - "price": str(round(float(ticker["lastPrice"]) - 1, 0)), + "price": str(round(float(ticker["lastPrice"]) + 2, 0)), "quantity": "0.1", - "side": "BUY", + "side": "SELL", "symbol": ticker["symbol"], "timeInForce": "GTC", "type": "LIMIT", }, { - "side": "BUY", + "side": "SELL", "type": "LIMIT", "positionSide": positions[0]["positionSide"], - "price": str(round(float(ticker["lastPrice"]) - 1, 0)), + "price": str(round(float(ticker["lastPrice"]) + 2, 0)), "quantity": "0.1", "symbol": ticker["symbol"], "timeInForce": "GTC",