python-binance 1.0.29__tar.gz → 1.0.30__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_binance-1.0.29/python_binance.egg-info → python-binance-1.0.30}/PKG-INFO +4 -3
- {python_binance-1.0.29 → python-binance-1.0.30}/README.rst +3 -2
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/__init__.py +1 -1
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/async_client.py +105 -18
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/base_client.py +31 -7
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/client.py +1309 -526
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/exceptions.py +4 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/ws/keepalive_websocket.py +45 -6
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/ws/reconnecting_websocket.py +7 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/ws/streams.py +25 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/ws/websocket_api.py +20 -7
- {python_binance-1.0.29 → python-binance-1.0.30}/pyproject.toml +3 -1
- {python_binance-1.0.29 → python-binance-1.0.30/python_binance.egg-info}/PKG-INFO +4 -3
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_async_client.py +16 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_async_client_futures.py +4 -2
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_async_client_options.py +2 -1
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_async_client_ws_api.py +2 -15
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_async_client_ws_futures_requests.py +22 -6
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_client.py +20 -3
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_client_futures.py +8 -6
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_client_options.py +2 -1
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_client_ws_api.py +3 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_client_ws_futures_requests.py +11 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_get_order_book.py +2 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_reconnecting_websocket.py +20 -2
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_socket_manager.py +2 -1
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_streams_options.py +2 -2
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_ws_api.py +56 -33
- {python_binance-1.0.29 → python-binance-1.0.30}/LICENSE +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/enums.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/helpers.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/ws/__init__.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/ws/constants.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/ws/depthcache.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/binance/ws/threaded_stream.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/python_binance.egg-info/SOURCES.txt +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/python_binance.egg-info/dependency_links.txt +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/python_binance.egg-info/requires.txt +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/python_binance.egg-info/top_level.txt +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/setup.cfg +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/setup.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_api_request.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_async_client_gift_card copy.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_async_client_margin.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_async_client_portfolio.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_client_gift_card.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_client_margin.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_client_portfolio.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_cryptography.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_depth_cache.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_futures.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_headers.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_historical_klines.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_ids.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_init.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_order.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_ping.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_streams.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_threaded_socket_manager.py +0 -0
- {python_binance-1.0.29 → python-binance-1.0.30}/tests/test_threaded_stream.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-binance
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.30
|
|
4
4
|
Summary: Binance REST API python implementation
|
|
5
5
|
Home-page: https://github.com/sammchardy/python-binance
|
|
6
6
|
Author: Sam McHardy
|
|
@@ -31,7 +31,7 @@ Requires-Dist: websockets
|
|
|
31
31
|
Requires-Dist: pycryptodome
|
|
32
32
|
|
|
33
33
|
=================================
|
|
34
|
-
Welcome to python-binance v1.0.
|
|
34
|
+
Welcome to python-binance v1.0.30
|
|
35
35
|
=================================
|
|
36
36
|
|
|
37
37
|
.. image:: https://img.shields.io/pypi/v/python-binance.svg
|
|
@@ -95,7 +95,8 @@ Features
|
|
|
95
95
|
|
|
96
96
|
- Implementation of all General, Market Data and Account endpoints.
|
|
97
97
|
- Asyncio implementation
|
|
98
|
-
-
|
|
98
|
+
- Demo trading support (by providing demo=True)
|
|
99
|
+
- Testnet support for Spot, Futures and Vanilla Options (deprecated)
|
|
99
100
|
- Simple handling of authentication include RSA and EDDSA keys
|
|
100
101
|
- No need to generate timestamps yourself, the wrapper does it for you
|
|
101
102
|
- RecvWindow sent by default
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
=================================
|
|
2
|
-
Welcome to python-binance v1.0.
|
|
2
|
+
Welcome to python-binance v1.0.30
|
|
3
3
|
=================================
|
|
4
4
|
|
|
5
5
|
.. image:: https://img.shields.io/pypi/v/python-binance.svg
|
|
@@ -63,7 +63,8 @@ Features
|
|
|
63
63
|
|
|
64
64
|
- Implementation of all General, Market Data and Account endpoints.
|
|
65
65
|
- Asyncio implementation
|
|
66
|
-
-
|
|
66
|
+
- Demo trading support (by providing demo=True)
|
|
67
|
+
- Testnet support for Spot, Futures and Vanilla Options (deprecated)
|
|
67
68
|
- Simple handling of authentication include RSA and EDDSA keys
|
|
68
69
|
- No need to generate timestamps yourself, the wrapper does it for you
|
|
69
70
|
- RecvWindow sent by default
|
|
@@ -31,6 +31,7 @@ class AsyncClient(BaseClient):
|
|
|
31
31
|
tld: str = "com",
|
|
32
32
|
base_endpoint: str = BaseClient.BASE_ENDPOINT_DEFAULT,
|
|
33
33
|
testnet: bool = False,
|
|
34
|
+
demo: bool = False,
|
|
34
35
|
loop=None,
|
|
35
36
|
session_params: Optional[Dict[str, Any]] = None,
|
|
36
37
|
private_key: Optional[Union[str, Path]] = None,
|
|
@@ -41,6 +42,15 @@ class AsyncClient(BaseClient):
|
|
|
41
42
|
self.https_proxy = https_proxy
|
|
42
43
|
self.loop = loop or get_loop()
|
|
43
44
|
self._session_params: Dict[str, Any] = session_params or {}
|
|
45
|
+
|
|
46
|
+
# Convert https_proxy to requests_params format for BaseClient
|
|
47
|
+
if https_proxy and requests_params is None:
|
|
48
|
+
requests_params = {'proxies': {'http': https_proxy, 'https': https_proxy}}
|
|
49
|
+
elif https_proxy and requests_params is not None:
|
|
50
|
+
if 'proxies' not in requests_params:
|
|
51
|
+
requests_params['proxies'] = {}
|
|
52
|
+
requests_params['proxies'].update({'http': https_proxy, 'https': https_proxy})
|
|
53
|
+
|
|
44
54
|
super().__init__(
|
|
45
55
|
api_key,
|
|
46
56
|
api_secret,
|
|
@@ -48,6 +58,7 @@ class AsyncClient(BaseClient):
|
|
|
48
58
|
tld,
|
|
49
59
|
base_endpoint,
|
|
50
60
|
testnet,
|
|
61
|
+
demo,
|
|
51
62
|
private_key,
|
|
52
63
|
private_key_pass,
|
|
53
64
|
time_unit=time_unit,
|
|
@@ -62,6 +73,7 @@ class AsyncClient(BaseClient):
|
|
|
62
73
|
tld: str = "com",
|
|
63
74
|
base_endpoint: str = BaseClient.BASE_ENDPOINT_DEFAULT,
|
|
64
75
|
testnet: bool = False,
|
|
76
|
+
demo: bool = False,
|
|
65
77
|
loop=None,
|
|
66
78
|
session_params: Optional[Dict[str, Any]] = None,
|
|
67
79
|
private_key: Optional[Union[str, Path]] = None,
|
|
@@ -76,6 +88,7 @@ class AsyncClient(BaseClient):
|
|
|
76
88
|
tld,
|
|
77
89
|
base_endpoint,
|
|
78
90
|
testnet,
|
|
91
|
+
demo,
|
|
79
92
|
loop,
|
|
80
93
|
session_params,
|
|
81
94
|
private_key,
|
|
@@ -151,6 +164,9 @@ class AsyncClient(BaseClient):
|
|
|
151
164
|
url_encoded_data = urlencode(dict_data)
|
|
152
165
|
data = f"{url_encoded_data}&signature={signature}"
|
|
153
166
|
|
|
167
|
+
# Remove proxies from kwargs since aiohttp uses 'proxy' parameter instead
|
|
168
|
+
kwargs.pop('proxies', None)
|
|
169
|
+
|
|
154
170
|
async with getattr(self.session, method)(
|
|
155
171
|
yarl.URL(uri, encoded=True),
|
|
156
172
|
proxy=self.https_proxy,
|
|
@@ -283,7 +299,7 @@ class AsyncClient(BaseClient):
|
|
|
283
299
|
get_products.__doc__ = Client.get_products.__doc__
|
|
284
300
|
|
|
285
301
|
async def get_exchange_info(self) -> Dict:
|
|
286
|
-
return await self._get("exchangeInfo"
|
|
302
|
+
return await self._get("exchangeInfo")
|
|
287
303
|
|
|
288
304
|
get_exchange_info.__doc__ = Client.get_exchange_info.__doc__
|
|
289
305
|
|
|
@@ -301,12 +317,12 @@ class AsyncClient(BaseClient):
|
|
|
301
317
|
# General Endpoints
|
|
302
318
|
|
|
303
319
|
async def ping(self) -> Dict:
|
|
304
|
-
return await self._get("ping"
|
|
320
|
+
return await self._get("ping")
|
|
305
321
|
|
|
306
322
|
ping.__doc__ = Client.ping.__doc__
|
|
307
323
|
|
|
308
324
|
async def get_server_time(self) -> Dict:
|
|
309
|
-
return await self._get("time"
|
|
325
|
+
return await self._get("time")
|
|
310
326
|
|
|
311
327
|
get_server_time.__doc__ = Client.get_server_time.__doc__
|
|
312
328
|
|
|
@@ -319,7 +335,7 @@ class AsyncClient(BaseClient):
|
|
|
319
335
|
if symbol:
|
|
320
336
|
params["symbol"] = symbol
|
|
321
337
|
response = await self._get(
|
|
322
|
-
"ticker/price",
|
|
338
|
+
"ticker/price", data=params
|
|
323
339
|
)
|
|
324
340
|
if isinstance(response, list) and all(isinstance(item, dict) for item in response):
|
|
325
341
|
return response
|
|
@@ -334,13 +350,13 @@ class AsyncClient(BaseClient):
|
|
|
334
350
|
elif "symbols" in params:
|
|
335
351
|
data["symbols"] = params["symbols"]
|
|
336
352
|
return await self._get(
|
|
337
|
-
"ticker/bookTicker", data=data
|
|
353
|
+
"ticker/bookTicker", data=data
|
|
338
354
|
)
|
|
339
355
|
|
|
340
356
|
get_orderbook_tickers.__doc__ = Client.get_orderbook_tickers.__doc__
|
|
341
357
|
|
|
342
358
|
async def get_order_book(self, **params) -> Dict:
|
|
343
|
-
return await self._get("depth", data=params
|
|
359
|
+
return await self._get("depth", data=params)
|
|
344
360
|
|
|
345
361
|
get_order_book.__doc__ = Client.get_order_book.__doc__
|
|
346
362
|
|
|
@@ -351,14 +367,14 @@ class AsyncClient(BaseClient):
|
|
|
351
367
|
|
|
352
368
|
async def get_historical_trades(self, **params) -> Dict:
|
|
353
369
|
return await self._get(
|
|
354
|
-
"historicalTrades", data=params
|
|
370
|
+
"historicalTrades", data=params
|
|
355
371
|
)
|
|
356
372
|
|
|
357
373
|
get_historical_trades.__doc__ = Client.get_historical_trades.__doc__
|
|
358
374
|
|
|
359
375
|
async def get_aggregate_trades(self, **params) -> Dict:
|
|
360
376
|
return await self._get(
|
|
361
|
-
"aggTrades", data=params
|
|
377
|
+
"aggTrades", data=params
|
|
362
378
|
)
|
|
363
379
|
|
|
364
380
|
get_aggregate_trades.__doc__ = Client.get_aggregate_trades.__doc__
|
|
@@ -419,12 +435,12 @@ class AsyncClient(BaseClient):
|
|
|
419
435
|
aggregate_trade_iter.__doc__ = Client.aggregate_trade_iter.__doc__
|
|
420
436
|
|
|
421
437
|
async def get_ui_klines(self, **params) -> Dict:
|
|
422
|
-
return await self._get("uiKlines", data=params
|
|
438
|
+
return await self._get("uiKlines", data=params)
|
|
423
439
|
|
|
424
440
|
get_ui_klines.__doc__ = Client.get_ui_klines.__doc__
|
|
425
441
|
|
|
426
442
|
async def get_klines(self, **params) -> Dict:
|
|
427
|
-
return await self._get("klines", data=params
|
|
443
|
+
return await self._get("klines", data=params)
|
|
428
444
|
|
|
429
445
|
get_klines.__doc__ = Client.get_klines.__doc__
|
|
430
446
|
|
|
@@ -655,33 +671,33 @@ class AsyncClient(BaseClient):
|
|
|
655
671
|
|
|
656
672
|
async def get_avg_price(self, **params):
|
|
657
673
|
return await self._get(
|
|
658
|
-
"avgPrice", data=params
|
|
674
|
+
"avgPrice", data=params
|
|
659
675
|
)
|
|
660
676
|
|
|
661
677
|
get_avg_price.__doc__ = Client.get_avg_price.__doc__
|
|
662
678
|
|
|
663
679
|
async def get_ticker(self, **params):
|
|
664
680
|
return await self._get(
|
|
665
|
-
"ticker/24hr", data=params
|
|
681
|
+
"ticker/24hr", data=params
|
|
666
682
|
)
|
|
667
683
|
|
|
668
684
|
get_ticker.__doc__ = Client.get_ticker.__doc__
|
|
669
685
|
|
|
670
686
|
async def get_symbol_ticker(self, **params):
|
|
671
687
|
return await self._get(
|
|
672
|
-
"ticker/price", data=params
|
|
688
|
+
"ticker/price", data=params
|
|
673
689
|
)
|
|
674
690
|
|
|
675
691
|
get_symbol_ticker.__doc__ = Client.get_symbol_ticker.__doc__
|
|
676
692
|
|
|
677
693
|
async def get_symbol_ticker_window(self, **params):
|
|
678
|
-
return await self._get("ticker", data=params
|
|
694
|
+
return await self._get("ticker", data=params)
|
|
679
695
|
|
|
680
696
|
get_symbol_ticker_window.__doc__ = Client.get_symbol_ticker_window.__doc__
|
|
681
697
|
|
|
682
698
|
async def get_orderbook_ticker(self, **params):
|
|
683
699
|
return await self._get(
|
|
684
|
-
"ticker/bookTicker", data=params
|
|
700
|
+
"ticker/bookTicker", data=params
|
|
685
701
|
)
|
|
686
702
|
|
|
687
703
|
get_orderbook_ticker.__doc__ = Client.get_orderbook_ticker.__doc__
|
|
@@ -1727,11 +1743,11 @@ class AsyncClient(BaseClient):
|
|
|
1727
1743
|
|
|
1728
1744
|
futures_premium_index_klines.__doc__ = Client.futures_index_price_klines.__doc__
|
|
1729
1745
|
|
|
1730
|
-
async def
|
|
1746
|
+
async def futures_continuous_klines(self, **params):
|
|
1731
1747
|
return await self._request_futures_api("get", "continuousKlines", data=params)
|
|
1732
1748
|
|
|
1733
1749
|
async def futures_historical_klines(
|
|
1734
|
-
self, symbol, interval, start_str, end_str=None, limit=
|
|
1750
|
+
self, symbol: str, interval: str, start_str, end_str=None, limit=None
|
|
1735
1751
|
):
|
|
1736
1752
|
return await self._historical_klines(
|
|
1737
1753
|
symbol,
|
|
@@ -1876,6 +1892,77 @@ class AsyncClient(BaseClient):
|
|
|
1876
1892
|
params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22()
|
|
1877
1893
|
return await self._request_futures_api("post", "order", True, data=params)
|
|
1878
1894
|
|
|
1895
|
+
async def futures_limit_order(self, **params):
|
|
1896
|
+
"""Send in a new futures limit order.
|
|
1897
|
+
|
|
1898
|
+
https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api
|
|
1899
|
+
|
|
1900
|
+
"""
|
|
1901
|
+
if "newClientOrderId" not in params:
|
|
1902
|
+
params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22()
|
|
1903
|
+
params["type"] = "LIMIT"
|
|
1904
|
+
return await self._request_futures_api("post", "order", True, data=params)
|
|
1905
|
+
|
|
1906
|
+
async def futures_market_order(self, **params):
|
|
1907
|
+
"""Send in a new futures market order.
|
|
1908
|
+
|
|
1909
|
+
https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api
|
|
1910
|
+
|
|
1911
|
+
"""
|
|
1912
|
+
if "newClientOrderId" not in params:
|
|
1913
|
+
params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22()
|
|
1914
|
+
params["type"] = "MARKET"
|
|
1915
|
+
return await self._request_futures_api("post", "order", True, data=params)
|
|
1916
|
+
|
|
1917
|
+
|
|
1918
|
+
async def futures_limit_buy_order(self, **params):
|
|
1919
|
+
"""Send in a new futures limit buy order.
|
|
1920
|
+
|
|
1921
|
+
https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api
|
|
1922
|
+
|
|
1923
|
+
"""
|
|
1924
|
+
if "newClientOrderId" not in params:
|
|
1925
|
+
params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22()
|
|
1926
|
+
params["side"] = "BUY"
|
|
1927
|
+
params["type"] = "LIMIT"
|
|
1928
|
+
return await self._request_futures_api("post", "order", True, data=params)
|
|
1929
|
+
|
|
1930
|
+
async def futures_limit_sell_order(self, **params):
|
|
1931
|
+
"""Send in a new futures limit sell order.
|
|
1932
|
+
|
|
1933
|
+
https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api
|
|
1934
|
+
|
|
1935
|
+
"""
|
|
1936
|
+
if "newClientOrderId" not in params:
|
|
1937
|
+
params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22()
|
|
1938
|
+
params["side"] = "SELL"
|
|
1939
|
+
params["type"] = "LIMIT"
|
|
1940
|
+
return await self._request_futures_api("post", "order", True, data=params)
|
|
1941
|
+
|
|
1942
|
+
async def futures_market_buy_order(self, **params):
|
|
1943
|
+
"""Send in a new futures market buy order.
|
|
1944
|
+
|
|
1945
|
+
https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api
|
|
1946
|
+
|
|
1947
|
+
"""
|
|
1948
|
+
if "newClientOrderId" not in params:
|
|
1949
|
+
params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22()
|
|
1950
|
+
params["side"] = "BUY"
|
|
1951
|
+
params["type"] = "MARKET"
|
|
1952
|
+
return await self._request_futures_api("post", "order", True, data=params)
|
|
1953
|
+
|
|
1954
|
+
async def futures_market_sell_order(self, **params):
|
|
1955
|
+
"""Send in a new futures market sell order.
|
|
1956
|
+
|
|
1957
|
+
https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api
|
|
1958
|
+
|
|
1959
|
+
"""
|
|
1960
|
+
if "newClientOrderId" not in params:
|
|
1961
|
+
params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22()
|
|
1962
|
+
params["side"] = "SELL"
|
|
1963
|
+
params["type"] = "MARKET"
|
|
1964
|
+
return await self._request_futures_api("post", "order", True, data=params)
|
|
1965
|
+
|
|
1879
1966
|
async def futures_modify_order(self, **params):
|
|
1880
1967
|
"""Modify an existing order. Currently only LIMIT order modification is supported.
|
|
1881
1968
|
|
|
@@ -5363,4 +5450,4 @@ class AsyncClient(BaseClient):
|
|
|
5363
5450
|
return await self._request_futures_api("get", "convert/orderStatus", signed=True, data=params, version=1)
|
|
5364
5451
|
|
|
5365
5452
|
futures_v1_get_convert_order_status.__doc__ = Client.futures_v1_get_convert_order_status.__doc__
|
|
5366
|
-
|
|
5453
|
+
|
|
@@ -22,14 +22,17 @@ from .helpers import get_loop
|
|
|
22
22
|
class BaseClient:
|
|
23
23
|
API_URL = "https://api{}.binance.{}/api"
|
|
24
24
|
API_TESTNET_URL = "https://testnet.binance.vision/api"
|
|
25
|
+
API_DEMO_URL = "https://demo-api.binance.com/api"
|
|
25
26
|
MARGIN_API_URL = "https://api{}.binance.{}/sapi"
|
|
26
27
|
WEBSITE_URL = "https://www.binance.{}"
|
|
27
28
|
FUTURES_URL = "https://fapi.binance.{}/fapi"
|
|
28
29
|
FUTURES_TESTNET_URL = "https://testnet.binancefuture.com/fapi"
|
|
30
|
+
FUTURES_DEMO_URL = "https://demo-fapi.binance.com/fapi"
|
|
29
31
|
FUTURES_DATA_URL = "https://fapi.binance.{}/futures/data"
|
|
30
32
|
FUTURES_DATA_TESTNET_URL = "https://testnet.binancefuture.com/futures/data"
|
|
31
33
|
FUTURES_COIN_URL = "https://dapi.binance.{}/dapi"
|
|
32
34
|
FUTURES_COIN_TESTNET_URL = "https://testnet.binancefuture.com/dapi"
|
|
35
|
+
FUTURES_COIN_DEMO_URL = "https://demo-dapi.binance.com/dapi"
|
|
33
36
|
FUTURES_COIN_DATA_URL = "https://dapi.binance.{}/futures/data"
|
|
34
37
|
FUTURES_COIN_DATA_TESTNET_URL = "https://testnet.binancefuture.com/futures/data"
|
|
35
38
|
OPTIONS_URL = "https://eapi.binance.{}/eapi"
|
|
@@ -37,9 +40,11 @@ class BaseClient:
|
|
|
37
40
|
PAPI_URL = "https://papi.binance.{}/papi"
|
|
38
41
|
WS_API_URL = "wss://ws-api.binance.{}/ws-api/v3"
|
|
39
42
|
WS_API_TESTNET_URL = "wss://ws-api.testnet.binance.vision/ws-api/v3"
|
|
43
|
+
WS_API_DEMO_URL = "wss://demo-ws-api.binance.com/ws-api/v3"
|
|
40
44
|
WS_FUTURES_URL = "wss://ws-fapi.binance.{}/ws-fapi/v1"
|
|
41
45
|
WS_FUTURES_TESTNET_URL = "wss://testnet.binancefuture.com/ws-fapi/v1"
|
|
42
|
-
|
|
46
|
+
WS_FUTURES_DEMO_URL = "wss://testnet.binancefuture.com/ws-fapi/v1"
|
|
47
|
+
PUBLIC_API_VERSION = "v3"
|
|
43
48
|
PRIVATE_API_VERSION = "v3"
|
|
44
49
|
MARGIN_API_VERSION = "v1"
|
|
45
50
|
MARGIN_API_VERSION2 = "v2"
|
|
@@ -157,6 +162,7 @@ class BaseClient:
|
|
|
157
162
|
tld: str = "com",
|
|
158
163
|
base_endpoint: str = BASE_ENDPOINT_DEFAULT,
|
|
159
164
|
testnet: bool = False,
|
|
165
|
+
demo: bool = False,
|
|
160
166
|
private_key: Optional[Union[str, Path]] = None,
|
|
161
167
|
private_key_pass: Optional[str] = None,
|
|
162
168
|
loop: Optional[asyncio.AbstractEventLoop] = None,
|
|
@@ -201,15 +207,27 @@ class BaseClient:
|
|
|
201
207
|
self._requests_params = requests_params
|
|
202
208
|
self.response = None
|
|
203
209
|
self.testnet = testnet
|
|
210
|
+
self.demo = demo
|
|
204
211
|
self.timestamp_offset = 0
|
|
205
|
-
ws_api_url = self.
|
|
212
|
+
ws_api_url = self.WS_API_URL.format(tld)
|
|
213
|
+
if testnet:
|
|
214
|
+
ws_api_url = self.WS_API_TESTNET_URL
|
|
215
|
+
elif demo:
|
|
216
|
+
ws_api_url = self.WS_API_DEMO_URL
|
|
206
217
|
if self.TIME_UNIT:
|
|
207
218
|
ws_api_url += f"?timeUnit={self.TIME_UNIT}"
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
219
|
+
# Extract proxy from requests_params for WebSocket connections
|
|
220
|
+
https_proxy = None
|
|
221
|
+
if requests_params and 'proxies' in requests_params:
|
|
222
|
+
https_proxy = requests_params['proxies'].get('https') or requests_params['proxies'].get('http')
|
|
223
|
+
|
|
224
|
+
self.ws_api = WebsocketAPI(url=ws_api_url, tld=tld, https_proxy=https_proxy)
|
|
225
|
+
ws_future_url = self.WS_FUTURES_URL.format(tld)
|
|
226
|
+
if testnet:
|
|
227
|
+
ws_future_url = self.WS_FUTURES_TESTNET_URL
|
|
228
|
+
elif demo:
|
|
229
|
+
ws_future_url = self.WS_FUTURES_DEMO_URL
|
|
230
|
+
self.ws_future = WebsocketAPI(url=ws_future_url, tld=tld, https_proxy=https_proxy)
|
|
213
231
|
self.loop = loop or get_loop()
|
|
214
232
|
|
|
215
233
|
def _get_headers(self) -> Dict:
|
|
@@ -250,6 +268,8 @@ class BaseClient:
|
|
|
250
268
|
url = self.API_URL
|
|
251
269
|
if self.testnet:
|
|
252
270
|
url = self.API_TESTNET_URL
|
|
271
|
+
elif self.demo:
|
|
272
|
+
url = self.API_DEMO_URL
|
|
253
273
|
v = self.PRIVATE_API_VERSION if signed else version
|
|
254
274
|
return url + "/" + v + "/" + path
|
|
255
275
|
|
|
@@ -273,6 +293,8 @@ class BaseClient:
|
|
|
273
293
|
url = self.FUTURES_URL
|
|
274
294
|
if self.testnet:
|
|
275
295
|
url = self.FUTURES_TESTNET_URL
|
|
296
|
+
elif self.demo:
|
|
297
|
+
url = self.FUTURES_DEMO_URL
|
|
276
298
|
options = {
|
|
277
299
|
1: self.FUTURES_API_VERSION,
|
|
278
300
|
2: self.FUTURES_API_VERSION2,
|
|
@@ -290,6 +312,8 @@ class BaseClient:
|
|
|
290
312
|
url = self.FUTURES_COIN_URL
|
|
291
313
|
if self.testnet:
|
|
292
314
|
url = self.FUTURES_COIN_TESTNET_URL
|
|
315
|
+
elif self.demo:
|
|
316
|
+
url = self.FUTURES_COIN_DEMO_URL
|
|
293
317
|
options = {
|
|
294
318
|
1: self.FUTURES_API_VERSION,
|
|
295
319
|
2: self.FUTURES_API_VERSION2,
|