.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.settings_loader Namespace Reference

Functions

SettingsType load_yaml (str|Path file_name)
SettingsType get_yaml_cfg (str|Path file_name)
Path|None get_user_cfg_folder ()
 update_dict (MutableMapping[str, t.Any] default_dict, MutableMapping[str, t.Any] user_dict)
 update_settings (MutableMapping[str, t.Any] default_settings, MutableMapping[str, t.Any] user_settings)
bool is_use_default_settings (SettingsType user_settings)
tuple[SettingsType, str] load_settings (bool load_user_settings=True)

Variables

JSONType = dict[str, "JSONType"] | list["JSONType"] | str | int | float | bool | None
SettingsType = dict[str, JSONType]
 searx_dir = os.path.abspath(os.path.dirname(__file__))
 SETTINGS_YAML = Path("settings.yml")
 DEFAULT_SETTINGS_FILE = Path(searx_dir) / SETTINGS_YAML

Detailed Description

Implementations for loading configurations from YAML files.  This essentially
includes the configuration of the (:ref:`SearXNG appl <searxng settings.yml>`)
server. The default configuration for the application server is loaded from the
:origin:`DEFAULT_SETTINGS_FILE <searx/settings.yml>`.  This default
configuration can be completely replaced or :ref:`customized individually
<use_default_settings.yml>` and the ``SEARXNG_SETTINGS_PATH`` environment
variable can be used to set the location from which the local customizations are
to be loaded. The rules used for this can be found in the
:py:obj:`get_user_cfg_folder` function.

- By default, local configurations are expected in folder ``/etc/searxng`` from
  where applications can load them with the :py:obj:`get_yaml_cfg` function.

- By default, customized :ref:`SearXNG appl <searxng settings.yml>` settings are
  expected in a file named ``settings.yml``.

Function Documentation

◆ get_user_cfg_folder()

Path | None searx.settings_loader.get_user_cfg_folder ( )
Returns folder where the local configurations are located.

1. If the ``SEARXNG_SETTINGS_PATH`` environment is set and points to a
   folder (e.g. ``/etc/mysxng/``), all local configurations are expected in
   this folder.  The settings of the :ref:`SearXNG appl <searxng
   settings.yml>` then expected in ``settings.yml``
   (e.g. ``/etc/mysxng/settings.yml``).

2. If the ``SEARXNG_SETTINGS_PATH`` environment is set and points to a file
   (e.g. ``/etc/mysxng/myinstance.yml``), this file contains the settings of
   the :ref:`SearXNG appl <searxng settings.yml>` and the folder
   (e.g. ``/etc/mysxng/``) is used for all other configurations.

   This type (``SEARXNG_SETTINGS_PATH`` points to a file) is suitable for
   use cases in which different profiles of the :ref:`SearXNG appl <searxng
   settings.yml>` are to be managed, such as in test scenarios.

3. If folder ``/etc/searxng`` exists, it is used.

In case none of the above path exists, ``None`` is returned.  In case of
environment ``SEARXNG_SETTINGS_PATH`` is set, but the (folder or file) does
not exists, a :py:obj:`EnvironmentError` is raised.

Definition at line 66 of file settings_loader.py.

66def get_user_cfg_folder() -> Path | None:
67 """Returns folder where the local configurations are located.
68
69 1. If the ``SEARXNG_SETTINGS_PATH`` environment is set and points to a
70 folder (e.g. ``/etc/mysxng/``), all local configurations are expected in
71 this folder. The settings of the :ref:`SearXNG appl <searxng
72 settings.yml>` then expected in ``settings.yml``
73 (e.g. ``/etc/mysxng/settings.yml``).
74
75 2. If the ``SEARXNG_SETTINGS_PATH`` environment is set and points to a file
76 (e.g. ``/etc/mysxng/myinstance.yml``), this file contains the settings of
77 the :ref:`SearXNG appl <searxng settings.yml>` and the folder
78 (e.g. ``/etc/mysxng/``) is used for all other configurations.
79
80 This type (``SEARXNG_SETTINGS_PATH`` points to a file) is suitable for
81 use cases in which different profiles of the :ref:`SearXNG appl <searxng
82 settings.yml>` are to be managed, such as in test scenarios.
83
84 3. If folder ``/etc/searxng`` exists, it is used.
85
86 In case none of the above path exists, ``None`` is returned. In case of
87 environment ``SEARXNG_SETTINGS_PATH`` is set, but the (folder or file) does
88 not exists, a :py:obj:`EnvironmentError` is raised.
89
90 """
91
92 folder = None
93 settings_path = os.environ.get("SEARXNG_SETTINGS_PATH")
94
95 # Disable default /etc/searxng is intended exclusively for internal testing purposes
96 # and is therefore not documented!
97 disable_etc = os.environ.get('SEARXNG_DISABLE_ETC_SETTINGS', '').lower() in ('1', 'true')
98
99 if settings_path:
100 # rule 1. and 2.
101 settings_path = Path(settings_path)
102 if settings_path.is_dir():
103 folder = settings_path
104 elif settings_path.is_file():
105 folder = settings_path.parent
106 else:
107 raise EnvironmentError(1, f"{settings_path} not exists!", settings_path)
108
109 if not folder and not disable_etc:
110 # default: rule 3.
111 folder = Path("/etc/searxng")
112 if not folder.is_dir():
113 folder = None
114
115 return folder
116
117

