perf: optional orjson JSON codec behind ENABLE_ORJSON (#27583)

Swap the JSON encoder/decoder used across the backend from stdlib json to
orjson when ENABLE_ORJSON is set — HTTP request bodies, JSONResponse
bodies, upstream provider responses, SSE chunks, and socket.io/Redis
payloads.

The flag defaults to off, in which case the app uses stdlib json and
engineio's codec verbatim, so default behaviour is unchanged.

- json_codec exports JSONCodec (stdlib json or the orjson codec) and
  SOCKETIO_JSON (engineio's codec or the orjson codec); call sites import
  JSONCodec and stay implementation-agnostic
- apply_orjson_http_json() is a no-op when the flag is off, leaving
  starlette's Request.json / JSONResponse.render untouched
- the orjson codec falls back to the stdlib for inputs orjson rejects
  (non-str dict keys, ints beyond 64 bits, NaN literals)
- orjson is imported only when the flag is on
- FastAPI(default_response_class=...) is deliberately not used: an
  explicit default disables the Pydantic direct-to-bytes fast path for
  response_model routes
This commit is contained in:
Classic298
2026-07-27 03:45:37 -04:00
committed by GitHub
parent 602004dd5f
commit 72fdf238a8
13 changed files with 176 additions and 51 deletions
+3 -2
View File
@@ -2,6 +2,7 @@ import json
from numbers import Number
from uuid import uuid4
from open_webui.utils.json_codec import JSONCodec
from open_webui.utils.misc import (
openai_chat_chunk_message_template,
openai_chat_completion_message_template,
@@ -237,7 +238,7 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response)
completion_id = f'chatcmpl-{str(uuid4())}'
first = True
async for data in ollama_streaming_response.body_iterator:
data = json.loads(data)
data = JSONCodec.loads(data)
model = data.get('model', 'ollama')
message = data.get('message') or {}
@@ -268,7 +269,7 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response)
if done and has_tool_calls:
data['choices'][0]['finish_reason'] = 'tool_calls'
line = f'data: {json.dumps(data)}\n\n'
line = f'data: {JSONCodec.dumps(data)}\n\n'
yield line
yield 'data: [DONE]\n\n'