summaryrefslogtreecommitdiff
path: root/searx/enginelib
diff options
context:
space:
mode:
authorMarkus Heiser <markus.heiser@darmarit.de>2026-06-14 15:16:26 +0200
committerMarkus Heiser <markus.heiser@darmarIT.de>2026-06-15 10:52:00 +0200
commit6c9dcd42420cee087ad7fe3d686dfc2b632ebbee (patch)
tree27031bc2bbb57a2eb9596bb6d5f588bd9a2db0e3 /searx/enginelib
parentb3e08f2a44640ffc45d5955f5ff43b4a4d555578 (diff)
[chore] complete and normalize the attributes of engine objects (#6258)
Drop outdated engine attributes: supported_languages, language_aliases Complete, normalize and document the type definitions for the engine-module and engine-class. For the ``engine.about`` section of the configuration, a type check is performed based on structure ``searx.enginelib.EngineAbout``. The property ``engine.about.language`` no longer exists; existing values have been migrated to ``engine.language``. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Diffstat (limited to 'searx/enginelib')
-rw-r--r--searx/enginelib/__init__.py123
-rw-r--r--searx/enginelib/traits.py29
2 files changed, 84 insertions, 68 deletions
diff --git a/searx/enginelib/__init__.py b/searx/enginelib/__init__.py
index 5e8d738a9..0af69190d 100644
--- a/searx/enginelib/__init__.py
+++ b/searx/enginelib/__init__.py
@@ -41,7 +41,7 @@ if t.TYPE_CHECKING:
from searx.enginelib.traits import EngineTraits
from searx.extended_types import SXNG_Response
from searx.result_types import EngineResults
- from searx.search.processors import OfflineParamTypes, OnlineParamTypes
+ from searx.search.processors import OfflineParamTypes, OnlineParamTypes, ProcessorType
ENGINES_CACHE: ExpireCacheSQLite = ExpireCacheSQLite.build_cache(
ExpireCacheCfg(
@@ -180,7 +180,7 @@ class EngineCache:
return ENGINES_CACHE.secret_hash(name=name)
-class EngineAbout(msgspec.Struct):
+class EngineAbout(msgspec.Struct, kw_only=True):
"""Additional fields describing the engine.
.. code:: yaml
@@ -213,12 +213,11 @@ class EngineAbout(msgspec.Struct):
results: str = ""
"""Data format of the source (online-engines: of the response)."""
- language: str = ""
- """If the engine supports only one language, this language is specified
- here (``en``, ``de``, ``"no"`` or ..); otherwise, the value remains empty.
+ description: str = ""
+ """Brief description of the engine and where it gets its data from.
- For the YAML configuration: think of the `YAML-Norway problem
- <https://ruuda.nl/2023/the-yaml-document-from-hell#the-norway-problem>`_
+ This value should only be set as long as no description of the data source
+ is available via a :py:obj:`EngineAbout.wikidata_id`.
"""
@@ -227,6 +226,8 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
Further documentation see :ref:`general engine configuration`.
+ The defaults are taken from :py:obj:`searx.engines.ENGINE_DEFAULT_ARGS`.
+
.. hint::
This class is currently never initialized and only used for type hinting.
@@ -234,49 +235,27 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
logger: logging.Logger
- # Common options in the engine module
+ # Common options of the engine module
- engine_type: str
+ engine_type: "ProcessorType" = "online"
"""Type of the engine (:ref:`searx.search.processors`)"""
- paging: bool
+ paging: bool = False
"""Engine supports multiple pages."""
max_page: int = 0
"""If the engine supports paging, then this is the value for the last page
that is still supported. ``0`` means unlimited numbers of pages."""
- time_range_support: bool
+ time_range_support: bool = False
"""Engine supports search time range."""
- safesearch: bool
+ safesearch: bool = False
"""Engine supports SafeSearch"""
- language_support: bool
+ language_support: bool = False
"""Engine supports languages (locales) search."""
- language: str
- """For an engine, when there is ``language: ...`` in the YAML settings the engine
- does support only this one language:
-
- .. code:: yaml
-
- - name: google french
- engine: google
- language: fr
- """
-
- region: str
- """For an engine, when there is ``region: ...`` in the YAML settings the engine
- does support only this one region::
-
- .. code:: yaml
-
- - name: google belgium
- engine: google
- region: fr-BE
- """
-
fetch_traits: "Callable[[EngineTraits, bool], None]"
"""Function to to fetch engine's traits from origin."""
@@ -285,9 +264,6 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
# settings.yml
- categories: list[str]
- """Specifies to which :ref:`engine categories` the engine should be added."""
-
name: str
"""Name that will be used across SearXNG to define this engine. In settings, on
the result page .."""
@@ -297,6 +273,43 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
this search engine (file name from :origin:`searx/engines` without
``.py``)."""
+ categories: list[str] = ["general"]
+ """Specifies to which :ref:`engine categories` the engine should be added."""
+
+ language: str = ""
+ """If the engine supports only one language, this language is specified here
+ (``en``, ``de``, ``"no"`` or ..); otherwise, the value remains empty. For
+ the YAML configuration: think of the `YAML-Norway problem
+ <https://ruuda.nl/2023/the-yaml-document-from-hell#the-norway-problem>`_
+
+ .. code:: yaml
+
+ - name: google norway
+ engine: google
+ language: "no"
+
+ Depending on ``language_support``, this value has similar but also slightly
+ different meanings.
+
+ - When ``language_support`` is **true**, the map of
+ :py:obj:`traits.EngineTraits.languages` is reduced to the selected
+ language
+
+ - When ``language_support`` is **false**, then the implementation of the
+ engine only supports this one ``language``
+ """
+
+ region: str = ""
+ """For an engine, when there is ``region: ...`` in the YAML settings the engine
+ does support only this one region::
+
+ .. code:: yaml
+
+ - name: google belgium
+ engine: google
+ region: fr-BE
+ """
+
enable_http: bool
"""Enable HTTP (by default only HTTPS is enabled)."""
@@ -309,41 +322,41 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
display_error_messages: bool
"""Display error messages on the web UI."""
- proxies: dict[str, dict[str, str]]
- """Set proxies for a specific engine (YAML):
-
- .. code:: yaml
-
- proxies :
- http: socks5://proxy:port
- https: socks5://proxy:port
- """
-
- disabled: bool
+ disabled: bool = False
"""To disable by default the engine, but not deleting it. It will allow the
user to manually activate it in the settings."""
- inactive: bool
+ inactive: bool = False
"""Remove the engine from the settings (*disabled & removed*)."""
- about: EngineAbout
+ about: EngineAbout = EngineAbout()
"""Additional fields describing the engine."""
- using_tor_proxy: bool
+ using_tor_proxy: bool = False
"""Using tor proxy (``true``) or not (``false``) for this engine."""
- send_accept_language_header: bool
+ send_accept_language_header: bool = True
"""When this option is activated (default), the language (locale) that is
selected by the user is used to build and send a ``Accept-Language`` header
in the request to the origin search engine."""
- tokens: list[str]
+ tokens: list[str] = []
"""A list of secret tokens to make this engine *private*, more details see
:ref:`private engines`."""
- weight: int
+ weight: float = 1.0
"""Weighting of the results of this engine (:ref:`weight <settings engines>`)."""
+ proxies: dict[str, dict[str, str]]
+ """Set proxies for a specific engine (YAML):
+
+ .. code:: yaml
+
+ proxies :
+ http: socks5://proxy:port
+ https: socks5://proxy:port
+ """
+
def setup(self, engine_settings: dict[str, t.Any]) -> bool: # pylint: disable=unused-argument
"""Dynamic setup of the engine settings.
diff --git a/searx/enginelib/traits.py b/searx/enginelib/traits.py
index 4a051ac05..d4d45ac19 100644
--- a/searx/enginelib/traits.py
+++ b/searx/enginelib/traits.py
@@ -142,11 +142,11 @@ class EngineTraits:
"""
if self.data_type == "traits_v1":
- self._set_traits_v1(engine)
+ self._set_traits_v1(engine) # pyright: ignore[reportArgumentType]
else:
raise TypeError("engine traits of type %s is unknown" % self.data_type)
- def _set_traits_v1(self, engine: "Engine | types.ModuleType") -> None:
+ def _set_traits_v1(self, engine: "Engine") -> None:
# For an engine, when there is `language: ...` in the YAML settings the engine
# does support only this one language (region)::
#
@@ -159,22 +159,25 @@ class EngineTraits:
_msg = "settings.yml - engine: '%s' / %s: '%s' not supported"
- languages = traits.languages
- if hasattr(engine, "language"):
- if engine.language not in languages:
- raise ValueError(_msg % (engine.name, "language", engine.language))
- traits.languages = {engine.language: languages[engine.language]}
-
- regions = traits.regions
- if hasattr(engine, "region"):
- if engine.region not in regions:
+ if engine.language:
+ if engine.language_support:
+ if not len(traits.languages) > 1:
+ raise ValueError(
+ f"engine {engine.name}: activated language_support with just one or less languages"
+ )
+ if engine.language not in traits.languages:
+ raise ValueError(_msg % (engine.name, "language", engine.language))
+ traits.languages = {engine.language: traits.languages[engine.language]}
+
+ if engine.region:
+ if engine.region not in traits.regions:
raise ValueError(_msg % (engine.name, "region", engine.region))
- traits.regions = {engine.region: regions[engine.region]}
+ traits.regions = {engine.region: traits.regions[engine.region]}
engine.language_support = bool(traits.languages or traits.regions)
# set the copied & modified traits in engine's namespace
- engine.traits = traits # pyright: ignore[reportAttributeAccessIssue]
+ engine.traits = traits
class EngineTraitsMap(dict[str, EngineTraits]):