Repository: searxng/searxng

Issue:
SEARX_SETTINGS_PATH fallback is ignored for uwsgi
<!-- PLEASE FILL THESE FIELDS, IT REALLY HELPS THE MAINTAINERS OF SearXNG -->

**Version of SearXNG, commit number if you are using on master branch and stipulate if you forked SearXNG**
<!-- If you are running on master branch using git execute this command
in order to fetch the latest commit ID:
```
git log -1
``` 
If you are using searxng-docker then look at the bottom of the SearXNG page
and check for the version after "Powered by SearXNG"

Please also stipulate if you are using a forked version of SearXNG and
include a link to the fork source code.
-->
7bf4e8d12d1d0ee53bf71f7c3a4010ef936f25d9
**How did you install SearXNG?**
<!-- Did you install SearXNG using the official wiki or using searxng-docker
or manually by executing the searx/webapp.py file? -->
NixOS module
**What happened?**
<!-- A clear and concise description of what the bug is. -->
``SEARX_SETTINGS_PATH`` is being ignored when running via uwsgi vessel and the default config is being used. Using SEARXNG_SETTINGS_PATH instead works.
**How To Reproduce**
<!-- How can we reproduce this issue? (as minimally and as precisely as possible) -->
Run searx via uwsgi and supply the config only via SEARXNG_SETTINGS_PATH.
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->

**Screenshots & Logs**
<!-- If applicable, add screenshots, logs to help explain your problem. -->

```
Jul 17 21:18:12 hydrogen uwsgi[4009531]: DAMN ! worker 1 (pid: 42032) died :( trying respawn ...
Jul 17 21:18:12 hydrogen uwsgi[4009531]: worker respawning too fast !!! i have to sleep a bit (2 seconds)...
Jul 17 21:18:14 hydrogen uwsgi[4009531]: Respawned uWSGI worker 1 (new pid: 43476)
Jul 17 21:18:14 hydrogen uwsgi[43476]: SEARXNG_SETTINGS_PATH uses value from SEARX_SETTINGS_PATH
Jul 17 21:18:14 hydrogen uwsgi[43476]: 2022-07-17 21:18:14,905 ERROR:searx: git is not found, fallback to the default version
Jul 17 21:18:14 hydrogen uwsgi[43476]: 2022-07-17 21:18:14,991 ERROR:searx.shared: uwsgi.ini configuration error, add this line to your uwsgi.ini
Jul 17 21:18:14 hydrogen uwsgi[43476]: cache2 = name=searxcache,items=2000,blocks=2000,blocksize=4096,bitmap=1
Jul 17 21:18:14 hydrogen uwsgi[43476]: 2022-07-17 21:18:14,994 ERROR:searx.webapp: server.secret_key is not changed. Please use something else instead of ultrasecretkey.
Jul 17 21:18:15 hydrogen uwsgi[4009531]: DAMN ! worker 1 (pid: 43476) died :( trying respawn ...
Jul 17 21:18:15 hydrogen uwsgi[4009531]: Respawned uWSGI worker 1 (new pid: 43615)
Jul 17 21:18:15 hydrogen uwsgi[43615]: SEARXNG_SETTINGS_PATH uses value from SEARX_SETTINGS_PATH
Jul 17 21:18:15 hydrogen uwsgi[43615]: 2022-07-17 21:18:15,928 ERROR:searx: git is not found, fallback to the default version
Jul 17 21:18:15 hydrogen systemd[1]: Stopping uwsgi.service...
``` 

**Additional context**
<!-- Add any other context about the problem here. -->



