Skip to content

Commit

Permalink
v4.0.0 release (#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
urbanogt authored Aug 8, 2023
1 parent 7fc9623 commit 395cfe1
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 4.0.0 - 2023-08-08

### Changed
- Add proxy support for websockets
- Remove support for Python 3.7

## 4.0.0rc3 - 2023-07-03

### Changed
Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,47 @@ my_client.agg_trade(symbol="bnbusdt", id="my_request_id")
# library will generate a random uuid string
my_client.agg_trade(symbol="bnbusdt")
```
#### Proxy

Proxy is supported for both WebSocket CM futures and UM futures.

To use it, pass in the `proxies` parameter when initializing the client.

The format of the `proxies` parameter is the same as the one used in the Spot RESTful API.

It consists on a dictionary with the following format, where the key is the type of the proxy and the value is the proxy URL:

For websockets, the proxy type is `http`.

```python
proxies = { 'http': 'http://1.2.3.4:8080' }
```

You can also use authentication for the proxy by adding the `username` and `password` parameters to the proxy URL:

```python
proxies = { 'http': 'http://username:password@host:port' }
```

```python
# WebSocket Stream Client
import time
from binance.websocket.um_futures.websocket_client import UMFuturesWebsocketClient

proxies = {'http': 'http://1.2.3.4:8080'}

def message_handler(_, message):
logging.info(message)

my_client = UMFuturesWebsocketClient(on_message=message_handler, proxies=proxies)

# Subscribe to a single symbol stream
my_client.agg_trade(symbol="bnbusdt")
time.sleep(5)
logging.info("closing ws connection")
my_client.stop()
```


#### Combined Streams
- If you set `is_combined` to `True`, `"/stream/"` will be appended to the `baseURL` to allow for Combining streams.
Expand Down
2 changes: 1 addition & 1 deletion binance/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "4.0.0rc3"
__version__ = "4.0.0"
20 changes: 18 additions & 2 deletions binance/lib/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
import time

from urllib.parse import urlencode
from urllib.parse import urlencode, urlparse
from binance.error import (
ParameterRequiredError,
ParameterValueError,
Expand Down Expand Up @@ -40,7 +40,7 @@ def check_enum_parameter(value, enum_class):


def check_type_parameter(value, name, data_type):
if value is not None and type(value) != data_type:
if value is not None and not isinstance(value, data_type):
raise ParameterTypeError([name, data_type])


Expand All @@ -64,3 +64,19 @@ def convert_list_to_json_array(symbols):

def config_logging(logging, logging_devel, log_file=None):
logging.basicConfig(level=logging_devel, filename=log_file)


def parse_proxies(proxies: dict):
"""Parse proxy url from dict, only support http and https proxy, not support socks5 proxy"""
proxy_url = proxies.get("http") or proxies.get("https")
if not proxy_url:
return {}

parsed = urlparse(proxy_url)
return {
"http_proxy_host": parsed.hostname,
"http_proxy_port": parsed.port,
"http_proxy_auth": (parsed.username, parsed.password)
if parsed.username and parsed.password
else None,
}
14 changes: 11 additions & 3 deletions binance/websocket/binance_socket_manager.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

import logging
import threading
from websocket import (
Expand All @@ -6,6 +8,7 @@
WebSocketException,
WebSocketConnectionClosedException,
)
from binance.lib.utils import parse_proxies


class BinanceSocketManager(threading.Thread):
Expand All @@ -19,6 +22,7 @@ def __init__(
on_ping=None,
on_pong=None,
logger=None,
proxies: Optional[dict] = None,
):
threading.Thread.__init__(self)
if not logger:
Expand All @@ -31,15 +35,19 @@ def __init__(
self.on_ping = on_ping
self.on_pong = on_pong
self.on_error = on_error
self.proxies = proxies

self._proxy_params = parse_proxies(proxies) if proxies else {}

self.create_ws_connection()

def create_ws_connection(self):
self.logger.debug(
"Creating connection with WebSocket Server: %s", self.stream_url
f"Creating connection with WebSocket Server: {self.stream_url}, proxies: {self.proxies}",
)
self.ws = create_connection(self.stream_url)
self.ws = create_connection(self.stream_url, **self._proxy_params)
self.logger.debug(
"WebSocket connection has been established: %s", self.stream_url
f"WebSocket connection has been established: {self.stream_url}, proxies: {self.proxies}",
)
self._callback(self.on_open)

Expand Down
4 changes: 4 additions & 0 deletions binance/websocket/cm_futures/websocket_client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from binance.websocket.websocket_client import BinanceWebsocketClient


Expand All @@ -12,6 +14,7 @@ def __init__(
on_ping=None,
on_pong=None,
is_combined=False,
proxies: Optional[dict] = None,
):
if is_combined:
stream_url = stream_url + "/stream"
Expand All @@ -25,6 +28,7 @@ def __init__(
on_error=on_error,
on_ping=on_ping,
on_pong=on_pong,
proxies=proxies,
)

def agg_trade(self, symbol: str, id=None, action=None, **kwargs):
Expand Down
4 changes: 4 additions & 0 deletions binance/websocket/um_futures/websocket_client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from binance.websocket.websocket_client import BinanceWebsocketClient


Expand All @@ -12,6 +14,7 @@ def __init__(
on_ping=None,
on_pong=None,
is_combined=False,
proxies: Optional[dict] = None,
):
if is_combined:
stream_url = stream_url + "/stream"
Expand All @@ -25,6 +28,7 @@ def __init__(
on_error=on_error,
on_ping=on_ping,
on_pong=on_pong,
proxies=proxies,
)

def agg_trade(self, symbol: str, id=None, action=None, **kwargs):
Expand Down
7 changes: 7 additions & 0 deletions binance/websocket/websocket_client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from typing import Optional

import json
import logging

from binance.lib.utils import get_timestamp
from binance.websocket.binance_socket_manager import BinanceSocketManager

Expand All @@ -18,6 +21,7 @@ def __init__(
on_ping=None,
on_pong=None,
logger=None,
proxies: Optional[dict] = None,
):
if not logger:
logger = logging.getLogger(__name__)
Expand All @@ -31,6 +35,7 @@ def __init__(
on_ping,
on_pong,
logger,
proxies,
)

# start the thread
Expand All @@ -47,6 +52,7 @@ def _initialize_socket(
on_ping,
on_pong,
logger,
proxies,
):
return BinanceSocketManager(
stream_url,
Expand All @@ -57,6 +63,7 @@ def _initialize_socket(
on_ping=on_ping,
on_pong=on_pong,
logger=logger,
proxies=proxies,
)

def _single_stream(self, stream):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
"Intended Audience :: Developers",
"Intended Audience :: Financial and Insurance Industry",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
],
python_requires=">=3.7",
)
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py36,py37,py38,py39
envlist = py38,py39,py310,py311

[testenv]
deps =
Expand Down

1 comment on commit 395cfe1

@StemmlerSisters
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.