Skip to content

Commit

Permalink
feat: add async dapi endpoints (#1490)
Browse files Browse the repository at this point in the history
* feat: add async dapi endpoints

* rename

* add tests
  • Loading branch information
pcriadoperez authored Dec 2, 2024
1 parent 792612a commit d944e6e
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 4 deletions.
36 changes: 36 additions & 0 deletions binance/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2165,6 +2165,42 @@ async def futures_coin_stream_keepalive(self, listenKey):
"put", "listenKey", signed=False, data=params
)

async def futures_coin_account_order_history_download(self, **params):
return await self._request_futures_coin_api(
"get", "order/asyn", True, data=params
)

futures_coin_account_order_history_download.__doc__ = (
Client.futures_coin_account_order_history_download.__doc__
)

async def futures_coin_account_order_history_download_link(self, **params):
return await self._request_futures_coin_api(
"get", "order/asyn/id", True, data=params
)

futures_coin_account_order_history_download_link.__doc__ = (
Client.futures_coin_accout_order_history_download_link.__doc__
)

async def futures_coin_account_trade_history_download(self, **params):
return await self._request_futures_coin_api(
"get", "trade/asyn", True, data=params
)

futures_coin_account_trade_history_download.__doc__ = (
Client.futures_coin_account_trade_history_download.__doc__
)

async def futures_coin_account_trade_history_download_link(self, **params):
return await self._request_futures_coin_api(
"get", "trade/asyn/id", True, data=params
)

futures_coin_account_trade_history_download_link.__doc__ = (
Client.futures_coin_account_trade_history_download_link.__doc__
)

async def futures_coin_stream_close(self, listenKey):
params = {"listenKey": listenKey}
return await self._request_futures_coin_api(
Expand Down
140 changes: 140 additions & 0 deletions binance/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8093,6 +8093,146 @@ def futures_coin_stream_close(self, listenKey):
"delete", "listenKey", signed=False, data=params
)

def futures_coin_account_order_history_download(self, **params):
"""Get Download Id For Futures Order History
https://developers.binance.com/docs/derivatives/coin-margined-futures/account/Get-Download-Id-For-Futures-Order-History
:param startTime: required - Start timestamp in ms
:type startTime: int
:param endTime: required - End timestamp in ms
:type endTime: int
:param recvWindow: optional
:type recvWindow: int
:returns: API response
.. code-block:: python
{
"avgCostTimestampOfLast30d": 7241837, # Average time taken for data download in the past 30 days
"downloadId": "546975389218332672"
}
Note:
- Request Limitation is 10 times per month, shared by front end download page and rest api
- The time between startTime and endTime can not be longer than 1 year
:raises: BinanceRequestException, BinanceAPIException
"""
return self._request_futures_coin_api(
"get", "order/asyn", signed=True, data=params
)

def futures_coin_accout_order_history_download_link(self, **params):
"""Get futures order history download link by Id
https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Futures-Order-History-Download-Link-by-Id
:param downloadId: required - Download ID obtained from futures_coin_download_id
:type downloadId: str
:param recvWindow: optional
:type recvWindow: int
:returns: API response
.. code-block:: python
{
"downloadId": "545923594199212032",
"status": "completed", # Enum:completed,processing
"url": "www.binance.com", # The link is mapped to download id
"notified": true, # ignore
"expirationTimestamp": 1645009771000, # The link would expire after this timestamp
"isExpired": null
}
# OR (Response when server is processing)
{
"downloadId": "545923594199212032",
"status": "processing",
"url": "",
"notified": false,
"expirationTimestamp": -1,
"isExpired": null
}
Note:
- Download link expiration: 24h
:raises: BinanceRequestException, BinanceAPIException
"""
return self._request_futures_coin_api("get", "order/asyn/id", True, data=params)

def futures_coin_account_trade_history_download(self, **params):
"""Get Download Id For Futures Trade History (USER_DATA)
https://developers.binance.com/docs/derivatives/coin-margined-futures/account/Get-Download-Id-For-Futures-Trade-History
:param startTime: required - Start timestamp in ms
:type startTime: int
:param endTime: required - End timestamp in ms
:type endTime: int
:returns: API response
.. code-block:: python
{
"avgCostTimestampOfLast30d": 7241837, # Average time taken for data download in the past 30 days
"downloadId": "546975389218332672"
}
Note:
- Request Limitation is 5 times per month, shared by front end download page and rest api
- The time between startTime and endTime can not be longer than 1 year
:raises: BinanceRequestException, BinanceAPIException
"""
return self._request_futures_coin_api("get", "trade/asyn", True, data=params)

def futures_coin_account_trade_history_download_link(self, **params):
"""Get futures trade download link by Id
https://developers.binance.com/docs/derivatives/coin-margined-futures/account/Get-Futures-Trade-Download-Link-by-Id
:param downloadId: required - Download ID obtained from futures_coin_trade_download_id
:type downloadId: str
:returns: API response
.. code-block:: python
{
"downloadId": "545923594199212032",
"status": "completed", # Enum:completed,processing
"url": "www.binance.com", # The link is mapped to download id
"notified": true, # ignore
"expirationTimestamp": 1645009771000, # The link would expire after this timestamp
"isExpired": null
}
# OR (Response when server is processing)
{
"downloadId": "545923594199212032",
"status": "processing",
"url": "",
"notified": false,
"expirationTimestamp": -1,
"isExpired": null
}
Note:
- Download link expiration: 24h
:raises: BinanceRequestException, BinanceAPIException
"""
return self._request_futures_coin_api("get", "trade/asyn/id", True, data=params)

