Compare commits

..

2 Commits

Author SHA1 Message Date
w-e-w dc34c0041c fix shadows name 'k' from outer scope
while syntactically correct this triggers a false Unresolved reference 'k' error in PyCharms
2024-12-29 00:16:35 +09:00
w-e-w fc54833505 Authenticated Sysinfo 2024-12-29 00:16:35 +09:00
8 changed files with 81 additions and 57 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
<div>
<a href="{api_docs}" target="_blank">API</a>
<a href="{api_docs}">API</a>
 • 
<a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui">GitHub</a>
 • 
+36
View File
@@ -69,3 +69,39 @@ onOptionsChanged(function() {
});
});
function downloadSysinfo() {
const pad = (n) => String(n).padStart(2, '0');
const now = new Date();
const YY = now.getFullYear();
const MM = pad(now.getMonth() + 1);
const DD = pad(now.getDate());
const HH = pad(now.getHours());
const mm = pad(now.getMinutes());
const link = document.createElement('a');
link.download = `sysinfo-${YY}-${MM}-${DD}-${HH}-${mm}.json`;
const sysinfo_textbox = gradioApp().querySelector('#internal-sysinfo-textbox textarea');
const content = sysinfo_textbox.value;
if (content.startsWith('file=')) {
link.href = content;
} else {
const blob = new Blob([content], {type: 'application/json'});
link.href = URL.createObjectURL(blob);
}
link.click();
sysinfo_textbox.value = '';
updateInput(sysinfo_textbox);
}
function openTabSysinfo() {
const sysinfo_textbox = gradioApp().querySelector('#internal-sysinfo-textbox textarea');
const content = sysinfo_textbox.value;
if (content.startsWith('file=')) {
window.open(content, '_blank');
} else {
const blob = new Blob([content], {type: 'application/json'});
const url = URL.createObjectURL(blob);
window.open(url, '_blank');
}
sysinfo_textbox.value = '';
updateInput(sysinfo_textbox);
}
+4 -1
View File
@@ -17,7 +17,7 @@ from fastapi.encoders import jsonable_encoder
from secrets import compare_digest
import modules.shared as shared
from modules import sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing, errors, restart, shared_items, script_callbacks, infotext_utils, sd_models, sd_schedulers
from modules import sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing, errors, restart, shared_items, script_callbacks, infotext_utils, sd_models, sd_schedulers, sysinfo
from modules.api import models
from modules.shared import opts
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
@@ -33,6 +33,7 @@ import piexif.helper
from contextlib import closing
from modules.progress import create_task_id, add_task_to_queue, start_task, finish_task, current_task
def script_name_to_index(name, scripts):
try:
return [script.title().lower() for script in scripts].index(name.lower())
@@ -244,6 +245,8 @@ class Api:
self.add_api_route("/sdapi/v1/scripts", self.get_scripts_list, methods=["GET"], response_model=models.ScriptsList)
self.add_api_route("/sdapi/v1/script-info", self.get_script_info, methods=["GET"], response_model=list[models.ScriptInfo])
self.add_api_route("/sdapi/v1/extensions", self.get_extensions_list, methods=["GET"], response_model=list[models.ExtensionItem])
self.add_api_route("/internal/sysinfo", sysinfo.download_sysinfo, methods=["GET"])
self.add_api_route("/internal/sysinfo-download", lambda: sysinfo.download_sysinfo(attachment=True), methods=["GET"])
if shared.cmd_opts.api_server_stop:
self.add_api_route("/sdapi/v1/server-kill", self.kill_webui, methods=["POST"])
-1
View File
@@ -50,7 +50,6 @@ def check_versions():
def initialize():
from modules import initialize_util
initialize_util.allow_add_middleware_after_start()
initialize_util.fix_torch_version()
initialize_util.fix_pytorch_lightning()
initialize_util.fix_asyncio_event_loop_policy()
+3 -37
View File
@@ -5,8 +5,6 @@ import sys
import re
from modules.timer import startup_timer
from modules import patches
from functools import wraps
def gradio_server_name():
@@ -193,8 +191,11 @@ def configure_opts_onchange():
def setup_middleware(app):
from starlette.middleware.gzip import GZipMiddleware
app.middleware_stack = None # reset current middleware to allow modifying user provided list
app.add_middleware(GZipMiddleware, minimum_size=1000)
configure_cors_middleware(app)
app.build_middleware_stack() # rebuild middleware stack on-the-fly
def configure_cors_middleware(app):
@@ -212,38 +213,3 @@ def configure_cors_middleware(app):
cors_options["allow_origin_regex"] = cmd_opts.cors_allow_origins_regex
app.add_middleware(CORSMiddleware, **cors_options)
def allow_add_middleware_after_start():
from starlette.applications import Starlette
def add_middleware_wrapper(func):
"""Patch Starlette.add_middleware to allow for middleware to be added after the app has started
Starlette.add_middleware raises RuntimeError("Cannot add middleware after an application has started") if middleware_stack is not None.
We can force add new middleware by first setting middleware_stack to None, then adding the middleware.
When middleware_stack is None, it will rebuild the middleware_stack on the next request (Lazily build middleware stack).
If packages are updated in the future, things may break, so we have two ways to add middleware after the app has started:
the first way is to just set middleware_stack to None and then retry
the second manually insert the middleware into the user_middleware list without calling add_middleware
"""
@wraps(func)
def wrapper(self, *args, **kwargs):
res = None
try:
res = func(self, *args, **kwargs)
except RuntimeError as _:
try:
self.middleware_stack = None
res = func(self, *args, **kwargs)
except RuntimeError as e:
print(f'Warning: "{e}", Retrying...')
from starlette.middleware import Middleware
self.user_middleware.insert(0, Middleware(*args, **kwargs))
self.middleware_stack = None # ensure middleware_stack in the event of concurrent requests
return res
return wrapper
patches.patch(__name__, obj=Starlette, field="add_middleware", replacement=add_middleware_wrapper(Starlette.add_middleware))
+10
View File
@@ -213,3 +213,13 @@ def get_config():
return json.load(f)
except Exception as e:
return str(e)
def download_sysinfo(attachment=False):
from fastapi.responses import PlainTextResponse
from datetime import datetime
text = get()
filename = f"sysinfo-{datetime.utcnow().strftime('%Y-%m-%d-%H-%M')}.json"
return PlainTextResponse(text, headers={'Content-Disposition': f'{"attachment" if attachment else "inline"}; filename="{filename}"'})
+2 -14
View File
@@ -1,4 +1,3 @@
import datetime
import mimetypes
import os
import sys
@@ -10,10 +9,10 @@ import gradio as gr
import gradio.utils
import numpy as np
from PIL import Image, PngImagePlugin # noqa: F401
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call, wrap_gradio_call_no_job # noqa: F401
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call, wrap_gradio_call_no_job # noqa: F401
from modules import gradio_extensons, sd_schedulers # noqa: F401
from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, shared_items, ui_settings, timer, sysinfo, ui_checkpoint_merger, scripts, sd_samplers, processing, ui_extra_networks, ui_toprow, launch_utils
from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, shared_items, ui_settings, timer, ui_checkpoint_merger, scripts, sd_samplers, processing, ui_extra_networks, ui_toprow, launch_utils
from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML, InputAccordion, ResizeHandleRow
from modules.paths import script_path
from modules.ui_common import create_refresh_button
@@ -1223,16 +1222,5 @@ def setup_ui_api(app):
app.add_api_route("/internal/profile-startup", lambda: timer.startup_record, methods=["GET"])
def download_sysinfo(attachment=False):
from fastapi.responses import PlainTextResponse
text = sysinfo.get()
filename = f"sysinfo-{datetime.datetime.utcnow().strftime('%Y-%m-%d-%H-%M')}.json"
return PlainTextResponse(text, headers={'Content-Disposition': f'{"attachment" if attachment else "inline"}; filename="{filename}"'})
app.add_api_route("/internal/sysinfo", download_sysinfo, methods=["GET"])
app.add_api_route("/internal/sysinfo-download", lambda: download_sysinfo(attachment=True), methods=["GET"])
import fastapi.staticfiles
app.mount("/webui-assets", fastapi.staticfiles.StaticFiles(directory=launch_utils.repo_dir('stable-diffusion-webui-assets')), name="webui-assets")
+25 -3
View File
@@ -1,12 +1,13 @@
import gradio as gr
from modules import ui_common, shared, script_callbacks, scripts, sd_models, sysinfo, timer, shared_items
from modules import ui_common, shared, script_callbacks, scripts, sd_models, sysinfo, timer, shared_items, paths_internal, util
from modules.call_queue import wrap_gradio_call_no_job
from modules.options import options_section
from modules.shared import opts
from modules.ui_components import FormRow
from modules.ui_gradio_extensions import reload_javascript
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
def get_value_for_setting(key):
@@ -170,7 +171,28 @@ class UiSettings:
loadsave.create_ui()
with gr.TabItem("Sysinfo", id="sysinfo", elem_id="settings_tab_sysinfo"):
gr.HTML('<a href="./internal/sysinfo-download" class="sysinfo_big_link" download>Download system info</a><br /><a href="./internal/sysinfo" target="_blank">(or open as text in a new page)</a>', elem_id="sysinfo_download")
download_sysinfo = gr.Button(value='Download system info', elem_id="internal-download-sysinfo", visible=False)
open_sysinfo = gr.Button(value='Open as text in a new page', elem_id="internal-open-sysinfo", visible=False)
sysinfo_html = gr.HTML('''<a class="sysinfo_big_link" onclick="gradioApp().getElementById('internal-download-sysinfo').click();">Download system info</a><br/><a onclick="gradioApp().getElementById('internal-open-sysinfo').click();">(or open as text in a new page)</a>''', elem_id="sysinfo_download")
sysinfo_textbox = gr.Textbox(label='Sysinfo textarea', elem_id="internal-sysinfo-textbox", visible=False)
def create_sysinfo():
sysinfo_str = sysinfo.get()
if len(sysinfo_utf8 := sysinfo_str.encode('utf8')) > 2 ** 20: # 1MB
sysinfo_path = Path(paths_internal.script_path) / 'tmp' / 'sysinfo.json'
sysinfo_path.parent.mkdir(parents=True, exist_ok=True)
sysinfo_path.write_bytes(sysinfo_utf8)
return gr.update(), gr.update(value=f'file={util.truncate_path(sysinfo_path)}')
return gr.update(), gr.update(value=sysinfo_str)
download_sysinfo.click(
fn=create_sysinfo, outputs=[sysinfo_html, sysinfo_textbox], show_progress=True).success(
fn=None, _js='downloadSysinfo'
)
open_sysinfo.click(
fn=create_sysinfo, outputs=[sysinfo_html, sysinfo_textbox], show_progress=True).success(
fn=None, _js='openTabSysinfo'
)
with gr.Row():
with gr.Column(scale=1):
@@ -313,7 +335,7 @@ class UiSettings:
for method in methods:
method(
fn=lambda value, k=k: self.run_settings_single(value, key=k),
fn=lambda value, key=k: self.run_settings_single(value, key=key),
inputs=[component],
outputs=[component, self.text_settings],
show_progress=info.refresh is not None,