Referenced by get_yaml_cfg(), and load_settings().

Here is the caller graph for this function:

◆ get_yaml_cfg()

SettingsType searx.settings_loader.get_yaml_cfg ( str | Path file_name)
Shortcut to load a YAML config from a file, located in the

- :py:obj:`get_user_cfg_folder` or
- in the ``searx`` folder of the SearXNG installation

Definition at line 51 of file settings_loader.py.

51def get_yaml_cfg(file_name: str | Path) -> SettingsType:
52 """Shortcut to load a YAML config from a file, located in the
53
54 - :py:obj:`get_user_cfg_folder` or
55 - in the ``searx`` folder of the SearXNG installation
56 """
57
58 folder = get_user_cfg_folder() or Path(searx_dir)
59 fname = folder / file_name
60 if not fname.is_file():
61 raise FileNotFoundError(f"File {fname} does not exist!")
62
63 return load_yaml(fname)
64
65

References get_user_cfg_folder(), and load_yaml().

Here is the call graph for this function:

◆ is_use_default_settings()

bool searx.settings_loader.is_use_default_settings ( SettingsType user_settings)

Definition at line 182 of file settings_loader.py.

182def is_use_default_settings(user_settings: SettingsType) -> bool:
183
184 use_default_settings: bool | JSONType = user_settings.get('use_default_settings')
185 if use_default_settings is True:
186 return True
187 if isinstance(use_default_settings, dict):
188 return True
189 if use_default_settings is False or use_default_settings is None:
190 return False
191 raise ValueError('Invalid value for use_default_settings')
192
193

Referenced by load_settings().

Here is the caller graph for this function:

◆ load_settings()

tuple[SettingsType, str] searx.settings_loader.load_settings ( bool load_user_settings = True)
Function for loading the settings of the SearXNG application
(:ref:`settings.yml <searxng settings.yml>`).

Definition at line 194 of file settings_loader.py.

194def load_settings(load_user_settings: bool = True) -> tuple[SettingsType, str]:
195 """Function for loading the settings of the SearXNG application
196 (:ref:`settings.yml <searxng settings.yml>`)."""
197
198 msg = f"load the default settings from {DEFAULT_SETTINGS_FILE}"
199 cfg = load_yaml(DEFAULT_SETTINGS_FILE)
200 cfg_folder = get_user_cfg_folder()
201
202 if not load_user_settings or not cfg_folder:
203 return cfg, msg
204
205 settings_yml = os.environ.get("SEARXNG_SETTINGS_PATH")
206 if settings_yml and Path(settings_yml).is_file():
207 # see get_user_cfg_folder() --> SEARXNG_SETTINGS_PATH points to a file
208 settings_yml = Path(settings_yml).name
209 else:
210 # see get_user_cfg_folder() --> SEARXNG_SETTINGS_PATH points to a folder
211 settings_yml = SETTINGS_YAML
212
213 cfg_file = cfg_folder / settings_yml
214 if not cfg_file.exists():
215 return cfg, msg
216
217 msg = f"load the user settings from {cfg_file}"
218 user_cfg = load_yaml(cfg_file)
219
220 if is_use_default_settings(user_cfg):
221 # the user settings are merged with the default configuration
222 msg = f"merge the default settings ( {DEFAULT_SETTINGS_FILE} ) and the user settings ( {cfg_file} )"
223 update_settings(cfg, user_cfg)
224 else:
225 cfg = user_cfg
226
227 return cfg, msg

References get_user_cfg_folder(), is_use_default_settings(), load_yaml(), and update_settings().

Here is the call graph for this function:

◆ load_yaml()

SettingsType searx.settings_loader.load_yaml ( str | Path file_name)
Load YAML config from a file.

