Coverage for open_webui/utils/json_response.py: 34%
25 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 05:07 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 05:07 +0000
1"""orjson-backed JSON parsing/rendering for starlette/FastAPI requests and responses."""
3from __future__ import annotations
5import json
6from typing import Any
8from starlette.requests import Request
9from starlette.responses import JSONResponse
11from open_webui.env import ENABLE_ORJSON
14def apply_orjson_http_json() -> None:
15 """Parse request bodies and serialize ``JSONResponse`` with orjson.
17 A no-op unless ``ENABLE_ORJSON`` is set, leaving starlette's own
18 stdlib-``json`` implementations untouched.
20 Not ``FastAPI(default_response_class=...)`` on purpose: an explicit
21 default disables FastAPI's Pydantic direct-to-bytes fast path for
22 ``response_model`` routes. NaN/Infinity floats serialize as ``null``
23 instead of raising.
24 """
25 if not ENABLE_ORJSON: 25 ↛ 28line 25 didn't jump to line 28 because the condition on line 25 was always true
26 return
28 import orjson
30 def render(self, content: Any) -> bytes:
31 try:
32 return orjson.dumps(content)
33 except (TypeError, ValueError):
34 # Fallback matches starlette's JSONResponse.render exactly.
35 return json.dumps(
36 content,
37 ensure_ascii=False,
38 allow_nan=False,
39 indent=None,
40 separators=(',', ':'),
41 ).encode('utf-8')
43 async def request_json(self) -> Any:
44 if not hasattr(self, '_json'):
45 body = await self.body()
46 try:
47 self._json = orjson.loads(body)
48 except (TypeError, ValueError):
49 # Fallback matches starlette's Request.json exactly, including the
50 # json.JSONDecodeError that FastAPI turns into a 422.
51 self._json = json.loads(body)
52 return self._json
54 JSONResponse.render = render
55 Request.json = request_json