From fdf562bc32028cc0a2d3da1bad02a84da1e6a1d6 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Mon, 17 Jan 2022 08:06:31 +0100 Subject: [PATCH] [typing] add results.Timing --- searx/results.py | 19 +++++++++++-------- searx/webapp.py | 14 +++++++------- tests/unit/test_webapp.py | 6 +++++- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/searx/results.py b/searx/results.py index 6ab751c5..39e6e95d 100644 --- a/searx/results.py +++ b/searx/results.py @@ -2,7 +2,9 @@ import re from collections import defaultdict from operator import itemgetter from threading import RLock +from typing import List, NamedTuple from urllib.parse import urlparse, unquote + from searx import logger from searx.engines import engines from searx.metrics import histogram_observe, counter_add, count_error @@ -137,6 +139,12 @@ def result_score(result): return sum((occurences * weight) / position for position in result['positions']) +class Timing(NamedTuple): + engine: str + total: float + load: float + + class ResultContainer: """docstring for ResultContainer""" @@ -169,7 +177,7 @@ class ResultContainer: self._closed = False self.paging = False self.unresponsive_engines = set() - self.timings = [] + self.timings: List[Timing] = [] self.redirect_url = None self.on_result = lambda _: True self._lock = RLock() @@ -405,13 +413,8 @@ class ResultContainer: if engines[engine_name].display_error_messages: self.unresponsive_engines.add((engine_name, error_type, error_message, suspended)) - def add_timing(self, engine_name, engine_time, page_load_time): - timing = { - 'engine': engines[engine_name].shortcut, - 'total': engine_time, - 'load': page_load_time, - } - self.timings.append(timing) + def add_timing(self, engine_name: str, engine_time: float, page_load_time: float): + self.timings.append(Timing(engine_name, total=engine_time, load=page_load_time)) def get_timings(self): return self.timings diff --git a/searx/webapp.py b/searx/webapp.py index 905f53d1..fc851d44 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -56,6 +56,7 @@ from searx import ( searx_debug, ) from searx.data import ENGINE_DESCRIPTIONS +from searx.results import Timing from searx.settings_defaults import OUTPUT_FORMATS from searx.settings_loader import get_default_settings_path from searx.exceptions import SearxParameterException @@ -234,7 +235,7 @@ class ExtendedRequest(flask.Request): form: Dict[str, str] start_time: float render_time: float - timings: List[dict] + timings: List[Timing] request = typing.cast(ExtendedRequest, flask.request) @@ -585,15 +586,14 @@ def post_request(response): 'render;dur=' + str(round(request.render_time * 1000, 3)), ] if len(request.timings) > 0: - timings = sorted(request.timings, key=lambda v: v['total']) + timings = sorted(request.timings, key=lambda t: t.total) timings_total = [ - 'total_' + str(i) + '_' + v['engine'] + ';dur=' + str(round(v['total'] * 1000, 3)) - for i, v in enumerate(timings) + 'total_' + str(i) + '_' + t.engine + ';dur=' + str(round(t.total * 1000, 3)) for i, t in enumerate(timings) ] timings_load = [ - 'load_' + str(i) + '_' + v['engine'] + ';dur=' + str(round(v['load'] * 1000, 3)) - for i, v in enumerate(timings) - if v.get('load') + 'load_' + str(i) + '_' + t.engine + ';dur=' + str(round(t.load * 1000, 3)) + for i, t in enumerate(timings) + if t.load ] timings_all = timings_all + timings_total + timings_load response.headers.add('Server-Timing', ', '.join(timings_all)) diff --git a/tests/unit/test_webapp.py b/tests/unit/test_webapp.py index 920a346a..fd7c72e6 100644 --- a/tests/unit/test_webapp.py +++ b/tests/unit/test_webapp.py @@ -3,6 +3,7 @@ import json from urllib.parse import ParseResult from mock import Mock +from searx.results import Timing import searx.search.processors from searx.search import Search @@ -46,7 +47,10 @@ class ViewsTestCase(SearxTestCase): }, ] - timings = [{'engine': 'startpage', 'total': 0.8, 'load': 0.7}, {'engine': 'youtube', 'total': 0.9, 'load': 0.6}] + timings = [ + Timing(engine='startpage', total=0.8, load=0.7), + Timing(engine='youtube', total=0.9, load=0.6), + ] def search_mock(search_self, *args): search_self.result_container = Mock(