Skip to content

Commit 2eeeeae

Browse files
authored
feat(websockets): add orjson support (sammchardy#1479)
* feat(websockets): add orjson support * formatting * update readme * remove unused dependency
1 parent c6dc758 commit 2eeeeae

File tree

4 files changed

+28
-6
lines changed

4 files changed

+28
-6
lines changed

README.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Features
7878
- Porfolio Margin Trading
7979
- Vanilla Options
8080
- Proxy support
81+
- Orjson support for faster JSON parsing
8182
- Support other domains (.us, .jp, etc)
8283

8384
Upgrading to v1.0.0+
@@ -274,14 +275,20 @@ for more information.
274275
await client.close_connection()
275276
276277
if __name__ == "__main__":
277-
278278
loop = asyncio.get_event_loop()
279279
loop.run_until_complete(main())
280280
281281
282282
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.
283283

284284

285+
Orjson support
286+
-------------------
287+
288+
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.
289+
290+
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.
291+
285292
Star history
286293
------------
287294

binance/ws/reconnecting_websocket.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
from asyncio import sleep
88
from random import random
99

10+
# load orjson if available, otherwise default to json
11+
orjson = None
12+
try:
13+
import orjson as orjson
14+
except ImportError:
15+
pass
16+
1017
try:
1118
from websockets.exceptions import ConnectionClosedError # type: ignore
1219
except ImportError:
@@ -52,6 +59,16 @@ def __init__(
5259
self._handle_read_loop = None
5360
self._ws_kwargs = kwargs
5461

62+
def json_dumps(self, msg):
63+
if orjson:
64+
return orjson.dumps(msg)
65+
return json.dumps(msg)
66+
67+
def json_loads(self, msg):
68+
if orjson:
69+
return orjson.loads(msg)
70+
return json.loads(msg)
71+
5572
async def __aenter__(self):
5673
await self.connect()
5774
return self
@@ -114,7 +131,7 @@ def _handle_message(self, evt):
114131
except (ValueError, OSError):
115132
return None
116133
try:
117-
return json.loads(evt)
134+
return self.json_loads(evt)
118135
except ValueError:
119136
self._log.debug(f"error parsing evt json:{evt}")
120137
return None

binance/ws/websocket_api.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from typing import Dict
22
import asyncio
3-
import json
43

54
from websockets import WebSocketClientProtocol # type: ignore
65

@@ -31,7 +30,7 @@ def _handle_message(self, msg):
3130
if parsed_msg["status"] != 200:
3231
throwError = True
3332
exception = BinanceAPIException(
34-
parsed_msg, parsed_msg["status"], json.dumps(parsed_msg["error"])
33+
parsed_msg, parsed_msg["status"], self.json_dumps(parsed_msg["error"])
3534
)
3635
if req_id is not None and req_id in self._responses:
3736
if throwError and exception is not None:
@@ -102,7 +101,7 @@ async def request(self, id: str, payload: dict) -> dict:
102101
raise BinanceWebsocketUnableToConnect(
103102
"Trying to send request while WebSocket is not connected"
104103
)
105-
await self.ws.send(json.dumps(payload))
104+
await self.ws.send(self.json_dumps(payload))
106105

107106
# Wait for response
108107
response = await asyncio.wait_for(future, timeout=self.TIMEOUT)

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ aiohttp
22
dateparser
33
pycryptodome
44
requests
5-
ujson
65
websockets

0 commit comments

Comments
 (0)