[refactor] typification of SearXNG / EngineResults
In [1] and [2] we discussed the need of a Result.results property and how we can
avoid unclear code. This patch implements a class for the reslut-lists of
engines::
searx.result_types.EngineResults
A simple example for the usage in engine development::
from searx.result_types import EngineResults
...
def response(resp) -> EngineResults:
res = EngineResults()
...
res.add( res.types.Answer(answer="lorem ipsum ..", url="https://example.org") )
...
return res
[1] https://github.com/searxng/searxng/pull/4183#pullrequestreview-257400034
[2] https://github.com/searxng/searxng/pull/4183#issuecomment-2614301580
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
committed by
Markus Heiser
parent
edfbf1e118
commit
36a1ef1239
@@ -9,10 +9,50 @@
|
||||
gradually. For more, please read :ref:`result types`.
|
||||
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ["Result", "AnswerSet", "Answer", "Translations"]
|
||||
__all__ = ["Result", "EngineResults", "AnswerSet", "Answer", "Translations"]
|
||||
|
||||
import abc
|
||||
|
||||
from searx import enginelib
|
||||
|
||||
from ._base import Result, LegacyResult
|
||||
from .answer import AnswerSet, Answer, Translations
|
||||
|
||||
|
||||
class ResultList(list, abc.ABC):
|
||||
"""Base class of all result lists (abstract)."""
|
||||
|
||||
class types: # pylint: disable=invalid-name
|
||||
"""The collection of result types (which have already been implemented)."""
|
||||
|
||||
Answer = Answer
|
||||
Translations = Translations
|
||||
|
||||
def __init__(self):
|
||||
# pylint: disable=useless-parent-delegation
|
||||
super().__init__()
|
||||
|
||||
def add(self, result: Result):
|
||||
"""Add a :py:`Result` item to the result list."""
|
||||
self.append(result)
|
||||
|
||||
|
||||
class EngineResults(ResultList):
|
||||
"""Result list that should be used by engine developers. For convenience,
|
||||
engine developers don't need to import types / see :py:obj:`ResultList.types`.
|
||||
|
||||
.. code:: python
|
||||
|
||||
from searx.result_types import EngineResults
|
||||
...
|
||||
def response(resp) -> EngineResults:
|
||||
res = EngineResults()
|
||||
...
|
||||
res.add( res.types.Answer(answer="lorem ipsum ..", url="https://example.org") )
|
||||
...
|
||||
return res
|
||||
"""
|
||||
|
||||
@@ -53,27 +53,6 @@ class Result(msgspec.Struct, kw_only=True):
|
||||
The field is optional and is initialized from the context if necessary.
|
||||
"""
|
||||
|
||||
results: list = [] # https://jcristharif.com/msgspec/structs.html#default-values
|
||||
"""Result list of an :origin:`engine <searx/engines>` response or a
|
||||
:origin:`answerer <searx/answerers>` to which the answer should be added.
|
||||
|
||||
This field is only present for the sake of simplicity. Typically, the
|
||||
response function of an engine has a result list that is returned at the
|
||||
end. By specifying the result list in the constructor of the result, this
|
||||
result is then immediately added to the list (this parameter does not have
|
||||
another function).
|
||||
|
||||
.. code:: python
|
||||
|
||||
def response(resp):
|
||||
results = []
|
||||
...
|
||||
Answer(results=results, answer=answer, url=url)
|
||||
...
|
||||
return results
|
||||
|
||||
"""
|
||||
|
||||
def normalize_result_fields(self):
|
||||
"""Normalize a result ..
|
||||
|
||||
@@ -92,9 +71,7 @@ class Result(msgspec.Struct, kw_only=True):
|
||||
self.url = self.parsed_url.geturl()
|
||||
|
||||
def __post_init__(self):
|
||||
"""Add *this* result to the result list."""
|
||||
|
||||
self.results.append(self)
|
||||
pass
|
||||
|
||||
def __hash__(self) -> int:
|
||||
"""Generates a hash value that uniquely identifies the content of *this*
|
||||
|
||||
Reference in New Issue
Block a user