Source code for searx.search

# SPDX-License-Identifier: AGPL-3.0-or-later
# lint: pylint
# pylint: disable=missing-module-docstring, too-few-public-methods

import threading
from copy import copy
from timeit import default_timer
from uuid import uuid4

import flask
from flask import copy_current_request_context
import babel

from searx import settings
from searx.answerers import ask
from searx.external_bang import get_bang_url
from searx.results import ResultContainer
from searx import logger
from searx.plugins import plugins
from searx.search.models import EngineRef, SearchQuery
from searx.engines import load_engines
from searx.network import initialize as initialize_network, check_network_configuration
from searx.metrics import initialize as initialize_metrics, counter_inc, histogram_observe_time
from searx.search.processors import PROCESSORS, initialize as initialize_processors
from searx.search.checker import initialize as initialize_checker


logger = logger.getChild('search')


def initialize(settings_engines=None, enable_checker=False, check_network=False, enable_metrics=True):
    settings_engines = settings_engines or settings['engines']
    load_engines(settings_engines)
    initialize_network(settings_engines, settings['outgoing'])
    if check_network:
        check_network_configuration()
    initialize_metrics([engine['name'] for engine in settings_engines], enable_metrics)
    initialize_processors(settings_engines)
    if enable_checker:
        initialize_checker()





[docs]class SearchWithPlugins(Search): """Inherit from the Search class, add calls to the plugins.""" __slots__ = 'ordered_plugin_list', 'request' def __init__(self, search_query: SearchQuery, ordered_plugin_list, request: flask.Request): super().__init__(search_query) self.ordered_plugin_list = ordered_plugin_list self.result_container.on_result = self._on_result # pylint: disable=line-too-long # get the "real" request to use it outside the Flask context. # see # * https://github.com/pallets/flask/blob/d01d26e5210e3ee4cbbdef12f05c886e08e92852/src/flask/globals.py#L55 # * https://github.com/pallets/werkzeug/blob/3c5d3c9bd0d9ce64590f0af8997a38f3823b368d/src/werkzeug/local.py#L548-L559 # * https://werkzeug.palletsprojects.com/en/2.0.x/local/#werkzeug.local.LocalProxy._get_current_object # pylint: enable=line-too-long self.request = request._get_current_object() def _on_result(self, result): return plugins.call(self.ordered_plugin_list, 'on_result', self.request, self, result)
[docs] def search(self) -> ResultContainer: if plugins.call(self.ordered_plugin_list, 'pre_search', self.request, self): super().search() plugins.call(self.ordered_plugin_list, 'post_search', self.request, self) self.result_container.close() return self.result_container