Definition at line 40 of file settings_loader.py.

40def load_yaml(file_name: str | Path) -> SettingsType:
41 """Load YAML config from a file."""
42 try:
43 with open(file_name, 'r', encoding='utf-8') as settings_yaml:
44 return yaml.safe_load(settings_yaml) or {}
45 except IOError as e:
46 raise SearxSettingsException(e, str(file_name)) from e
47 except yaml.YAMLError as e:
48 raise SearxSettingsException(e, str(file_name)) from e
49
50

Referenced by get_yaml_cfg(), and load_settings().

Here is the caller graph for this function:

◆ update_dict()

searx.settings_loader.update_dict ( MutableMapping[str, t.Any] default_dict,
MutableMapping[str, t.Any] user_dict )

Definition at line 118 of file settings_loader.py.

118def update_dict(default_dict: MutableMapping[str, t.Any], user_dict: MutableMapping[str, t.Any]):
119 for k, v in user_dict.items():
120 if isinstance(v, MutableMapping):
121 default_dict[k] = update_dict(default_dict.get(k, {}), v) # type: ignore
122 else:
123 default_dict[k] = v
124 return default_dict
125
126

References update_dict().

Referenced by update_dict(), and update_settings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_settings()

searx.settings_loader.update_settings ( MutableMapping[str, t.Any] default_settings,
MutableMapping[str, t.Any] user_settings )

Definition at line 127 of file settings_loader.py.

127def update_settings(default_settings: MutableMapping[str, t.Any], user_settings: MutableMapping[str, t.Any]):
128 # pylint: disable=too-many-branches
129
130 # merge everything except the engines
131 for k, v in user_settings.items():
132 if k not in ('use_default_settings', 'engines'):
133 if k in default_settings and isinstance(v, MutableMapping):
134 update_dict(default_settings[k], v) # type: ignore
135 else:
136 default_settings[k] = v
137
138 categories_as_tabs = user_settings.get('categories_as_tabs')
139 if categories_as_tabs:
140 default_settings['categories_as_tabs'] = categories_as_tabs
141
142 plugins = user_settings.get('plugins')
143 if plugins is not None:
144 default_settings['plugins'] = plugins
145
146 # parse the engines
147 remove_engines: None | list[str] = None
148 keep_only_engines: list[str] | None = None
149 use_default_settings: dict[str, t.Any] | None = user_settings.get('use_default_settings')
150 if isinstance(use_default_settings, dict):
151 remove_engines = use_default_settings.get('engines', {}).get('remove')
152 keep_only_engines = use_default_settings.get('engines', {}).get('keep_only')
153
154 if 'engines' in user_settings or remove_engines is not None or keep_only_engines is not None:
155 engines: list[dict[str, t.Any]] = default_settings['engines']
156
157 # parse "use_default_settings.engines.remove"
158 if remove_engines is not None:
159 engines = list(filterfalse(lambda engine: (engine.get('name')) in remove_engines, engines))
160
161 # parse "use_default_settings.engines.keep_only"
162 if keep_only_engines is not None:
163 engines = list(filter(lambda engine: (engine.get('name')) in keep_only_engines, engines))
164
165 # parse "engines"
166 user_engines = user_settings.get('engines')
167 if user_engines:
168 engines_dict = dict((definition['name'], definition) for definition in engines)
169 for user_engine in user_engines:
170 default_engine: dict[str, t.Any] | None = engines_dict.get(user_engine['name'])
171 if default_engine:
172 update_dict(default_engine, user_engine)
173 else:
174 engines.append(user_engine)
175
176 # store the result
177 default_settings['engines'] = engines
178
179 return default_settings
180
181

References update_dict().

Referenced by load_settings().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ DEFAULT_SETTINGS_FILE

searx.settings_loader.DEFAULT_SETTINGS_FILE = Path(searx_dir) / SETTINGS_YAML

Definition at line 36 of file settings_loader.py.

◆ JSONType

t searx.settings_loader.JSONType = dict[str, "JSONType"] | list["JSONType"] | str | int | float | bool | None

Definition at line 30 of file settings_loader.py.

◆ searx_dir

searx.settings_loader.searx_dir = os.path.abspath(os.path.dirname(__file__))

Definition at line 33 of file settings_loader.py.

◆ SETTINGS_YAML

searx.settings_loader.SETTINGS_YAML = Path("settings.yml")

Definition at line 35 of file settings_loader.py.

◆ SettingsType

t searx.settings_loader.SettingsType = dict[str, JSONType]

Definition at line 31 of file settings_loader.py.