From ee4ba14c6b3dccfaf8e81165f5dd30c5992d98c8 Mon Sep 17 00:00:00 2001 From: Lucas Santos <100425690+lucassantos540@users.noreply.github.com> Date: Wed, 25 Jun 2025 20:46:41 -0300 Subject: [PATCH 1/8] Update webui.py --- webui.py | 169 ++++++++++++++++++++----------------------------------- 1 file changed, 61 insertions(+), 108 deletions(-) diff --git a/webui.py b/webui.py index 2c417168aa6..4e90b050f7a 100644 --- a/webui.py +++ b/webui.py @@ -1,117 +1,88 @@ -from __future__ import annotations +def limpar_temp_dir(): + if shared.opts.clean_temp_dir_at_start: + ui_tempdir.cleanup_tmpdr() + startup_timer.record("cleanup temp dir") -import os -import time -from modules import timer -from modules import initialize_util -from modules import initialize +def configurar_ui(): + shared.demo = ui.create_ui() + startup_timer.record("create ui") + if not cmd_opts.no_gradio_queue: + shared.demo.queue(64) -startup_timer = timer.startup_timer -startup_timer.record("launcher") -initialize.imports() +def decidir_autolancamento(): + if os.getenv('SD_WEBUI_RESTARTING') == '1': + return False + if shared.opts.auto_launch_browser == "Remote" or cmd_opts.autolaunch: + return True + if shared.opts.auto_launch_browser == "Local": + return not cmd_opts.webui_is_non_local + return False -initialize.check_versions() +def lancar_interface(auto_launch_browser): + gradio_auth_creds = list(initialize_util.get_gradio_auth_creds()) or None -def create_api(app): - from modules.api.api import Api - from modules.call_queue import queue_lock - - api = Api(app, queue_lock) - return api + return shared.demo.launch( + share=cmd_opts.share, + server_name=initialize_util.gradio_server_name(), + server_port=cmd_opts.port, + ssl_keyfile=cmd_opts.tls_keyfile, + ssl_certfile=cmd_opts.tls_certfile, + ssl_verify=cmd_opts.disable_tls_verify, + debug=cmd_opts.gradio_debug, + auth=gradio_auth_creds, + inbrowser=auto_launch_browser, + prevent_thread_lock=True, + allowed_paths=cmd_opts.gradio_allowed_path, + app_kwargs={"docs_url": "/docs", "redoc_url": "/redoc"}, + root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else "", + ) -def api_only(): - from fastapi import FastAPI - from modules.shared_cmd_options import cmd_opts +def proteger_app(app): + app.user_middleware = [ + x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware' + ] + initialize_util.setup_middleware(app) - initialize.initialize() - app = FastAPI() - initialize_util.setup_middleware(app) - api = create_api(app) +def configurar_apis(app): + progress.setup_progress_api(app) + ui.setup_ui_api(app) + if cmd_opts.api: + create_api(app) + ui_extra_networks.add_pages_to_demo(app) - from modules import script_callbacks - script_callbacks.before_ui_callback() - script_callbacks.app_started_callback(None, app) - print(f"Startup time: {startup_timer.summary()}.") - api.launch( - server_name=initialize_util.gradio_server_name(), - port=cmd_opts.port if cmd_opts.port else 7861, - root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else "" - ) +def monitorar_comandos(): + while True: + server_command = shared.state.wait_for_server_command(timeout=5) + if server_command: + if server_command in ("stop", "restart"): + return server_command + else: + print(f"Unknown server command: {server_command}") def webui(): - from modules.shared_cmd_options import cmd_opts - - launch_api = cmd_opts.api initialize.initialize() - from modules import shared, ui_tempdir, script_callbacks, ui, progress, ui_extra_networks - while 1: - if shared.opts.clean_temp_dir_at_start: - ui_tempdir.cleanup_tmpdr() - startup_timer.record("cleanup temp dir") - + while True: + limpar_temp_dir() script_callbacks.before_ui_callback() startup_timer.record("scripts before_ui_callback") - shared.demo = ui.create_ui() - startup_timer.record("create ui") - - if not cmd_opts.no_gradio_queue: - shared.demo.queue(64) - - gradio_auth_creds = list(initialize_util.get_gradio_auth_creds()) or None - - auto_launch_browser = False - if os.getenv('SD_WEBUI_RESTARTING') != '1': - if shared.opts.auto_launch_browser == "Remote" or cmd_opts.autolaunch: - auto_launch_browser = True - elif shared.opts.auto_launch_browser == "Local": - auto_launch_browser = not cmd_opts.webui_is_non_local - - app, local_url, share_url = shared.demo.launch( - share=cmd_opts.share, - server_name=initialize_util.gradio_server_name(), - server_port=cmd_opts.port, - ssl_keyfile=cmd_opts.tls_keyfile, - ssl_certfile=cmd_opts.tls_certfile, - ssl_verify=cmd_opts.disable_tls_verify, - debug=cmd_opts.gradio_debug, - auth=gradio_auth_creds, - inbrowser=auto_launch_browser, - prevent_thread_lock=True, - allowed_paths=cmd_opts.gradio_allowed_path, - app_kwargs={ - "docs_url": "/docs", - "redoc_url": "/redoc", - }, - root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else "", - ) + configurar_ui() + auto_launch_browser = decidir_autolancamento() + app, _, _ = lancar_interface(auto_launch_browser) startup_timer.record("gradio launch") - # gradio uses a very open CORS policy via app.user_middleware, which makes it possible for - # an attacker to trick the user into opening a malicious HTML page, which makes a request to the - # running web ui and do whatever the attacker wants, including installing an extension and - # running its code. We disable this here. Suggested by RyotaK. - app.user_middleware = [x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware'] - - initialize_util.setup_middleware(app) - - progress.setup_progress_api(app) - ui.setup_ui_api(app) - - if launch_api: - create_api(app) - - ui_extra_networks.add_pages_to_demo(app) + proteger_app(app) + configurar_apis(app) startup_timer.record("add APIs") @@ -122,26 +93,17 @@ def webui(): print(f"Startup time: {startup_timer.summary()}.") try: - while True: - server_command = shared.state.wait_for_server_command(timeout=5) - if server_command: - if server_command in ("stop", "restart"): - break - else: - print(f"Unknown server command: {server_command}") + server_command = monitorar_comandos() except KeyboardInterrupt: print('Caught KeyboardInterrupt, stopping...') server_command = "stop" if server_command == "stop": print("Stopping server...") - # If we catch a keyboard interrupt, we want to stop the server and exit. shared.demo.close() break - # disable auto launch webui in browser for subsequent UI Reload os.environ.setdefault('SD_WEBUI_RESTARTING', '1') - print('Restarting UI...') shared.demo.close() time.sleep(0.5) @@ -151,12 +113,3 @@ def webui(): script_callbacks.script_unloaded_callback() startup_timer.record("scripts unloaded callback") initialize.initialize_rest(reload_script_modules=True) - - -if __name__ == "__main__": - from modules.shared_cmd_options import cmd_opts - - if cmd_opts.nowebui: - api_only() - else: - webui() From 6b71b0ed836b8c61f092e369e77501911dc9d5f3 Mon Sep 17 00:00:00 2001 From: Lucas Santos <100425690+lucassantos540@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:07:12 -0300 Subject: [PATCH 2/8] Update webui.py --- webui.py | 56 ++++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/webui.py b/webui.py index 418e0a8704a..d9e1ef6af4b 100644 --- a/webui.py +++ b/webui.py @@ -1,16 +1,33 @@ +import os +import time +from modules import ( + shared, + ui_tempdir, + startup_timer, + initialize_util, + progress, + ui, + ui_extra_networks, + timer, + initialize, + script_callbacks +) +from api import create_api # ajuste se create_api for de outro módulo +from packaging.version import parse +from pathlib import Path +import gradio + def limpar_temp_dir(): if shared.opts.clean_temp_dir_at_start: ui_tempdir.cleanup_tmpdr() startup_timer.record("cleanup temp dir") - def configurar_ui(): shared.demo = ui.create_ui() startup_timer.record("create ui") if not cmd_opts.no_gradio_queue: shared.demo.queue(64) - def decidir_autolancamento(): if os.getenv('SD_WEBUI_RESTARTING') == '1': return False @@ -20,10 +37,8 @@ def decidir_autolancamento(): return not cmd_opts.webui_is_non_local return False - def lancar_interface(auto_launch_browser): gradio_auth_creds = list(initialize_util.get_gradio_auth_creds()) or None - return shared.demo.launch( share=cmd_opts.share, server_name=initialize_util.gradio_server_name(), @@ -40,14 +55,12 @@ def lancar_interface(auto_launch_browser): root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else "", ) - def proteger_app(app): app.user_middleware = [ x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware' ] initialize_util.setup_middleware(app) - def configurar_apis(app): progress.setup_progress_api(app) ui.setup_ui_api(app) @@ -55,7 +68,6 @@ def configurar_apis(app): create_api(app) ui_extra_networks.add_pages_to_demo(app) - def monitorar_comandos(): while True: server_command = shared.state.wait_for_server_command(timeout=5) @@ -65,29 +77,9 @@ def monitorar_comandos(): else: print(f"Unknown server command: {server_command}") - def warning_if_invalid_install_dir(): - """ - Shows a warning if the webui is installed under a path that contains a leading dot in any of its parent directories. - - Gradio '/file=' route will block access to files that have a leading dot in the path segments. - We use this route to serve files such as JavaScript and CSS to the webpage, - if those files are blocked, the webpage will not function properly. - See https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/13292 - - This is a security feature was added to Gradio 3.32.0 and is removed in later versions, - this function replicates Gradio file access blocking logic. - - This check should be removed when it's no longer applicable. - """ - from packaging.version import parse - from pathlib import Path - import gradio - if parse('3.32.0') <= parse(gradio.__version__) < parse('4'): - def abspath(path): - """modified from Gradio 3.41.2 gradio.utils.abspath()""" if path.is_absolute(): return path is_symlink = path.is_symlink() or any(parent.is_symlink() for parent in path.parents) @@ -103,16 +95,12 @@ def abspath(path): For more information see: https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/13292 {"!"*25} Warning {"!"*25}''') - def webui(): initialize.initialize() - from modules import shared, ui_tempdir, script_callbacks, ui, progress, ui_extra_networks + warning_if_invalid_install_dir() -warning_if_invalid_install_dir() - -while True: - limpar_temp_dir() - + while True: + limpar_temp_dir() script_callbacks.before_ui_callback() startup_timer.record("scripts before_ui_callback") From 0e75f96b3486c0d4f8a94f1b5cccfee92e7efced Mon Sep 17 00:00:00 2001 From: Lucas Santos <100425690+lucassantos540@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:28:45 -0300 Subject: [PATCH 3/8] Update webui.py --- webui.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/webui.py b/webui.py index d9e1ef6af4b..c1b41516808 100644 --- a/webui.py +++ b/webui.py @@ -1,5 +1,9 @@ import os import time +from pathlib import Path +from packaging.version import parse +import gradio + from modules import ( shared, ui_tempdir, @@ -10,24 +14,26 @@ ui_extra_networks, timer, initialize, - script_callbacks + script_callbacks, + cmd_opts ) -from api import create_api # ajuste se create_api for de outro módulo -from packaging.version import parse -from pathlib import Path -import gradio + +from api import create_api + def limpar_temp_dir(): if shared.opts.clean_temp_dir_at_start: ui_tempdir.cleanup_tmpdr() startup_timer.record("cleanup temp dir") + def configurar_ui(): shared.demo = ui.create_ui() startup_timer.record("create ui") if not cmd_opts.no_gradio_queue: shared.demo.queue(64) + def decidir_autolancamento(): if os.getenv('SD_WEBUI_RESTARTING') == '1': return False @@ -37,6 +43,7 @@ def decidir_autolancamento(): return not cmd_opts.webui_is_non_local return False + def lancar_interface(auto_launch_browser): gradio_auth_creds = list(initialize_util.get_gradio_auth_creds()) or None return shared.demo.launch( @@ -55,12 +62,14 @@ def lancar_interface(auto_launch_browser): root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else "", ) + def proteger_app(app): app.user_middleware = [ x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware' ] initialize_util.setup_middleware(app) + def configurar_apis(app): progress.setup_progress_api(app) ui.setup_ui_api(app) @@ -68,6 +77,7 @@ def configurar_apis(app): create_api(app) ui_extra_networks.add_pages_to_demo(app) + def monitorar_comandos(): while True: server_command = shared.state.wait_for_server_command(timeout=5) @@ -77,6 +87,7 @@ def monitorar_comandos(): else: print(f"Unknown server command: {server_command}") + def warning_if_invalid_install_dir(): if parse('3.32.0') <= parse(gradio.__version__) < parse('4'): def abspath(path): @@ -90,11 +101,12 @@ def abspath(path): print(f'''{"!"*25} Warning {"!"*25} WebUI is installed in a directory that has a leading dot (.) in one of its parent directories. This will prevent WebUI from functioning properly. -Please move the installation to a different directory. Current path: "{webui_root}" -For more information see: https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/13292 +Please move the installation to a different directory. +More info: https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/13292 {"!"*25} Warning {"!"*25}''') + def webui(): initialize.initialize() warning_if_invalid_install_dir() @@ -142,3 +154,7 @@ def webui(): script_callbacks.script_unloaded_callback() startup_timer.record("scripts unloaded callback") initialize.initialize_rest(reload_script_modules=True) + + +if __name__ == "__main__": + webui() From 9ebf1306949be814d5d048b1664ba52ec7ed9223 Mon Sep 17 00:00:00 2001 From: Lucas Santos <100425690+lucassantos540@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:37:27 -0300 Subject: [PATCH 4/8] Create test.yml --- .github/workflows/test.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000000..640bb6a3490 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,37 @@ +name: Test WebUI Startup + +on: [pull_request, push] + +jobs: + test-webui: + runs-on: ubuntu-latest + + steps: + - name: Checkout código + uses: actions/checkout@v3 + + - name: Instalar dependências + run: | + sudo apt-get update + sudo apt-get install -y libgl1-mesa-glx wait-for-it curl + python -m venv venv + source venv/bin/activate + pip install -r requirements.txt || true # use requirements.txt se existir + + - name: Iniciar servidor WebUI + run: | + source venv/bin/activate + nohup python webui.py > log.txt 2>&1 & + + - name: Esperar servidor iniciar + run: | + chmod +x wait-for-it.sh || true + wait-for-it --timeout=20 127.0.0.1:7860 + + - name: Testar API (opcional) + run: | + curl -X POST http://127.0.0.1:7860/sdapi/v1/server-stop || true + + - name: Mostrar log do servidor + run: | + cat log.txt || true From 7c80f2191ef7ec9b6a34d272f6378d6cf3b179a1 Mon Sep 17 00:00:00 2001 From: Lucas Santos <100425690+lucassantos540@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:39:16 -0300 Subject: [PATCH 5/8] Update test.yml --- .github/workflows/test.yml | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 640bb6a3490..7347df16822 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,37 +1,41 @@ name: Test WebUI Startup -on: [pull_request, push] +on: [push, pull_request] jobs: test-webui: runs-on: ubuntu-latest steps: - - name: Checkout código + - name: Checkout do código uses: actions/checkout@v3 - - name: Instalar dependências + - name: Instalar dependências de sistema run: | sudo apt-get update - sudo apt-get install -y libgl1-mesa-glx wait-for-it curl - python -m venv venv + sudo apt-get install -y python3-venv curl + + - name: Configurar ambiente virtual e dependências Python + run: | + python3 -m venv venv source venv/bin/activate - pip install -r requirements.txt || true # use requirements.txt se existir + pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Iniciar servidor WebUI + - name: Iniciar WebUI em background run: | source venv/bin/activate nohup python webui.py > log.txt 2>&1 & - + - name: Esperar servidor iniciar run: | - chmod +x wait-for-it.sh || true - wait-for-it --timeout=20 127.0.0.1:7860 + sleep 20 + curl -sf http://127.0.0.1:7860 || (echo "Servidor não respondeu" && cat log.txt && exit 1) - - name: Testar API (opcional) + - name: Encerrar servidor (se rodando) run: | curl -X POST http://127.0.0.1:7860/sdapi/v1/server-stop || true - - name: Mostrar log do servidor + - name: Mostrar log final do servidor run: | cat log.txt || true From 5fd26f9497be018e4f933b1e44c6d3b33fb19d05 Mon Sep 17 00:00:00 2001 From: Lucas Santos <100425690+lucassantos540@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:43:17 -0300 Subject: [PATCH 6/8] Update test.yml --- .github/workflows/test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7347df16822..8712cd0917d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,3 +39,7 @@ jobs: - name: Mostrar log final do servidor run: | cat log.txt || true + + - name: Mostrar log final do servidor + run: cat log.txt || true + From 593c918491af6f9309a6031b91d012c0f97c2ef2 Mon Sep 17 00:00:00 2001 From: Lucas Santos <100425690+lucassantos540@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:49:48 -0300 Subject: [PATCH 7/8] Update test.yml --- .github/workflows/test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8712cd0917d..0222ddc0e6b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,6 +40,7 @@ jobs: run: | cat log.txt || true - - name: Mostrar log final do servidor - run: cat log.txt || true + - name: Rodar webui e salvar log + run: | + python webui.py > log.txt 2>&1 From 830f57dad6daff93453c0017a1a6d1a27a167bd7 Mon Sep 17 00:00:00 2001 From: Lucas Santos <100425690+lucassantos540@users.noreply.github.com> Date: Wed, 25 Jun 2025 21:51:04 -0300 Subject: [PATCH 8/8] Update test.yml --- .github/workflows/test.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0222ddc0e6b..f93b888dd68 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,11 +36,10 @@ jobs: run: | curl -X POST http://127.0.0.1:7860/sdapi/v1/server-stop || true - - name: Mostrar log final do servidor - run: | - cat log.txt || true - - name: Rodar webui e salvar log run: | python webui.py > log.txt 2>&1 + - name: Mostrar log final do servidor + run: | + cat log.txt || true