[enh] py: whitenoise for static handling (#5032)

While looking at ways to better handle static files, I saw a package that replaces Flask `static_folder` functionality. Not only it's considerably faster, but already includes the capability to serve sidecars without having to intercept. This also replaces the uWSGI folder mapping functionality.

Closes https://github.com/searxng/searxng/issues/4977
This commit is contained in:
Ivan Gabaldon 2025-07-23 18:16:10 +02:00 committed by GitHub
parent 5cbf422621
commit 42f102ce1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 27 additions and 17 deletions

View File

@ -19,3 +19,4 @@ tomli==2.2.1; python_version < '3.11'
msgspec==0.19.0
typer-slim==0.16.0
isodate==0.7.2
whitenoise==6.9.0

View File

@ -30,6 +30,9 @@ from pygments.formatters import HtmlFormatter # pylint: disable=no-name-in-modu
from werkzeug.serving import is_running_from_reloader
from whitenoise import WhiteNoise
from whitenoise.base import Headers
import flask
from flask import (
@ -147,7 +150,7 @@ STATS_SORT_PARAMETERS = {
}
# Flask app
app = Flask(__name__, static_folder=settings['ui']['static_path'], template_folder=templates_path)
app = Flask(__name__, static_folder=None, template_folder=templates_path)
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
@ -245,6 +248,7 @@ def custom_url_for(endpoint: str, **values):
if not _STATIC_FILES:
_STATIC_FILES = webutils.get_static_file_list()
# handled by WhiteNoise
if endpoint == "static" and values.get("filename"):
# We need to verify the "filename" argument: in the jinja templates
@ -257,9 +261,11 @@ def custom_url_for(endpoint: str, **values):
if arg_filename not in _STATIC_FILES:
# try file in the current theme
theme_name = sxng_request.preferences.get_value("theme")
arg_filename = f"themes/{theme_name}/{arg_filename}"
if arg_filename in _STATIC_FILES:
values["filename"] = arg_filename
theme_filename = f"themes/{theme_name}/{arg_filename}"
if theme_filename in _STATIC_FILES:
values["filename"] = theme_filename
return f"/static/{values['filename']}"
if endpoint == "info" and "locale" not in values:
@ -1424,7 +1430,22 @@ def init():
favicons.init()
application = app
def static_headers(headers: Headers, _path: str, _url: str) -> None:
headers['Cache-Control'] = 'public, max-age=30, stale-while-revalidate=60'
for header, value in settings['server']['default_http_headers'].items():
headers[header] = value
app.wsgi_app = WhiteNoise(
app.wsgi_app,
root=settings['ui']['static_path'],
prefix="static",
max_age=None,
allow_all_origins=False,
add_headers_function=static_headers,
)
patch_application(app)
init()

View File

@ -75,7 +75,4 @@ pythonpath = ${SEARXNG_SRC}
http = ${SEARXNG_INTERNAL_HTTP}
buffer-size = 8192
# To serve the static files via the WSGI server
static-map = /static=${SEARXNG_STATIC}
static-gzip-all = True
offload-threads = %k

View File

@ -72,7 +72,4 @@ pythonpath = ${SEARXNG_SRC}
socket = ${SEARXNG_UWSGI_SOCKET}
buffer-size = 8192
# To serve the static files via the WSGI server
static-map = /static=${SEARXNG_STATIC}
static-gzip-all = True
offload-threads = %k

View File

@ -78,7 +78,4 @@ pythonpath = ${SEARXNG_SRC}
http = ${SEARXNG_INTERNAL_HTTP}
buffer-size = 8192
# To serve the static files via the WSGI server
static-map = /static=${SEARXNG_STATIC}
static-gzip-all = True
offload-threads = %k

View File

@ -75,7 +75,4 @@ pythonpath = ${SEARXNG_SRC}
socket = ${SEARXNG_UWSGI_SOCKET}
buffer-size = 8192
# To serve the static files via the WSGI server
static-map = /static=${SEARXNG_STATIC}
static-gzip-all = True
offload-threads = %k