mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 07:03:53 +08:00
67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from fastapi import Request
|
|
from starlette.responses import JSONResponse, Response
|
|
|
|
from app.core.i18n import message_for
|
|
from app.core.serialization import java_compatible
|
|
|
|
|
|
class JavaJSONResponse(JSONResponse):
|
|
def render(self, content: Any) -> bytes:
|
|
return json.dumps(
|
|
java_compatible(content),
|
|
ensure_ascii=False,
|
|
allow_nan=False,
|
|
separators=(",", ":"),
|
|
).encode("utf-8")
|
|
|
|
|
|
def envelope(data: Any = None, *, code: int = 0, msg: str = "success") -> dict[str, Any]:
|
|
return {"code": code, "msg": msg, "data": data}
|
|
|
|
|
|
def ok(data: Any = None) -> JavaJSONResponse:
|
|
return JavaJSONResponse(envelope(data))
|
|
|
|
|
|
def error_response(
|
|
request: Request,
|
|
code: int,
|
|
message: str | None = None,
|
|
*,
|
|
status_code: int = 200,
|
|
params: tuple[object, ...] = (),
|
|
media_type: str = "application/json",
|
|
) -> JavaJSONResponse:
|
|
translated = message or message_for(code, request.headers.get("Accept-Language"), *params)
|
|
return JavaJSONResponse(
|
|
envelope(None, code=code, msg=translated),
|
|
status_code=status_code,
|
|
media_type=media_type,
|
|
)
|
|
|
|
|
|
def raw_json(content: Any, *, exclude_none: bool = False, status_code: int = 200) -> Response:
|
|
normalized = java_compatible(content)
|
|
if exclude_none:
|
|
normalized = _drop_none(normalized)
|
|
body = json.dumps(normalized, ensure_ascii=False, allow_nan=False, separators=(",", ":")).encode("utf-8")
|
|
return Response(
|
|
body,
|
|
status_code=status_code,
|
|
media_type="application/json",
|
|
headers={"Content-Length": str(len(body))},
|
|
)
|
|
|
|
|
|
def _drop_none(value: Any) -> Any:
|
|
if isinstance(value, dict):
|
|
return {key: _drop_none(item) for key, item in value.items() if item is not None}
|
|
if isinstance(value, list):
|
|
return [_drop_none(item) for item in value]
|
|
return value
|