diff --git a/requirements.txt b/requirements.txt index 7b90ffe3f..94578abbf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,6 @@ redis==5.0.8 markdown-it-py==3.0.0 fasttext-predict==0.9.2.2 tomli==2.0.2; python_version < '3.11' -pydantic==2.9.2 +msgspec==0.18.6 eval_type_backport; python_version < '3.9' typer-slim==0.12.5 diff --git a/searx/favicons/cache.py b/searx/favicons/cache.py index 4b8276154..c46eb5621 100644 --- a/searx/favicons/cache.py +++ b/searx/favicons/cache.py @@ -30,7 +30,7 @@ import tempfile import time import typer -from pydantic import BaseModel +import msgspec from searx import sqlitedb from searx import logger @@ -90,7 +90,7 @@ def init(cfg: "FaviconCacheConfig"): raise NotImplementedError(f"favicons db_type '{cfg.db_type}' is unknown") -class FaviconCacheConfig(BaseModel): +class FaviconCacheConfig(msgspec.Struct): # pylint: disable=too-few-public-methods """Configuration of the favicon cache.""" db_type: Literal["sqlite", "mem"] = "sqlite" diff --git a/searx/favicons/config.py b/searx/favicons/config.py index e244de52b..bf53b0821 100644 --- a/searx/favicons/config.py +++ b/searx/favicons/config.py @@ -4,9 +4,8 @@ from __future__ import annotations import pathlib -from pydantic import BaseModel +import msgspec -from searx.compat import tomllib from .cache import FaviconCacheConfig from .proxy import FaviconProxyConfig @@ -19,7 +18,7 @@ TOML_CACHE_CFG: dict[str, "FaviconConfig"] = {} DEFAULT_CFG_TOML_PATH = pathlib.Path(__file__).parent / "favicons.toml" -class FaviconConfig(BaseModel): +class FaviconConfig(msgspec.Struct): # pylint: disable=too-few-public-methods """The class aggregates configurations of the favicon tools""" cfg_schema: int @@ -28,10 +27,10 @@ class FaviconConfig(BaseModel): By specifying a version, it is possible to ensure downward compatibility in the event of future changes to the configuration schema""" - cache: FaviconCacheConfig = FaviconCacheConfig() + cache: FaviconCacheConfig = FaviconCacheConfig """Setup of the :py:obj:`.cache.FaviconCacheConfig`.""" - proxy: FaviconProxyConfig = FaviconProxyConfig() + proxy: FaviconProxyConfig = FaviconCacheConfig """Setup of the :py:obj:`.proxy.FaviconProxyConfig`.""" @classmethod @@ -45,18 +44,22 @@ class FaviconConfig(BaseModel): return cached with cfg_file.open("rb") as f: + data = f.read() - cfg = tomllib.load(f) - cfg = cfg.get("favicons", cfg) + cfg = msgspec.toml.decode(data, type=_FaviconConfig) + schema = cfg.favicons.cfg_schema + if schema != CONFIG_SCHEMA: + raise ValueError( + f"config schema version {CONFIG_SCHEMA} is needed, version {schema} is given in {cfg_file}" + ) - schema = cfg.get("cfg_schema") - if schema != CONFIG_SCHEMA: - raise ValueError( - f"config schema version {CONFIG_SCHEMA} is needed, version {schema} is given in {cfg_file}" - ) + cfg = cfg.favicons + if use_cache and cached: + TOML_CACHE_CFG[str(cfg_file.resolve())] = cfg - cfg = cls(**cfg) - if use_cache and cached: - TOML_CACHE_CFG[str(cfg_file.resolve())] = cfg + return cfg - return cfg + +class _FaviconConfig(msgspec.Struct): # pylint: disable=too-few-public-methods + # wrapper struct for root object "favicons." + favicons: FaviconConfig diff --git a/searx/favicons/proxy.py b/searx/favicons/proxy.py index 8cefe6c59..924092c80 100644 --- a/searx/favicons/proxy.py +++ b/searx/favicons/proxy.py @@ -12,7 +12,7 @@ import urllib.parse import flask from httpx import HTTPError -from pydantic import BaseModel +import msgspec from searx import get_setting @@ -41,7 +41,7 @@ def _initial_resolver_map(): return d -class FaviconProxyConfig(BaseModel): +class FaviconProxyConfig(msgspec.Struct): """Configuration of the favicon proxy.""" max_age: int = 60 * 60 * 24 * 7 # seven days @@ -59,7 +59,7 @@ class FaviconProxyConfig(BaseModel): outgoing request of the resolver. By default, the value from :ref:`outgoing.request_timeout ` setting is used.""" - resolver_map: dict[str, str] = _initial_resolver_map() + resolver_map: dict[str, str] = msgspec.field(default_factory=_initial_resolver_map) """The resolver_map is a key / value dictionary where the key is the name of the resolver and the value is the fully qualifying name (fqn) of resolver's function (the callable). The resolvers from the python module