2"""Abstract base classes for engine request processors.
7from abc
import abstractmethod, ABC
8from timeit
import default_timer
9from typing
import Dict, Union
11from searx
import settings, logger
14from searx.metrics import histogram_observe, counter_inc, count_exception, count_error
15from searx.exceptions import SearxEngineAccessDeniedException, SearxEngineResponseException
18logger = logger.getChild(
'searx.search.processor')
19SUSPENDED_STATUS: Dict[Union[int, str],
'SuspendedStatus'] = {}
23 """Class to handle suspend state."""
25 __slots__ =
'suspend_end_time',
'suspend_reason',
'continuous_errors',
'lock'
37 def suspend(self, suspended_time, suspend_reason):
41 if suspended_time
is None:
43 settings[
'search'][
'max_ban_time_on_fail'],
48 logger.debug(
'Suspend for %i seconds', suspended_time)
59 """Base classes used for all types of request processors."""
61 __slots__ =
'engine',
'engine_name',
'lock',
'suspended_status',
'logger'
66 self.
logger = engines[engine_name].logger
74 except SearxEngineResponseException
as exc:
75 self.
logger.warning(
'Fail to initialize // %s', exc)
77 self.
logger.exception(
'Fail to initialize')
79 self.
logger.debug(
'Initialized')
83 return hasattr(self.
engine,
'init')
87 if isinstance(exception_or_message, BaseException):
88 exception_class = exception_or_message.__class__
89 module_name = getattr(exception_class,
'__module__',
'builtins')
90 module_name =
'' if module_name ==
'builtins' else module_name +
'.'
91 error_message = module_name + exception_class.__qualname__
93 error_message = exception_or_message
94 result_container.add_unresponsive_engine(self.
engine_name, error_message)
96 counter_inc(
'engine', self.
engine_name,
'search',
'count',
'error')
97 if isinstance(exception_or_message, BaseException):
98 count_exception(self.
engine_name, exception_or_message)
100 count_error(self.
engine_name, exception_or_message)
103 suspended_time =
None
104 if isinstance(exception_or_message, SearxEngineAccessDeniedException):
105 suspended_time = exception_or_message.suspended_time
110 result_container.extend(self.
engine_name, search_results)
111 engine_time = default_timer() - start_time
112 page_load_time = get_time_for_thread()
113 result_container.add_timing(self.
engine_name, engine_time, page_load_time)
115 counter_inc(
'engine', self.
engine_name,
'search',
'count',
'successful')
116 histogram_observe(engine_time,
'engine', self.
engine_name,
'time',
'total')
117 if page_load_time
is not None:
118 histogram_observe(page_load_time,
'engine', self.
engine_name,
'time',
'http')
121 if getattr(threading.current_thread(),
'_timeout',
False):
126 if search_results
is not None:
132 result_container.add_unresponsive_engine(
139 """Returns a set of (see :ref:`request params <engine request arguments>`) or
140 ``None`` if request is not supported.
142 Not supported conditions (``None`` is returned):
144 - A page-number > 1 when engine does not support paging.
145 - A time range when the engine does not support time range.
148 if search_query.pageno > 1
and not self.
engine.paging:
152 max_page = self.
engine.max_page
or settings[
'search'][
'max_page']
153 if max_page
and max_page < search_query.pageno:
157 if search_query.time_range
and not self.
engine.time_range_support:
161 params[
'category'] = engine_category
162 params[
'pageno'] = search_query.pageno
163 params[
'safesearch'] = search_query.safesearch
164 params[
'time_range'] = search_query.time_range
165 params[
'engine_data'] = search_query.engine_data.get(self.
engine_name, {})
166 params[
'searxng_locale'] = search_query.lang
175 if hasattr(self.
engine,
'language')
and self.
engine.language:
176 params[
'language'] = self.
engine.language
178 params[
'language'] = search_query.lang
183 def search(self, query, params, result_container, start_time, timeout_limit):
187 tests = getattr(self.engine,
'tests',
None)
189 tests = getattr(self.engine,
'additional_tests', {})
190 tests.update(self.get_default_tests())
__init__(self, engine, str engine_name)
handle_exception(self, result_container, exception_or_message, suspend=False)
extend_container_if_suspended(self, result_container)
has_initialize_function(self)
_extend_container_basic(self, result_container, start_time, search_results)
get_params(self, search_query, engine_category)
extend_container(self, result_container, start_time, search_results)
suspend(self, suspended_time, suspend_reason)