automatic/modules/api/options.py

95 lines
3.9 KiB
Python

from typing import Any
from modules.shared import opts
def get_options():
options = {}
for k in opts.data.keys():
if opts.data_labels.get(k) is not None:
options.update({k: opts.data.get(k, opts.data_labels.get(k).default)})
else:
options.update({k: opts.data.get(k, None)})
if "sd_lyco" in options:
del options["sd_lyco"]
if "sd_lora" in options:
del options["sd_lora"]
return options
def set_options(req: dict[str, Any]):
updated = []
for k, v in req.items():
updated.append({k: opts.set(k, v)})
opts.save()
return {"updated": updated}
def get_options_info():
"""
Return metadata for all application settings.
Returns every registered option with its label, section, type, default value,
component kind (slider, switch, dropdown, etc.), and component args (min/max/step/choices).
Used by alternative UIs to dynamically build a settings editor.
"""
import re
import gradio as gr
from modules.shared_legacy import LegacyOption
from modules.ui_components import DropdownEditable
component_map = {
gr.Slider: "slider",
gr.Checkbox: "switch",
gr.Radio: "radio",
gr.Dropdown: "dropdown",
gr.Textbox: "input",
gr.Number: "number",
gr.ColorPicker: "color",
gr.CheckboxGroup: "checkboxgroup",
gr.HTML: "separator",
}
options_info = {}
sections_seen = {}
for key, info in opts.data_labels.items():
section_id = info.section[0] if info.section else None
section_title = info.section[1] if info.section and len(info.section) > 1 else ""
hidden = section_id is None or "hidden" in (section_id or "").lower() or "hidden" in section_title.lower()
if section_id and section_id not in sections_seen:
sections_seen[section_id] = {"id": section_id, "title": section_title, "hidden": hidden}
if hidden:
args = {}
else:
try:
args = info.component_args() if callable(info.component_args) else (info.component_args or {})
except Exception:
args = {}
comp_name = component_map.get(info.component, "input")
if info.component is DropdownEditable:
comp_name = "dropdown"
elif info.component is None:
comp_name = "switch" if isinstance(info.default, bool) else "number" if isinstance(info.default, (int, float)) else "input"
visible = args.get("visible", True) and (comp_name == "separator" or len(info.label) > 2)
serializable_args = {}
for arg_key in ("minimum", "maximum", "step", "choices", "precision", "multiselect"):
if arg_key in args:
serializable_args[arg_key] = args[arg_key]
label = info.label
if comp_name == "separator" and not label and isinstance(info.default, str):
label = re.sub(r"<[^>]+>", "", info.default).strip()
options_info[key] = {
"label": label,
"section_id": section_id,
"section_title": section_title,
"visible": visible,
"hidden": hidden,
"type": "boolean" if isinstance(info.default, bool) else "number" if isinstance(info.default, (int, float)) else "array" if isinstance(info.default, list) else "string",
"component": comp_name,
"component_args": serializable_args,
"default": info.default,
"is_legacy": isinstance(info, LegacyOption),
"is_secret": getattr(info, "secret", False),
}
return {"options": options_info, "sections": list(sections_seen.values())}
def register_api(app):
app.add_api_route("/sdapi/v1/options", get_options, methods=["GET"], response_model=dict, tags=["Server"])
app.add_api_route("/sdapi/v1/options", set_options, methods=["POST"], tags=["Server"])
app.add_api_route("/sdapi/v1/options-info", get_options_info, methods=["GET"], tags=["Server"])