Skip to content

Commit 65cf541

Browse files
authored
Use orjson (#1194)
1 parent 6e8c81f commit 65cf541

File tree

11 files changed

+63
-24
lines changed

11 files changed

+63
-24
lines changed

deebot_client/commands/json/common.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
from abc import ABC, abstractmethod
66
from datetime import UTC, datetime
7-
import json
87
from types import MappingProxyType
98
from typing import TYPE_CHECKING, Any
109

10+
import orjson
11+
1112
from deebot_client.command import (
1213
Command,
1314
CommandMqttP2P,
@@ -85,15 +86,15 @@ class JsonCommandMqttP2P(JsonCommand, CommandMqttP2P, ABC):
8586
@classmethod
8687
def create_from_mqtt(cls, payload: str | bytes | bytearray) -> CommandMqttP2P:
8788
"""Create a command from the mqtt data."""
88-
payload_json = json.loads(payload)
89+
payload_json = orjson.loads(payload)
8990
data = payload_json["body"]["data"]
9091
return cls._create_from_mqtt(data)
9192

9293
def handle_mqtt_p2p(
9394
self, event_bus: EventBus, response_payload: str | bytes | bytearray
9495
) -> None:
9596
"""Handle response received over the mqtt channel "p2p"."""
96-
response = json.loads(response_payload)
97+
response = orjson.loads(response_payload)
9798
self._handle_mqtt_p2p(event_bus, response)
9899

99100
@abstractmethod

deebot_client/commands/json/map/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
from __future__ import annotations
44

5-
import json
65
from types import MappingProxyType
76
from typing import TYPE_CHECKING, Any
87

8+
import orjson
9+
910
from deebot_client.commands.json.common import JsonCommandWithMessageHandling
1011
from deebot_client.events import (
1112
MapSetEvent,
@@ -233,7 +234,7 @@ def _handle_subsets(
233234
:return: A message response
234235
"""
235236
# subset is based64 7z compressed
236-
subsets = json.loads(decompress_base64_data(data["subsets"]).decode())
237+
subsets = orjson.loads(decompress_base64_data(data["subsets"]).decode())
237238

238239
match map_type := data["type"]:
239240
case MapSetType.ROOMS:

deebot_client/message.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
from dataclasses import dataclass, field
77
from enum import IntEnum, auto
88
import functools
9-
import json
109
from typing import TYPE_CHECKING, Any, final
1110

11+
import orjson
12+
1213
from deebot_client.events import FirmwareEvent
1314
from deebot_client.util import verify_required_class_variables_exists
1415

@@ -185,7 +186,7 @@ def _handle(
185186
data = message
186187
if not isinstance(message, dict):
187188
try:
188-
data = json.loads(message)
189+
data = orjson.loads(message)
189190
except Exception:
190191
_LOGGER.debug(
191192
"Could not decode message %s payload %s as JSON",

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ dependencies = [
3030
"aiomqtt>=2.0.0,<3.0",
3131
"cachetools>=5.0.0,<7.0",
3232
"defusedxml>=0.7.1",
33+
"orjson>=3.11.3",
3334
]
3435
version = "0.0.0"
3536

@@ -149,7 +150,7 @@ required-imports = ["from __future__ import annotations"]
149150
]
150151

151152
[tool.ruff.lint.flake8-tidy-imports.banned-api]
152-
"svg.Path".msg = "Use map.Path instead"
153+
"json".msg = "Use orjson instead"
153154

154155

155156
[tool.ruff.lint.mccabe]

scripts/check_for_similar_models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
from __future__ import annotations
44

55
import asyncio
6-
import json
76
import logging
87
import os
98
from pathlib import Path
109
import time
1110

1211
import aiohttp
12+
import orjson
1313

1414
from deebot_client.api_client import ApiClient
1515
from deebot_client.authentication import Authenticator, create_rest_config
@@ -22,7 +22,7 @@ def _save_file(name: str, data: dict[str, list[str]]) -> None:
2222
path = Path("similarity_output")
2323
path.mkdir(exist_ok=True)
2424
with path.joinpath(name).open("w") as f:
25-
f.write(json.dumps(data, indent=4))
25+
f.write(orjson.dumps(data, option=orjson.OPT_INDENT_2).decode("utf-8"))
2626

2727

2828
def _add_models_by_similarity(models: list[str]) -> None:

tests/commands/json/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from __future__ import annotations
22

33
from collections.abc import Sequence
4-
import json
54
from typing import TYPE_CHECKING, Any
65
from unittest.mock import Mock, call
76

7+
import orjson
88
from testfixtures import LogCapture
99

1010
from deebot_client.event_bus import EventBus
@@ -94,13 +94,13 @@ async def assert_set_command(
9494
"msg": "fail",
9595
}
9696
)
97-
command.handle_mqtt_p2p(event_bus, json.dumps(json_data))
97+
command.handle_mqtt_p2p(event_bus, orjson.dumps(json_data))
9898
event_bus.notify.assert_called_once_with(firmware_event)
9999

100100
event_bus.reset_mock()
101101
# Success
102102
data, firmware_event = get_message_json(get_success_body())
103-
command.handle_mqtt_p2p(event_bus, json.dumps(data))
103+
command.handle_mqtt_p2p(event_bus, orjson.dumps(data))
104104
if not isinstance(expected_get_command_events, Sequence):
105105
expected_events = [firmware_event, expected_get_command_events]
106106
else:
@@ -109,7 +109,7 @@ async def assert_set_command(
109109
event_bus.notify.assert_has_calls([call(x) for x in expected_events])
110110
assert event_bus.notify.call_count == len(expected_events)
111111

112-
payload = json.dumps({"body": {"data": args}})
112+
payload = orjson.dumps({"body": {"data": args}})
113113
mqtt_command = command.create_from_mqtt(payload)
114114
assert mqtt_command == command
115115

tests/mqtt_util.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
import asyncio
66
import datetime
7-
import json
87
from typing import TYPE_CHECKING
98
from unittest.mock import MagicMock, Mock
109

10+
import orjson
11+
1112
from deebot_client.event_bus import EventBus
1213
from deebot_client.mqtt_client import MqttClient, SubscriberInfo
1314

@@ -27,9 +28,7 @@ async def verify_subscribe(
2728
expected_called: bool,
2829
) -> None:
2930
command = "test"
30-
data = json.dumps({"test": str(datetime.datetime.now(tz=datetime.UTC))}).encode(
31-
"utf-8"
32-
)
31+
data = orjson.dumps({"test": str(datetime.datetime.now(tz=datetime.UTC))})
3332
api = device_info.api
3433
topic = f"iot/atr/{command}/{api['did']}/{api['class']}/{api['resource']}/j"
3534
await test_client.publish(topic, data)

tests/test_command.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from __future__ import annotations
22

3-
import json
43
import logging
54
from types import MappingProxyType
65
from typing import TYPE_CHECKING, Any
76

87
from aiohttp import ClientTimeout
8+
import orjson
99
import pytest
1010

1111
from deebot_client.command import Command, InitParam
@@ -80,7 +80,7 @@ def test_CommandMqttP2P_create_from_mqtt_error(
8080
data: dict[str, str], expected: str
8181
) -> None:
8282
with pytest.raises(DeebotError, match=expected):
83-
_TestCommand.create_from_mqtt(json.dumps({"body": {"data": data}}))
83+
_TestCommand.create_from_mqtt(orjson.dumps({"body": {"data": data}}))
8484

8585

8686
def test_CommandMqttP2P_create_from_mqtt_additional_fields(

tests/test_device.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import asyncio
44
from collections.abc import Callable
5-
import json
65
from typing import TYPE_CHECKING
76
from unittest.mock import Mock, patch
87

8+
import orjson
99
import pytest
1010

1111
from deebot_client.command import Command, DeviceCommandResult
@@ -46,7 +46,7 @@ def json_battery_message_payload(expected_version: str | None = "1.8.2") -> str:
4646
"header": header,
4747
"body": {"data": {"value": 100, "isLow": 0}},
4848
}
49-
return json.dumps(data)
49+
return orjson.dumps(data).decode("utf-8")
5050

5151

5252
def xml_battery_message_payload() -> str:

tests/test_mqtt_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
import asyncio
44
import datetime
5-
import json
65
import logging
76
import ssl
87
from typing import TYPE_CHECKING, Any
98
from unittest.mock import DEFAULT, MagicMock, Mock, patch
109

1110
from aiomqtt import Client, Message, MqttError as AioMqttError
1211
from cachetools import TTLCache
12+
import orjson
1313
import pytest
1414

1515
from deebot_client.commands.json.battery import GetBattery
@@ -97,7 +97,7 @@ async def _publish_p2p(
9797
*,
9898
is_request: bool,
9999
) -> bytes:
100-
data_bytes = json.dumps(data).encode("utf-8")
100+
data_bytes = orjson.dumps(data)
101101
if is_request:
102102
topic = f"iot/p2p/{command_name}/test/test/test/{device_info['did']}/{device_info['class']}/{device_info['resource']}/q/{request_id}/{data_type}"
103103
else:

0 commit comments

Comments
 (0)