1
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2026-03-30 13:28:07 +02:00

refactor(fuzzy-search): unify is_match for fuzzy search

This commit is contained in:
2026-03-16 16:20:30 +01:00
committed by Christian Appel
parent 2b0f575733
commit d4afcb6832
4 changed files with 39 additions and 57 deletions

View File

@@ -0,0 +1,35 @@
"""Module providing fuzzy search utilities for the BEC widgets."""
from __future__ import annotations
from typing import Any
from thefuzz import fuzz
FUZZY_SEARCH_THRESHOLD = 80
def is_match(
text: str, row_data: dict[str, Any], relevant_keys: list[str], enable_fuzzy: bool
) -> bool:
"""
Check if the text matches any of the relevant keys in the row data.
Args:
text (str): The text to search for.
row_data (dict[str, Any]): The row data to search in.
relevant_keys (list[str]): The keys to consider for searching.
enable_fuzzy (bool): Whether to use fuzzy matching.
Returns:
bool: True if a match is found, False otherwise.
"""
for key in relevant_keys:
data = str(row_data.get(key, "") or "")
if enable_fuzzy:
match_ratio = fuzz.partial_ratio(text.lower(), data.lower())
if match_ratio >= FUZZY_SEARCH_THRESHOLD:
return True
else:
if text.lower() in data.lower():
return True
return False

View File

@@ -5,9 +5,8 @@ in DeviceTableRow entries.
from __future__ import annotations
import traceback
from copy import deepcopy
from typing import TYPE_CHECKING, Any, Callable, Iterable, Literal, Tuple
from typing import TYPE_CHECKING, Any, Callable, Iterable, Tuple
from bec_lib.atlas_models import Device as DeviceModel
from bec_lib.callback_handler import EventType
@@ -19,6 +18,7 @@ from thefuzz import fuzz
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.utils.colors import get_accent_colors
from bec_widgets.utils.error_popups import SafeSlot
from bec_widgets.utils.fuzzy_search import is_match
from bec_widgets.widgets.control.device_manager.components.device_table.device_table_row import (
DeviceTableRow,
)
@@ -37,34 +37,6 @@ _DeviceCfgIter = Iterable[dict[str, Any]]
# DeviceValidationResult: device_config, config_status, connection_status, error_message
_ValidationResultIter = Iterable[Tuple[dict[str, Any], ConfigStatus, ConnectionStatus, str]]
FUZZY_SEARCH_THRESHOLD = 80
def is_match(
text: str, row_data: dict[str, Any], relevant_keys: list[str], enable_fuzzy: bool
) -> bool:
"""
Check if the text matches any of the relevant keys in the row data.
Args:
text (str): The text to search for.
row_data (dict[str, Any]): The row data to search in.
relevant_keys (list[str]): The keys to consider for searching.
enable_fuzzy (bool): Whether to use fuzzy matching.
Returns:
bool: True if a match is found, False otherwise.
"""
for key in relevant_keys:
data = str(row_data.get(key, "") or "")
if enable_fuzzy:
match_ratio = fuzz.partial_ratio(text.lower(), data.lower())
if match_ratio >= FUZZY_SEARCH_THRESHOLD:
return True
else:
if text.lower() in data.lower():
return True
return False
class TableSortOnHold:
"""Context manager for putting table sorting on hold. Works with nested calls."""

View File

@@ -21,6 +21,7 @@ from qtpy.QtWidgets import (
from thefuzz import fuzz
from bec_widgets.utils.error_popups import SafeSlot
from bec_widgets.utils.fuzzy_search import is_match
from bec_widgets.widgets.services.bec_atlas_admin_view.experiment_selection.experiment_mat_card import (
ExperimentMatCard,
)
@@ -31,32 +32,6 @@ from bec_widgets.widgets.services.bec_atlas_admin_view.experiment_selection.util
logger = bec_logger.logger
FUZZY_SEARCH_THRESHOLD = 80
def is_match(text: str, data: dict[str, Any], relevant_keys: list[str], enable_fuzzy: bool) -> bool:
"""
Check if the text matches any of the relevant keys in the row data.
Args:
text (str): The text to search for.
data (dict[str, Any]): The data to search in.
relevant_keys (list[str]): The keys to consider for searching.
enable_fuzzy (bool): Whether to use fuzzy matching.
Returns:
bool: True if a match is found, False otherwise.
"""
for key in relevant_keys:
data_value = str(data.get(key, "") or "")
if enable_fuzzy:
match_ratio = fuzz.partial_ratio(text.lower(), data_value.lower())
if match_ratio >= FUZZY_SEARCH_THRESHOLD:
return True
else:
if text.lower() in data_value.lower():
return True
return False
class ExperimentSelection(QWidget):
experiment_selected = Signal(dict)

View File

@@ -15,6 +15,7 @@ from bec_lib.messages import (
from qtpy.QtCore import QByteArray, QUrl
from qtpy.QtNetwork import QNetworkRequest
from bec_widgets.utils.fuzzy_search import is_match
from bec_widgets.widgets.services.bec_atlas_admin_view.bec_atlas_admin_view import BECAtlasAdminView
from bec_widgets.widgets.services.bec_atlas_admin_view.bec_atlas_http_service import (
AtlasEndpoints,
@@ -28,7 +29,6 @@ from bec_widgets.widgets.services.bec_atlas_admin_view.experiment_selection.expe
)
from bec_widgets.widgets.services.bec_atlas_admin_view.experiment_selection.experiment_selection import (
ExperimentSelection,
is_match,
)
from bec_widgets.widgets.services.bec_atlas_admin_view.experiment_selection.utils import (
format_datetime,