Skip to content

Commit

Permalink
feat: add proxy support to WS (#1467)
Browse files Browse the repository at this point in the history
* feat: add https_proxy support for ThreadedWebsocketManager and  BinanceSocketManager

* handle refactor

* remove requirement

* add readme

---------

Co-authored-by: carlosmiei <43336371+carlosmiei@users.noreply.github.com>
  • Loading branch information
animic and carlosmiei authored Nov 22, 2024
1 parent 2eeeeae commit 4b8d1ed
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Features
- Futures Trading
- Porfolio Margin Trading
- Vanilla Options
- Proxy support
- Proxy support (REST and WS)
- Orjson support for faster JSON parsing
- Support other domains (.us, .jp, etc)

Expand Down
24 changes: 23 additions & 1 deletion binance/ws/reconnecting_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
except ImportError:
from websockets import ConnectionClosedError # type: ignore


Proxy = None
proxy_connect = None
try:
from websockets_proxy import Proxy as w_Proxy, proxy_connect as w_proxy_connect
Proxy = w_Proxy
proxy_connect = w_proxy_connect
except ImportError:
pass

import websockets as ws

from binance.exceptions import BinanceWebsocketUnableToConnect
Expand All @@ -41,6 +51,7 @@ def __init__(
prefix: str = "ws/",
is_binary: bool = False,
exit_coro=None,
https_proxy: Optional[str] = None,
**kwargs,
):
self._loop = get_loop()
Expand All @@ -57,6 +68,7 @@ def __init__(
self.ws_state = WSListenerState.INITIALISING
self._queue = asyncio.Queue()
self._handle_read_loop = None
self._https_proxy = https_proxy
self._ws_kwargs = kwargs

def json_dumps(self, msg):
Expand Down Expand Up @@ -93,10 +105,20 @@ async def connect(self):
self._log.debug("Establishing new WebSocket connection")
self.ws_state = WSListenerState.RECONNECTING
await self._before_connect()

ws_url = (
f"{self._url}{getattr(self, '_prefix', '')}{getattr(self, '_path', '')}"
)
self._conn = ws.connect(ws_url, close_timeout=0.1, **self._ws_kwargs) # type: ignore

# handle https_proxy
if self._https_proxy:
if not Proxy or not proxy_connect:
raise ImportError("websockets_proxy is not installed, please install it to use a websockets proxy (pip install websockets_proxy)")
proxy = Proxy.from_url(self._https_proxy) # type: ignore
self._conn = proxy_connect(ws_url, close_timeout=0.1, proxy=proxy, **self._ws_kwargs) # type: ignore
else:
self._conn = ws.connect(ws_url, close_timeout=0.1, **self._ws_kwargs) # type: ignore

try:
self.ws = await self._conn.__aenter__()
except Exception as e: # noqa
Expand Down
5 changes: 4 additions & 1 deletion binance/ws/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def _get_socket(
prefix=prefix,
exit_coro=lambda p: self._exit_socket(f"{socket_type}_{p}"),
is_binary=is_binary,
https_proxy=self._client.https_proxy,
**self.ws_kwargs,
)

Expand All @@ -104,6 +105,7 @@ def _get_account_socket(
exit_coro=self._exit_socket,
is_binary=is_binary,
user_timeout=self._user_timeout,
https_proxy=self._client.https_proxy,
**self.ws_kwargs,
)

Expand Down Expand Up @@ -1094,10 +1096,11 @@ def __init__(
tld: str = "com",
testnet: bool = False,
session_params: Optional[Dict[str, Any]] = None,
https_proxy: Optional[str] = None,
loop: Optional[asyncio.AbstractEventLoop] = None,
):
super().__init__(
api_key, api_secret, requests_params, tld, testnet, session_params, loop
api_key, api_secret, requests_params, tld, testnet, session_params, https_proxy, loop
)
self._bsm: Optional[BinanceSocketManager] = None

Expand Down
2 changes: 2 additions & 0 deletions binance/ws/threaded_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def __init__(
tld: str = "com",
testnet: bool = False,
session_params: Optional[Dict[str, Any]] = None,
https_proxy: Optional[str] = None,
_loop: Optional[asyncio.AbstractEventLoop] = None,
):
"""Initialise the BinanceSocketManager"""
Expand All @@ -30,6 +31,7 @@ def __init__(
"tld": tld,
"testnet": testnet,
"session_params": session_params,
"https_proxy": https_proxy,
}

async def _before_socket_listener_start(self): ...
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"six",
"dateparser",
"aiohttp",
"ujson",
"websockets",
"pycryptodome",
],
Expand Down

0 comments on commit 4b8d1ed

Please sign in to comment.