Skip to content

Commit

Permalink
Add orjson support (#815)
Browse files Browse the repository at this point in the history
  • Loading branch information
raman325 committed Nov 14, 2023
1 parent f786501 commit 392543e
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 11 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ try:
except zwave_js_server.client.FailedCommand as err:
print("Command failed with", err.error_code)
```

## Optional dependencies

`zwave-js-server-python` optionally supports `orjson` which can be installed with the `orjson` extra (e.g. `pip install zwave-js-server-python[orjson]`)
9 changes: 6 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ classifiers = [
dependencies = ["aiohttp>3", "pydantic>=1.10.0"]
dynamic = ["version"]

[project.urls]
"Source Code" = "https://github.com/home-assistant-libs/zwave-js-server-python"
"Bug Reports" = "https://github.com/home-assistant-libs/zwave-js-server-python/issues"
[project.optional-dependencies]
orjson = ["orjson>=3.9.9"]

[project.scripts]
zwave-js-server-python = "zwave_js_server.__main__:main"

[project.urls]
"Source Code" = "https://github.com/home-assistant-libs/zwave-js-server-python"
"Bug Reports" = "https://github.com/home-assistant-libs/zwave-js-server-python/issues"

[tool.setuptools.dynamic]
version = { attr = "zwave_js_server.const.__version__" }

Expand Down
1 change: 1 addition & 0 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-r requirements.txt
-r requirements_extra.txt
-r requirements_lint.txt
-r requirements_scripts.txt
-r requirements_test.txt
Expand Down
1 change: 1 addition & 0 deletions requirements_extra.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
orjson==3.9.9
4 changes: 2 additions & 2 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ async def receive():

ws_client.receive.side_effect = receive

async def close_client(msg):
async def close_client(msg, dumps=json.dumps):
"""Close the client."""
if msg["command"] in ("initialize", "start_listening"):
return
Expand Down Expand Up @@ -328,7 +328,7 @@ def apply_mock_command(
mock_responses.append((match_command, response, success))
return ack_commands

async def set_response(message):
async def set_response(message, dumps=json.dumps):
"""Check the message and set the mocked response if a command matches."""
for match_command, response, success in mock_responses:
if all(message[key] == value for key, value in match_command.items()):
Expand Down
19 changes: 16 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
[tox]
envlist = py311, lint, mypy
envlist = clean, py311, test_orjson, lint, mypy
skip_missing_interpreters = True

[gh-actions]
python =
3.11: py311, lint, mypy
3.11: clean, py311, test_orjson, lint, mypy

[testenv:clean]
deps = coverage
skip_install = true
commands = coverage erase

[testenv]
commands =
pytest --timeout=30 --cov=zwave_js_server --cov-report=xml {posargs}
pytest --timeout=30 --cov=zwave_js_server --cov-report=xml --cov-append {posargs}
deps =
-rrequirements.txt
-rrequirements_test.txt

[testenv:test_orjson]
commands =
pytest --timeout=30 --cov=zwave_js_server --cov-report=xml --cov-append {posargs}
deps =
-rrequirements.txt
-rrequirements_extra.txt
-rrequirements_test.txt

[testenv:lint]
Expand Down
14 changes: 11 additions & 3 deletions zwave_js_server/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from collections.abc import Callable
from copy import deepcopy
from datetime import datetime
import functools
import logging
from operator import itemgetter
import pprint
Expand Down Expand Up @@ -39,6 +40,11 @@
from .model.log_message import LogMessage
from .model.version import VersionInfo, VersionInfoDataType

try:
import orjson as json
except ImportError:
import json

SIZE_PARSE_JSON_EXECUTOR = 8192

# Message IDs
Expand Down Expand Up @@ -458,9 +464,11 @@ async def _receive_json_or_raise(self) -> dict:

try:
if len(msg.data) > SIZE_PARSE_JSON_EXECUTOR:
data: dict = await self._loop.run_in_executor(None, msg.json)
data: dict = await self._loop.run_in_executor(
None, functools.partial(msg.json, loads=json.loads)
)
else:
data = msg.json()
data = msg.json(loads=json.loads)
except ValueError as err:
raise InvalidMessage("Received invalid JSON.") from err

Expand Down Expand Up @@ -557,7 +565,7 @@ async def _send_json_message(self, message: dict[str, Any]) -> None:
}
)

await self._client.send_json(message)
await self._client.send_json(message, dumps=json.dumps)

async def __aenter__(self) -> Client:
"""Connect to the websocket."""
Expand Down

0 comments on commit 392543e

Please sign in to comment.