def get_all_coins_info(self, **params):
"""Get information of coins (available for deposit and withdraw) for user.
Expand Down
20 changes: 20 additions & 0 deletions tests/test_async_client_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,3 +579,23 @@ async def test_futures_coin_get_position_mode(futuresClientAsync):
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(downloadId="123")
113 changes: 109 additions & 4 deletions tests/test_client_futures.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from datetime import datetime
import re

import pytest
import requests_mock
from .test_order import assert_contract_order
from .test_get_order_book import assert_ob

Expand Down Expand Up @@ -536,21 +538,18 @@ def test_futures_coin_change_position_margin(futuresClient):
futuresClient.futures_coin_change_position_margin()


@pytest.mark.skip(reason="Not implemented")
def test_futures_coin_position_margin_history(futuresClient):
futuresClient.futures_coin_position_margin_history()
futuresClient.futures_coin_position_margin_history(symbol="LTCUSD_PERP")


def test_futures_coin_position_information(futuresClient):
futuresClient.futures_coin_position_information()


@pytest.mark.skip(reason="Not implemented")
def test_futures_coin_account_trades(futuresClient):
futuresClient.futures_coin_account_trades()


@pytest.mark.skip(reason="Not implemented")
def test_futures_coin_income_history(futuresClient):
futuresClient.futures_coin_income_history()

Expand All @@ -567,3 +566,109 @@ def test_futures_coin_get_position_mode(futuresClient):
def test_futures_coin_stream_close(futuresClient):
listen_key = futuresClient.futures_coin_stream_get_listen_key()
futuresClient.futures_coin_stream_close(listenKey=listen_key)

########################################################
# Test block trades
########################################################

@pytest.mark.skip(reason="No sandbox support")
def test_futures_coin_account_order_history_download(futuresClient):
futuresClient.futures_coin_account_order_download()


@pytest.mark.skip(reason="No sandbox support")
def test_futures_coin_account_order_download_id(futuresClient):
futuresClient.futures_coin_account_order_download_link(downloadId="123")


@pytest.mark.skip(reason="No sandbox support")
def test_futures_coin_account_trade_history_download(futuresClient):
futuresClient.futures_coin_account_trade_history_download()


@pytest.mark.skip(reason="No sandbox support")
def test_futures_coin_account_trade_download_id(futuresClient):
futuresClient.futures_coin_account_trade_history_download_link(downloadId="123")


def test_futures_coin_account_order_history_download_mock(futuresClient):
expected_response = {
"avgCostTimestampOfLast30d": 7241837,
"downloadId": "546975389218332672",
}
url_pattern = re.compile(
r"https://(?:testnet\.)?binancefuture\.com/dapi/v1/order/asyn"
r"\?recvWindow=\d+"
r"&timestamp=\d+"
r"&signature=[a-f0-9]{64}"
)

with requests_mock.mock() as m:
m.get(
url_pattern,
json=expected_response,
)
response = futuresClient.futures_coin_account_order_history_download()
assert response == expected_response


def test_futures_coin_account_order_download_id_mock(futuresClient):
expected_response = {"link": "hello"}
url_pattern = re.compile(
r"https://(?:testnet\.)?binancefuture\.com/dapi/v1/order/asyn/id"
r"\?downloadId=123"
r"&recvWindow=\d+"
r"&timestamp=\d+"
r"&signature=.+"
)
with requests_mock.mock() as m:
m.get(
url_pattern,
json=expected_response,
)

response = futuresClient.futures_coin_accout_order_history_download_link(
downloadId="123"
)
assert response == expected_response

def test_futures_coin_account_trade_history_download_id_mock(futuresClient):
expected_response = {
"avgCostTimestampOfLast30d": 7241837,
"downloadId": "546975389218332672",
}
url_pattern = re.compile(
r"https://(?:testnet\.)?binancefuture\.com/dapi/v1/trade/asyn"
r"\?recvWindow=\d+"
r"&timestamp=\d+"
r"&signature=[a-f0-9]{64}"
)

with requests_mock.mock() as m:
m.get(
url_pattern,
json=expected_response,
)
response = futuresClient.futures_coin_account_trade_history_download()
assert response == expected_response


def test_futures_coin_account_trade_history_download_link_mock(futuresClient):
expected_response = {"link": "hello"}
url_pattern = re.compile(
r"https://(?:testnet\.)?binancefuture\.com/dapi/v1/trade/asyn/id"
r"\?downloadId=123"
r"&recvWindow=\d+"
r"&timestamp=\d+"
r"&signature=.+"
)
with requests_mock.mock() as m:
m.get(
url_pattern,
json=expected_response,
)

response = futuresClient.futures_coin_account_trade_history_download_link(
downloadId="123"
)
assert response == expected_response

0 comments on commit d944e6e

Please sign in to comment.