Skip to content

Commit d944e6e

Browse files
authored
feat: add async dapi endpoints (sammchardy#1490)
* feat: add async dapi endpoints * rename * add tests
1 parent 792612a commit d944e6e

File tree

4 files changed

+305
-4
lines changed

4 files changed

+305
-4
lines changed

binance/async_client.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,42 @@ async def futures_coin_stream_keepalive(self, listenKey):
21652165
"put", "listenKey", signed=False, data=params
21662166
)
21672167

2168+
async def futures_coin_account_order_history_download(self, **params):
2169+
return await self._request_futures_coin_api(
2170+
"get", "order/asyn", True, data=params
2171+
)
2172+
2173+
futures_coin_account_order_history_download.__doc__ = (
2174+
Client.futures_coin_account_order_history_download.__doc__
2175+
)
2176+
2177+
async def futures_coin_account_order_history_download_link(self, **params):
2178+
return await self._request_futures_coin_api(
2179+
"get", "order/asyn/id", True, data=params
2180+
)
2181+
2182+
futures_coin_account_order_history_download_link.__doc__ = (
2183+
Client.futures_coin_accout_order_history_download_link.__doc__
2184+
)
2185+
2186+
async def futures_coin_account_trade_history_download(self, **params):
2187+
return await self._request_futures_coin_api(
2188+
"get", "trade/asyn", True, data=params
2189+
)
2190+
2191+
futures_coin_account_trade_history_download.__doc__ = (
2192+
Client.futures_coin_account_trade_history_download.__doc__
2193+
)
2194+
2195+
async def futures_coin_account_trade_history_download_link(self, **params):
2196+
return await self._request_futures_coin_api(
2197+
"get", "trade/asyn/id", True, data=params
2198+
)
2199+
2200+
futures_coin_account_trade_history_download_link.__doc__ = (
2201+
Client.futures_coin_account_trade_history_download_link.__doc__
2202+
)
2203+
21682204
async def futures_coin_stream_close(self, listenKey):
21692205
params = {"listenKey": listenKey}
21702206
return await self._request_futures_coin_api(

binance/client.py

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8093,6 +8093,146 @@ def futures_coin_stream_close(self, listenKey):
80938093
"delete", "listenKey", signed=False, data=params
80948094
)
80958095

