Skip to content

Commit 03aec46

Browse files
authored
Add support for orjson (#412)
1 parent 519f22f commit 03aec46

5 files changed

Lines changed: 19 additions & 9 deletions

File tree

pyhap/hap_handler.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"""
55
import asyncio
66
from http import HTTPStatus
7-
import json
87
import logging
98
from urllib.parse import parse_qs, urlparse
109
import uuid
@@ -25,7 +24,7 @@
2524
from pyhap.util import long_to_bytes
2625

2726
from .hap_crypto import hap_hkdf, pad_tls_nonce
28-
from .util import to_hap_json
27+
from .util import to_hap_json, from_hap_json
2928

3029
# iOS will terminate the connection if it does not respond within
3130
# 10 seconds, so we only allow 9 seconds to avoid this.
@@ -614,7 +613,7 @@ def handle_set_characteristics(self):
614613
self.send_response(HTTPStatus.UNAUTHORIZED)
615614
return
616615

617-
requested_chars = json.loads(self.request_body.decode("utf-8"))
616+
requested_chars = from_hap_json(self.request_body.decode("utf-8"))
618617
logger.debug(
619618
"%s: Set characteristics content: %s", self.client_address, requested_chars
620619
)
@@ -639,7 +638,7 @@ def handle_prepare(self):
639638
self.send_response(HTTPStatus.UNAUTHORIZED)
640639
return
641640

642-
request = json.loads(self.request_body.decode("utf-8"))
641+
request = from_hap_json(self.request_body.decode("utf-8"))
643642
logger.debug("%s: prepare content: %s", self.client_address, request)
644643

645644
response = self.accessory_handler.prepare(request, self.client_address)
@@ -744,7 +743,7 @@ def _send_tlv_pairing_response(self, data):
744743

745744
def handle_resource(self):
746745
"""Get a snapshot from the camera."""
747-
data = json.loads(self.request_body.decode("utf-8"))
746+
data = from_hap_json(self.request_body.decode("utf-8"))
748747

749748
if self.accessory_handler.accessory.category == CATEGORY_BRIDGE:
750749
accessory = self.accessory_handler.accessory.accessories.get(data["aid"])

pyhap/util.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import asyncio
22
import base64
33
import functools
4-
import json
54
import random
65
import socket
76
from uuid import UUID
87

8+
import orjson
9+
910
from .const import BASE_UUID
1011

1112
ALPHANUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -157,9 +158,16 @@ def hap_type_to_uuid(hap_type):
157158

158159
def to_hap_json(dump_obj):
159160
"""Convert an object to HAP json."""
160-
return json.dumps(dump_obj, separators=(",", ":")).encode("utf-8")
161+
return orjson.dumps(dump_obj) # pylint: disable=no-member
161162

162163

163164
def to_sorted_hap_json(dump_obj):
164165
"""Convert an object to sorted HAP json."""
165-
return json.dumps(dump_obj, sort_keys=True, separators=(",", ":")).encode("utf-8")
166+
return orjson.dumps( # pylint: disable=no-member
167+
dump_obj, option=orjson.OPT_SORT_KEYS # pylint: disable=no-member
168+
)
169+
170+
171+
def from_hap_json(json_str):
172+
"""Convert json to an object."""
173+
return orjson.loads(json_str) # pylint: disable=no-member

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
h11
2+
chacha20poly1305-reuseable
23
cryptography
4+
orjson
35
zeroconf

requirements_all.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
base36
22
cryptography
3+
orjson
34
pyqrcode
45
h11
56
zeroconf

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
README = f.read()
2323

2424

25-
REQUIRES = ["cryptography", "chacha20poly1305-reuseable", "zeroconf>=0.36.2", "h11"]
25+
REQUIRES = ["cryptography", "chacha20poly1305-reuseable", "orjson>=3.7.2", "zeroconf>=0.36.2", "h11"]
2626

2727

2828
setup(

0 commit comments

Comments
 (0)