Coverage for qreward / utils / patch.py: 100.00%
42 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-23 19:32 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-23 19:32 +0000
1import os
3import httpx
5# 可以通过环境变量控制
6_default_json_lib = os.getenv(
7 key="JSON_LIB",
8 default=None,
9)
12def patch_httpx(json_lib_name: str = _default_json_lib): # type: ignore
13 _use_ujson = False
14 _use_orjson = False
16 from httpx._content import Any, ByteStream, json_dumps
17 from httpx._models import typing, jsonlib
19 if json_lib_name == "ujson":
20 try:
21 import ujson
23 _use_ujson = True
24 except ImportError:
25 pass
26 elif json_lib_name == "orjson":
27 try:
28 import orjson
30 _use_orjson = True
31 except ImportError:
32 pass
34 def encode_json(json: Any) -> tuple[dict[str, str], ByteStream]:
35 if _use_orjson:
36 body = orjson.dumps(json)
37 elif _use_ujson:
38 body = ujson.dumps(
39 json,
40 ensure_ascii=False,
41 separators=(",", ":"),
42 allow_nan=False,
43 )
44 else:
45 body = json_dumps(
46 json,
47 ensure_ascii=False,
48 separators=(",", ":"),
49 allow_nan=False,
50 )
52 if isinstance(body, str):
53 body = body.encode("utf-8")
55 content_length = str(len(body))
56 content_type = "application/json"
57 headers = {
58 "Content-Length": content_length,
59 "Content-Type": content_type,
60 }
61 return headers, ByteStream(body)
63 def decode_json(self, **kwargs: typing.Any) -> typing.Any:
64 if _use_orjson:
65 return orjson.loads(self.content)
66 elif _use_ujson:
67 return ujson.loads(self.content, **kwargs)
68 return jsonlib.loads(self.content, **kwargs)
70 # encode
71 encode_json.__globals__.update(httpx._content.__dict__)
72 encode_json.__module__ = httpx._content.__name__
73 httpx._content.encode_json = encode_json
75 # decode
76 httpx._models.Response.json = decode_json