8096+
def futures_coin_account_order_history_download(self, **params):
8097+
"""Get Download Id For Futures Order History
8098+
8099+
https://developers.binance.com/docs/derivatives/coin-margined-futures/account/Get-Download-Id-For-Futures-Order-History
8100+
8101+
:param startTime: required - Start timestamp in ms
8102+
:type startTime: int
8103+
:param endTime: required - End timestamp in ms
8104+
:type endTime: int
8105+
:param recvWindow: optional
8106+
:type recvWindow: int
8107+
8108+
:returns: API response
8109+
8110+
.. code-block:: python
8111+
8112+
{
8113+
"avgCostTimestampOfLast30d": 7241837, # Average time taken for data download in the past 30 days
8114+
"downloadId": "546975389218332672"
8115+
}
8116+
8117+
Note:
8118+
- Request Limitation is 10 times per month, shared by front end download page and rest api
8119+
- The time between startTime and endTime can not be longer than 1 year
8120+
8121+
:raises: BinanceRequestException, BinanceAPIException
8122+
8123+
"""
8124+
return self._request_futures_coin_api(
8125+
"get", "order/asyn", signed=True, data=params
8126+
)
8127+
8128+
def futures_coin_accout_order_history_download_link(self, **params):
8129+
"""Get futures order history download link by Id
8130+
8131+
https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Futures-Order-History-Download-Link-by-Id
8132+
8133+
:param downloadId: required - Download ID obtained from futures_coin_download_id
8134+
:type downloadId: str
8135+
:param recvWindow: optional
8136+
:type recvWindow: int
8137+
8138+
:returns: API response
8139+
8140+
.. code-block:: python
8141+
8142+
{
8143+
"downloadId": "545923594199212032",
8144+
"status": "completed", # Enum:completed,processing
8145+
"url": "www.binance.com", # The link is mapped to download id
8146+
"notified": true, # ignore
8147+
"expirationTimestamp": 1645009771000, # The link would expire after this timestamp
8148+
"isExpired": null
8149+
}
8150+
8151+
# OR (Response when server is processing)
8152+
{
8153+
"downloadId": "545923594199212032",
8154+
"status": "processing",
8155+
"url": "",
8156+
"notified": false,
8157+
"expirationTimestamp": -1,
8158+
"isExpired": null
8159+
}
8160+
8161+
Note:
8162+
- Download link expiration: 24h
8163+
8164+
:raises: BinanceRequestException, BinanceAPIException
8165+
8166+
"""
8167+
return self._request_futures_coin_api("get", "order/asyn/id", True, data=params)
8168+
8169+
def futures_coin_account_trade_history_download(self, **params):
8170+
"""Get Download Id For Futures Trade History (USER_DATA)
8171+
8172+
https://developers.binance.com/docs/derivatives/coin-margined-futures/account/Get-Download-Id-For-Futures-Trade-History
8173+
8174+
:param startTime: required - Start timestamp in ms
8175+
:type startTime: int
8176+
:param endTime: required - End timestamp in ms
8177+
:type endTime: int
8178+
8179+
:returns: API response
8180+
8181+
.. code-block:: python
8182+
8183+
{
8184+
"avgCostTimestampOfLast30d": 7241837, # Average time taken for data download in the past 30 days
8185+
"downloadId": "546975389218332672"
8186+
}
8187+
8188+
Note:
8189+
- Request Limitation is 5 times per month, shared by front end download page and rest api
8190+
- The time between startTime and endTime can not be longer than 1 year
8191+
8192+
:raises: BinanceRequestException, BinanceAPIException
8193+
8194+
"""
8195+
return self._request_futures_coin_api("get", "trade/asyn", True, data=params)
8196+
8197+
def futures_coin_account_trade_history_download_link(self, **params):
8198+
"""Get futures trade download link by Id
8199+
8200+
https://developers.binance.com/docs/derivatives/coin-margined-futures/account/Get-Futures-Trade-Download-Link-by-Id
8201+
8202+
:param downloadId: required - Download ID obtained from futures_coin_trade_download_id
8203+
:type downloadId: str
8204+
8205+
:returns: API response
8206+
8207+
.. code-block:: python
8208+
8209+
{
8210+
"downloadId": "545923594199212032",
8211+
"status": "completed", # Enum:completed,processing
8212+
"url": "www.binance.com", # The link is mapped to download id
8213+
"notified": true, # ignore
8214+
"expirationTimestamp": 1645009771000, # The link would expire after this timestamp
8215+
"isExpired": null
8216+
}
8217+
8218+
# OR (Response when server is processing)
8219+
{
8220+
"downloadId": "545923594199212032",
8221+
"status": "processing",
8222+
"url": "",
8223+
"notified": false,
8224+
"expirationTimestamp": -1,
8225+
"isExpired": null
8226+
}
8227+
8228+
Note:
8229+
- Download link expiration: 24h
8230+
8231+
:raises: BinanceRequestException, BinanceAPIException
8232+
8233+
"""
8234+
return self._request_futures_coin_api("get", "trade/asyn/id", True, data=params)
8235+
80968236
def get_all_coins_info(self, **params):
80978237
"""Get information of coins (available for deposit and withdraw) for user.
80988238

tests/test_async_client_futures.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,23 @@ async def test_futures_coin_get_position_mode(futuresClientAsync):
579579
async def test_futures_coin_stream_close(futuresClientAsync):
580580
listen_key = await futuresClientAsync.futures_coin_stream_get_listen_key()
581581
await futuresClientAsync.futures_coin_stream_close(listenKey=listen_key)
582+
583+
584+
@pytest.mark.skip(reason="No sandbox support")
585+
async def test_futures_coin_account_order_history_download(futuresClientAsync):
586+
await futuresClientAsync.futures_coin_account_order_download()
587+
588+
589+
@pytest.mark.skip(reason="No sandbox support")
590+
async def test_futures_coin_account_order_download_id(futuresClientAsync):
591+
await futuresClientAsync.futures_coin_account_order_download_link(downloadId="123")
592+
593+
594+
@pytest.mark.skip(reason="No sandbox support")
595+
async def test_futures_coin_account_trade_history_download(futuresClientAsync):
596+
await futuresClientAsync.futures_coin_account_trade_history_download()
597+
598+
599+
@pytest.mark.skip(reason="No sandbox support")
600+
async def test_futures_coin_account_trade_download_id(futuresClientAsync):
601+
await futuresClientAsync.futures_coin_account_trade_history_download_link(downloadId="123")

tests/test_client_futures.py

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from datetime import datetime
2+
import re
23

34
import pytest
5+
import requests_mock
46
from .test_order import assert_contract_order
57
from .test_get_order_book import assert_ob
68

@@ -536,21 +538,18 @@ def test_futures_coin_change_position_margin(futuresClient):
536538
futuresClient.futures_coin_change_position_margin()
537539

538540

539-
@pytest.mark.skip(reason="Not implemented")
540541
def test_futures_coin_position_margin_history(futuresClient):
541-
futuresClient.futures_coin_position_margin_history()
542+
futuresClient.futures_coin_position_margin_history(symbol="LTCUSD_PERP")
542543

543544

544545
def test_futures_coin_position_information(futuresClient):
545546
futuresClient.futures_coin_position_information()
546547

547548

548-
@pytest.mark.skip(reason="Not implemented")
549549
def test_futures_coin_account_trades(futuresClient):
550550
futuresClient.futures_coin_account_trades()
551551

552552

553-
@pytest.mark.skip(reason="Not implemented")
554553
def test_futures_coin_income_history(futuresClient):
555554
futuresClient.futures_coin_income_history()
556555

@@ -567,3 +566,109 @@ def test_futures_coin_get_position_mode(futuresClient):
567566
def test_futures_coin_stream_close(futuresClient):
568567
listen_key = futuresClient.futures_coin_stream_get_listen_key()
569568
futuresClient.futures_coin_stream_close(listenKey=listen_key)
569+
570+
########################################################
571+
# Test block trades
572+
########################################################
573+
574+
@pytest.mark.skip(reason="No sandbox support")
575+
def test_futures_coin_account_order_history_download(futuresClient):
576+
futuresClient.futures_coin_account_order_download()
577+
578+
579+
@pytest.mark.skip(reason="No sandbox support")
580+
def test_futures_coin_account_order_download_id(futuresClient):
581+
futuresClient.futures_coin_account_order_download_link(downloadId="123")
582+
583+
584+
@pytest.mark.skip(reason="No sandbox support")
585+
def test_futures_coin_account_trade_history_download(futuresClient):
586+
futuresClient.futures_coin_account_trade_history_download()
587+
588+
589+
@pytest.mark.skip(reason="No sandbox support")
590+
def test_futures_coin_account_trade_download_id(futuresClient):
591+
futuresClient.futures_coin_account_trade_history_download_link(downloadId="123")
592+
593+
594+
def test_futures_coin_account_order_history_download_mock(futuresClient):
595+
expected_response = {
596+
"avgCostTimestampOfLast30d": 7241837,
597+
"downloadId": "546975389218332672",
598+
}
599+
url_pattern = re.compile(
600+
r"https://(?:testnet\.)?binancefuture\.com/dapi/v1/order/asyn"
601+
r"\?recvWindow=\d+"
602+
r"&timestamp=\d+"
603+
r"&signature=[a-f0-9]{64}"
604+
)
605+
606+
with requests_mock.mock() as m:
607+
m.get(
608+
url_pattern,
609+
json=expected_response,
610+
)
611+
response = futuresClient.futures_coin_account_order_history_download()
612+
assert response == expected_response
613+
614+
615+
def test_futures_coin_account_order_download_id_mock(futuresClient):
616+
expected_response = {"link": "hello"}
617+
url_pattern = re.compile(
618+
r"https://(?:testnet\.)?binancefuture\.com/dapi/v1/order/asyn/id"
619+
r"\?downloadId=123"
620+
r"&recvWindow=\d+"
621+
r"&timestamp=\d+"
622+
r"&signature=.+"
623+
)
624+
with requests_mock.mock() as m:
625+
m.get(
626+
url_pattern,
627+
json=expected_response,
628+
)
629+
630+
response = futuresClient.futures_coin_accout_order_history_download_link(
631+
downloadId="123"
632+
)
633+
assert response == expected_response
634+
635+
def test_futures_coin_account_trade_history_download_id_mock(futuresClient):
636+
expected_response = {
637+
"avgCostTimestampOfLast30d": 7241837,
638+
"downloadId": "546975389218332672",
639+
}
640+
url_pattern = re.compile(
641+
r"https://(?:testnet\.)?binancefuture\.com/dapi/v1/trade/asyn"
642+
r"\?recvWindow=\d+"
643+
r"&timestamp=\d+"
644+
r"&signature=[a-f0-9]{64}"
645+
)
646+
647+
with requests_mock.mock() as m:
648+
m.get(
649+
url_pattern,
650+
json=expected_response,
651+
)
652+
response = futuresClient.futures_coin_account_trade_history_download()
653+
assert response == expected_response
654+
655+
656+
def test_futures_coin_account_trade_history_download_link_mock(futuresClient):
657+
expected_response = {"link": "hello"}
658+
url_pattern = re.compile(
659+
r"https://(?:testnet\.)?binancefuture\.com/dapi/v1/trade/asyn/id"
660+
r"\?downloadId=123"
661+
r"&recvWindow=\d+"
662+
r"&timestamp=\d+"
663+
r"&signature=.+"
664+
)
665+
with requests_mock.mock() as m:
666+
m.get(
667+
url_pattern,
668+
json=expected_response,
669+
)
670+
671+
response = futuresClient.futures_coin_account_trade_history_download_link(
672+
downloadId="123"
673+
)
674+
assert response == expected_response

0 commit comments

Comments
 (0)