summaryrefslogtreecommitdiff
path: root/searx/engines/valkey_server.py
diff options
context:
space:
mode:
authorGaspard d'Hautefeuille <github@dhautefeuille.eu>2025-07-09 07:55:37 +0200
committerGitHub <noreply@github.com>2025-07-09 07:55:37 +0200
commitf798ddd4922d793d5e6ccb7c4111810d549ff4f4 (patch)
tree223aa9d26deb176d983cd8e1bed51ff2cff71eff /searx/engines/valkey_server.py
parentbd593d0bad2189f57657bbcfa2c5e86f795c680e (diff)
[mod] migrate from Redis to Valkey (#4795)
This patch migrates from `redis==5.2.1` [1] to `valkey==6.1.0` [2]. The migration to valkey is necessary because the company behind Redis has decided to abandon the open source license. After experiencing a drop in user numbers, they now want to run it under a dual license again. But this move demonstrates once again how unreliable the company is and how it treats open source developers. To review first, read the docs:: $ make docs.live Follow the instructions to remove redis: - http://0.0.0.0:8000/admin/settings/settings_redis.html Config and install a local valkey DB: - http://0.0.0.0:8000/admin/settings/settings_valkey.html [1] https://pypi.org/project/redis/ [2] https://pypi.org/project/valkey/ Co-authored-by: HLFH <gaspard@dhautefeuille.eu> Co-authored-by: Markus Heiser <markus.heiser@darmarit.de>
Diffstat (limited to 'searx/engines/valkey_server.py')
-rw-r--r--searx/engines/valkey_server.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/searx/engines/valkey_server.py b/searx/engines/valkey_server.py
new file mode 100644
index 000000000..b2d3dd26f
--- /dev/null
+++ b/searx/engines/valkey_server.py
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+"""Valkey is an open source (BSD licensed), in-memory data structure (key value
+based) store. Before configuring the ``valkey_server`` engine, you must install
+the dependency valkey_.
+
+Configuration
+=============
+
+Select a database to search in and set its index in the option ``db``. You can
+either look for exact matches or use partial keywords to find what you are
+looking for by configuring ``exact_match_only``.
+
+Example
+=======
+
+Below is an example configuration:
+
+.. code:: yaml
+
+ # Required dependency: valkey
+
+ - name: myvalkey
+ shortcut : rds
+ engine: valkey_server
+ exact_match_only: false
+ host: '127.0.0.1'
+ port: 6379
+ enable_http: true
+ password: ''
+ db: 0
+
+Implementations
+===============
+
+"""
+
+import valkey # pylint: disable=import-error
+
+from searx.result_types import EngineResults
+
+engine_type = 'offline'
+
+# valkey connection variables
+host = '127.0.0.1'
+port = 6379
+password = ''
+db = 0
+
+# engine specific variables
+paging = False
+exact_match_only = True
+
+_valkey_client = None
+
+
+def init(_engine_settings):
+ global _valkey_client # pylint: disable=global-statement
+ _valkey_client = valkey.StrictValkey(
+ host=host,
+ port=port,
+ db=db,
+ password=password or None,
+ decode_responses=True,
+ )
+
+
+def search(query, _params) -> EngineResults:
+ res = EngineResults()
+
+ if not exact_match_only:
+ for kvmap in search_keys(query):
+ res.add(res.types.KeyValue(kvmap=kvmap))
+ return res
+
+ kvmap: dict[str, str] = _valkey_client.hgetall(query)
+ if kvmap:
+ res.add(res.types.KeyValue(kvmap=kvmap))
+ elif " " in query:
+ qset, rest = query.split(" ", 1)
+ for row in _valkey_client.hscan_iter(qset, match='*{}*'.format(rest)):
+ res.add(res.types.KeyValue(kvmap={row[0]: row[1]}))
+ return res
+
+
+def search_keys(query) -> list[dict]:
+ ret = []
+ for key in _valkey_client.scan_iter(match='*{}*'.format(query)):
+ key_type = _valkey_client.type(key)
+ res = None
+
+ if key_type == 'hash':
+ res = _valkey_client.hgetall(key)
+ elif key_type == 'list':
+ res = dict(enumerate(_valkey_client.lrange(key, 0, -1)))
+
+ if res:
+ res['valkey_key'] = key
+ ret.append(res)
+ return ret