
A local development server can be launched by one of these command lines:: $ flask --app searx.webapp run $ python -m searx.webapp The different ways of starting the server should lead to the same result, which is generally the case. However, if the modules are reloaded after code changes (reload option), it must be avoided that the application is initialized twice at startup. We have already discussed this in 2022 [1][2]. Further information on this topic can be found in [3][4][5]. To test a bash in the ./local environment was started and the follwing commands had been executed:: $ ./manage pyenv.cmd bash --norc --noprofile (py3) SEARXNG_DEBUG=1 flask --app searx.webapp run --reload (py3) SEARXNG_DEBUG=1 python -m searx.webapp Since the generic parts of the docs also initialize the app to generate doc from it, the build of the docs was also tested:: $ make docs.clean docs.live [1] https://github.com/searxng/searxng/pull/1656#issuecomment-1214198941 [2] https://github.com/searxng/searxng/pull/1616#issuecomment-1206137468 [3] https://flask.palletsprojects.com/en/stable/api/#flask.Flask.run [4] https://github.com/pallets/flask/issues/5307#issuecomment-1774646119 [5] https://stackoverflow.com/a/25504196 Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
128 lines
3.8 KiB
Python
128 lines
3.8 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
# pylint: disable=missing-module-docstring, cyclic-import
|
|
|
|
import sys
|
|
import os
|
|
from os.path import dirname, abspath
|
|
|
|
import logging
|
|
|
|
import searx.unixthreadname
|
|
import searx.settings_loader
|
|
from searx.settings_defaults import SCHEMA, apply_schema
|
|
|
|
# Debug
|
|
LOG_FORMAT_DEBUG = '%(levelname)-7s %(name)-30.30s: %(message)s'
|
|
|
|
# Production
|
|
LOG_FORMAT_PROD = '%(asctime)-15s %(levelname)s:%(name)s: %(message)s'
|
|
LOG_LEVEL_PROD = logging.WARNING
|
|
|
|
searx_dir = abspath(dirname(__file__))
|
|
searx_parent_dir = abspath(dirname(dirname(__file__)))
|
|
|
|
settings = {}
|
|
sxng_debug = False
|
|
logger = logging.getLogger('searx')
|
|
|
|
_unset = object()
|
|
|
|
|
|
def init_settings():
|
|
"""Initialize global ``settings`` and ``sxng_debug`` variables and
|
|
``logger`` from ``SEARXNG_SETTINGS_PATH``.
|
|
"""
|
|
|
|
global settings, sxng_debug # pylint: disable=global-variable-not-assigned
|
|
|
|
cfg, msg = searx.settings_loader.load_settings(load_user_settings=True)
|
|
cfg = cfg or {}
|
|
apply_schema(cfg, SCHEMA, [])
|
|
|
|
settings.clear()
|
|
settings.update(cfg)
|
|
|
|
sxng_debug = get_setting("general.debug")
|
|
if sxng_debug:
|
|
_logging_config_debug()
|
|
else:
|
|
logging.basicConfig(level=LOG_LEVEL_PROD, format=LOG_FORMAT_PROD)
|
|
logging.root.setLevel(level=LOG_LEVEL_PROD)
|
|
logging.getLogger('werkzeug').setLevel(level=LOG_LEVEL_PROD)
|
|
logger.info(msg)
|
|
|
|
# log max_request_timeout
|
|
max_request_timeout = settings['outgoing']['max_request_timeout']
|
|
if max_request_timeout is None:
|
|
logger.info('max_request_timeout=%s', repr(max_request_timeout))
|
|
else:
|
|
logger.info('max_request_timeout=%i second(s)', max_request_timeout)
|
|
|
|
if settings['server']['public_instance']:
|
|
logger.warning(
|
|
"Be aware you have activated features intended only for public instances. "
|
|
"This force the usage of the limiter and link_token / "
|
|
"see https://docs.searxng.org/admin/searx.limiter.html"
|
|
)
|
|
|
|
|
|
def get_setting(name, default=_unset):
|
|
"""Returns the value to which ``name`` point. If there is no such name in the
|
|
settings and the ``default`` is unset, a :py:obj:`KeyError` is raised.
|
|
|
|
"""
|
|
value = settings
|
|
for a in name.split('.'):
|
|
if isinstance(value, dict):
|
|
value = value.get(a, _unset)
|
|
else:
|
|
value = _unset
|
|
|
|
if value is _unset:
|
|
if default is _unset:
|
|
raise KeyError(name)
|
|
value = default
|
|
break
|
|
|
|
return value
|
|
|
|
|
|
def _is_color_terminal():
|
|
if os.getenv('TERM') in ('dumb', 'unknown'):
|
|
return False
|
|
return sys.stdout.isatty()
|
|
|
|
|
|
def _logging_config_debug():
|
|
try:
|
|
import coloredlogs # pylint: disable=import-outside-toplevel
|
|
except ImportError:
|
|
coloredlogs = None
|
|
|
|
log_level = os.environ.get('SEARXNG_DEBUG_LOG_LEVEL', 'DEBUG')
|
|
if coloredlogs and _is_color_terminal():
|
|
level_styles = {
|
|
'spam': {'color': 'green', 'faint': True},
|
|
'debug': {},
|
|
'notice': {'color': 'magenta'},
|
|
'success': {'bold': True, 'color': 'green'},
|
|
'info': {'bold': True, 'color': 'cyan'},
|
|
'warning': {'color': 'yellow'},
|
|
'error': {'color': 'red'},
|
|
'critical': {'bold': True, 'color': 'red'},
|
|
}
|
|
field_styles = {
|
|
'asctime': {'color': 'green'},
|
|
'hostname': {'color': 'magenta'},
|
|
'levelname': {'color': 8},
|
|
'name': {'color': 8},
|
|
'programname': {'color': 'cyan'},
|
|
'username': {'color': 'yellow'},
|
|
}
|
|
coloredlogs.install(level=log_level, level_styles=level_styles, field_styles=field_styles, fmt=LOG_FORMAT_DEBUG)
|
|
else:
|
|
logging.basicConfig(level=logging.getLevelName(log_level), format=LOG_FORMAT_DEBUG)
|
|
|
|
|
|
init_settings()
|