Coverage for apps / ai / services / ranking.py: 100%
19 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-12 10:49 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-12 10:49 +0000
1"""Deterministic search result ranking by image presence and query relevance."""
4def _filter_valid(results: list[dict]) -> list[dict]:
5 """Filter out results without titles (QA-053).
7 Results without titles will fail to import, so they should
8 never be shown to users.
9 """
10 return [r for r in results if r.get("title")]
13def _score_result(result: dict, query_terms: list[str]) -> int:
14 """Score a single result by image presence and query term matches."""
15 score = 0
16 if result.get("image_url"):
17 score += 100
19 title_lower = result.get("title", "").lower()
20 for term in query_terms:
21 if term in title_lower:
22 score += 5
24 if query_terms and " ".join(query_terms) in title_lower:
25 score += 10
27 return score
30def rank_results(query: str, results: list[dict]) -> list[dict]:
31 """Rank search results by image presence and query relevance.
33 Args:
34 query: The original search query.
35 results: List of search result dicts.
37 Returns:
38 Filtered and sorted results, highest score first.
39 """
40 results = _filter_valid(results)
41 if not results:
42 return results
44 query_terms = [t for t in query.lower().split() if len(t) >= 2]
45 return sorted(results, key=lambda r: _score_result(r, query_terms), reverse=True)