Discussion:
Is there a NixOS package for SearXNG? or did you use the [searx package](https://github.com/NixOS/nixpkgs/blob/nixos-22.05/pkgs/servers/web-apps/searx/default.nix#L71)?

---

Reading the code, it seems the issue can be fixed by moving this code
https://github.com/searxng/searxng/blob/a983db022954b302f12640c7b3f5c3a6ce697101/searx/settings_defaults.py#L230-L234
in this function:
https://github.com/searxng/searxng/blob/a983db022954b302f12640c7b3f5c3a6ce697101/searx/settings_loader.py#L123

> Is there a NixOS package for SearXNG? or did you use the [searx package](https://github.com/NixOS/nixpkgs/blob/nixos-22.05/pkgs/servers/web-apps/searx/default.nix?rgh-link-date=2022-07-19T21%3A57%3A47Z#L71)?

Yes, I am using it https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/web-apps/searxng/default.nix


> Reading the code, it seems the issue can be fixed by moving this code

@dalf to me the origin of the issue and the suggested bugfix is not 100% clear .. if you have time could you  implement a PR with the bugfix / thanks!


Resolving patch:
diff --git a/searx/settings_defaults.py b/searx/settings_defaults.py
--- a/searx/settings_defaults.py
+++ b/searx/settings_defaults.py
@@ -41,16 +41,6 @@
 }
 _UNDEFINED = object()
 
-# compatibility
-SEARX_ENVIRON_VARIABLES = {
-    'SEARX_DISABLE_ETC_SETTINGS': 'SEARXNG_DISABLE_ETC_SETTINGS',
-    'SEARX_SETTINGS_PATH': 'SEARXNG_SETTINGS_PATH',
-    'SEARX_DEBUG': 'SEARXNG_DEBUG',
-    'SEARX_PORT': 'SEARXNG_PORT',
-    'SEARX_BIND_ADDRESS': 'SEARXNG_BIND_ADDRESS',
-    'SEARX_SECRET': 'SEARXNG_SECRET',
-}
-
 
 class SettingsValue:
     """Check and update a setting value"""
@@ -227,11 +217,5 @@ def apply_schema(settings, schema, path_list):
 
 
 def settings_set_defaults(settings):
-    # compatibility with searx variables
-    for searx, searxng in SEARX_ENVIRON_VARIABLES.items():
-        if searx in os.environ and searxng not in os.environ:
-            os.environ[searxng] = os.environ[searx]
-            logger.warning('%s uses value from %s', searxng, searx)
-
     apply_schema(settings, SCHEMA, [])
     return settings
diff --git a/searx/settings_loader.py b/searx/settings_loader.py
--- a/searx/settings_loader.py
+++ b/searx/settings_loader.py
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: AGPL-3.0-or-later
 
+from typing import Optional
 from os import environ
 from os.path import dirname, join, abspath, isfile
 from collections.abc import Mapping
@@ -13,7 +14,7 @@
 searx_dir = abspath(dirname(__file__))
 
 
-def check_settings_yml(file_name):
+def existing_filename_or_none(file_name: str) -> Optional[str]:
     if isfile(file_name):
         return file_name
     return None
@@ -30,29 +31,29 @@ def load_yaml(file_name):
 
 
 def get_default_settings_path():
-    return check_settings_yml(join(searx_dir, 'settings.yml'))
+    return existing_filename_or_none(join(searx_dir, 'settings.yml'))
 
 
-def get_user_settings_path():
-    # find location of settings.yml
+def get_user_settings_path() -> Optional[str]:
+    """Get an user settings file.
+    By descending priority:
+    1. ``environ['SEARXNG_SETTINGS_PATH']``
+    2. ``/etc/searxng/settings.yml`` except if ``SEARXNG_DISABLE_ETC_SETTINGS`` is ``true`` or ``1``
+    3. ``None``
+    """
+
+    # check the environment variable SEARXNG_SETTINGS_PATH
+    # if the environment variable is defined, this is the last check
     if 'SEARXNG_SETTINGS_PATH' in environ:
-        # if possible set path to settings using the
-        # enviroment variable SEARXNG_SETTINGS_PATH
-        return check_settings_yml(environ['SEARXNG_SETTINGS_PATH'])
+        return existing_filename_or_none(environ['SEARXNG_SETTINGS_PATH'])
 
+    # if SEARXNG_DISABLE_ETC_SETTINGS don't look any futher
     if environ.get('SEARXNG_DISABLE_ETC_SETTINGS', '').lower() in ('1', 'true'):
         return None
 
-    # if not, get it from searx code base or last solution from /etc/searxng
-    try:
-        return check_settings_yml('/etc/searxng/settings.yml')
-    except SearxSettingsException as e:
-        # fall back to searx settings
-        try:
-            return check_settings_yml('/etc/searx/settings.yml')
-        except SearxSettingsException:
-            # if none are found, raise the exception about SearXNG
-            raise e  # pylint: disable=raise-missing-from
+    # check /etc/searxng/settings.yml
+    # (continue with other locations if the file is not found)
+    return existing_filename_or_none('/etc/searxng/settings.yml')
 
 
 def update_dict(default_dict, user_dict):


Test patch:
diff --git a/tests/unit/test_settings_loader.py b/tests/unit/test_settings_loader.py
--- a/tests/unit/test_settings_loader.py
+++ b/tests/unit/test_settings_loader.py
@@ -22,11 +22,11 @@ def test_load_zero(self):
         with self.assertRaises(SearxSettingsException):
             settings_loader.load_yaml(join(test_dir, '/settings/empty_settings.yml'))
 
-    def test_check_settings_yml(self):
-        self.assertIsNone(settings_loader.check_settings_yml('/dev/zero'))
+    def test_existing_filename_or_none(self):
+        self.assertIsNone(settings_loader.existing_filename_or_none('/dev/zero'))
 
         bad_settings_path = join(test_dir, 'settings/syntaxerror_settings.yml')
-        self.assertEqual(settings_loader.check_settings_yml(bad_settings_path), bad_settings_path)
+        self.assertEqual(settings_loader.existing_filename_or_none(bad_settings_path), bad_settings_path)
 
 
 class TestDefaultSettings(SearxTestCase):