Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Features
- Porfolio Margin Trading
- Vanilla Options
- Proxy support
- Orjson support for faster JSON parsing
- Support other domains (.us, .jp, etc)

Upgrading to v1.0.0+
Expand Down Expand Up @@ -274,14 +275,20 @@ for more information.
await client.close_connection()

if __name__ == "__main__":

loop = asyncio.get_event_loop()
loop.run_until_complete(main())


The library is under `MIT license`, that means it's absolutely free for any developer to build commercial and opensource software on top of it, but use it at your own risk with no warranties, as is.


Orjson support
-------------------

Python-binance also supports `orjson` for parsing JSON since it is much faster than the builtin library. This is especially important when using websockets because some exchanges return big messages that need to be parsed and dispatched as quickly as possible.

However, `orjson` is not enabled by default because it is not supported by every python interpreter. If you want to opt-in, you just need to install it (`pip install orjson`) on your local environment. Python-binance will detect the installion and pick it up automatically.

Star history
------------

Expand Down
19 changes: 18 additions & 1 deletion binance/ws/reconnecting_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
from asyncio import sleep
from random import random

# load orjson if available, otherwise default to json
orjson = None
try:
import orjson as orjson
except ImportError:
pass

try:
from websockets.exceptions import ConnectionClosedError # type: ignore
except ImportError:
Expand Down Expand Up @@ -52,6 +59,16 @@ def __init__(
self._handle_read_loop = None
self._ws_kwargs = kwargs

def json_dumps(self, msg):
if orjson:
return orjson.dumps(msg)
return json.dumps(msg)

def json_loads(self, msg):
if orjson:
return orjson.loads(msg)
return json.loads(msg)

async def __aenter__(self):
await self.connect()
return self
Expand Down Expand Up @@ -114,7 +131,7 @@ def _handle_message(self, evt):
except (ValueError, OSError):
return None
try:
return json.loads(evt)
return self.json_loads(evt)
except ValueError:
self._log.debug(f"error parsing evt json:{evt}")
return None
Expand Down
5 changes: 2 additions & 3 deletions binance/ws/websocket_api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import Dict
import asyncio
import json

from websockets import WebSocketClientProtocol # type: ignore

Expand Down Expand Up @@ -31,7 +30,7 @@ def _handle_message(self, msg):
if parsed_msg["status"] != 200:
throwError = True
exception = BinanceAPIException(
parsed_msg, parsed_msg["status"], json.dumps(parsed_msg["error"])
parsed_msg, parsed_msg["status"], self.json_dumps(parsed_msg["error"])
)
if req_id is not None and req_id in self._responses:
if throwError and exception is not None:
Expand Down Expand Up @@ -102,7 +101,7 @@ async def request(self, id: str, payload: dict) -> dict:
raise BinanceWebsocketUnableToConnect(
"Trying to send request while WebSocket is not connected"
)
await self.ws.send(json.dumps(payload))
await self.ws.send(self.json_dumps(payload))

# Wait for response
response = await asyncio.wait_for(future, timeout=self.TIMEOUT)
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ aiohttp
dateparser
pycryptodome
requests
ujson
websockets
Loading