# SPDX-License-Identifier: AGPL-3.0-or-later """Abstract base classes for all engine processors.""" import typing as t import logging import threading from abc import abstractmethod, ABC from timeit import default_timer from searx import get_setting from searx import logger from searx.engines import engines from searx.network import get_time_for_thread, get_network from searx.metrics import histogram_observe, counter_inc, count_exception, count_error from searx.exceptions import SearxEngineAccessDeniedException from searx.utils import get_engine_from_settings if t.TYPE_CHECKING: import types from searx.enginelib import Engine from searx.search.models import SearchQuery from searx.results import ResultContainer from searx.result_types import Result, LegacyResult # pyright: ignore[reportPrivateLocalImportUsage] logger = logger.getChild("searx.search.processor") SUSPENDED_STATUS: dict[int | str, "SuspendedStatus"] = {} class RequestParams(t.TypedDict): """Basic quantity of the Request parameters of all engine types.""" query: str """Search term, stripped of search syntax arguments.""" category: str """Current category, like ``general``. .. hint:: This field is deprecated, don't use it in further implementations. This field is currently *arbitrarily* filled with the name of "one"" category (the name of the first category of the engine). In practice, however, it is not clear what this "one" category should be; in principle, multiple categories can also be activated in a search. """ pageno: int """Current page number, where the first page is ``1``.""" safesearch: t.Literal[0, 1, 2] """Safe-Search filter (0:normal, 1:moderate, 2:strict).""" time_range: t.Literal["day", "week", "month", "year"] | None """Time-range filter.""" engine_data: dict[str, str] """Allows the transfer of (engine specific) data to the next request of the client. In the case of the ``online`` engines, this data is delivered to the client via the HTML ``