[fix] JSON format: serialization of the result-types

The ``JSONEncoder`` (``format="json"``) must perform a conversion to the
built-in types for the ``msgspec.Struct``::

    if isinstance(o, msgspec.Struct):
        return msgspec.to_builtins(o)

The result types are already of type ``msgspec.Struct``, so they can be
converted into built-in types.

The field types (in the result type) that were not yet of type ``msgspec.Struct``
have been converted to::

    searx.weather.GeoLocation@dataclass -> msgspec.Struct
    searx.weather.DateTime              -> msgspec.Struct
    searx.weather.Temperature           -> msgspec.Struct
    searx.weather.PressureUnits         -> msgspec.Struct
    searx.weather.WindSpeed             -> msgspec.Struct
    searx.weather.RelativeHumidity      -> msgspec.Struct
    searx.weather.Compass               -> msgspec.Struct

BTW: Wherever it seemed sensible, the typing was also modernized in the modified
files.

Closes: https://github.com/searxng/searxng/issues/5250
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
Markus Heiser
2025-09-30 14:00:09 +02:00
committed by Markus Heiser
parent 41e0f2abf0
commit e16b6cb148
7 changed files with 141 additions and 126 deletions

View File

@@ -16,6 +16,7 @@ from typing import Iterable, List, Tuple, TYPE_CHECKING
from io import StringIO
from codecs import getincrementalencoder
import msgspec
from flask_babel import gettext, format_date # type: ignore
from searx import logger, get_setting
@@ -147,6 +148,8 @@ def write_csv_response(csv: CSVWriter, rc: "ResultContainer") -> None: # pylint
class JSONEncoder(json.JSONEncoder): # pylint: disable=missing-class-docstring
def default(self, o):
if isinstance(o, msgspec.Struct):
return msgspec.to_builtins(o)
if isinstance(o, datetime):
return o.isoformat()
if isinstance(o, timedelta):