[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
+7 -5
View File
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""wttr.in (weather forecast service)"""
import typing as t
from urllib.parse import quote
from datetime import datetime
@@ -80,19 +82,19 @@ def request(query, params):
return params
def _weather_data(location: weather.GeoLocation, data: dict):
def _weather_data(location: weather.GeoLocation, data: dict[str, t.Any]):
# the naming between different data objects is inconsitent, thus temp_C and
# tempC are possible
tempC: float = data.get("temp_C") or data.get("tempC") # type: ignore
return WeatherAnswer.Item(
location=location,
temperature=weather.Temperature(unit="°C", value=tempC),
temperature=weather.Temperature(val=tempC, unit="°C"),
condition=WWO_TO_CONDITION[data["weatherCode"]],
feels_like=weather.Temperature(unit="°C", value=data["FeelsLikeC"]),
feels_like=weather.Temperature(val=data["FeelsLikeC"], unit="°C"),
wind_from=weather.Compass(int(data["winddirDegree"])),
wind_speed=weather.WindSpeed(data["windspeedKmph"], unit="km/h"),
pressure=weather.Pressure(data["pressure"], unit="hPa"),
wind_speed=weather.WindSpeed(val=data["windspeedKmph"], unit="km/h"),
pressure=weather.Pressure(val=data["pressure"], unit="hPa"),
humidity=weather.RelativeHumidity(data["humidity"]),
cloud_cover=data["cloudcover"],
)