Commit f6fc7916 authored by AUTOMATIC's avatar AUTOMATIC
Browse files

add /sdapi/v1/script-info api

parent 8fe9ea7f
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -204,6 +204,7 @@ class Api:
        self.add_api_route("/sdapi/v1/unload-checkpoint", self.unloadapi, methods=["POST"])
        self.add_api_route("/sdapi/v1/reload-checkpoint", self.reloadapi, methods=["POST"])
        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.default_script_arg_txt2img = []
        self.default_script_arg_img2img = []
@@ -229,11 +230,19 @@ class Api:
        return script, script_idx

    def get_scripts_list(self):
        t2ilist = [str(title.lower()) for title in scripts.scripts_txt2img.titles]
        i2ilist = [str(title.lower()) for title in scripts.scripts_img2img.titles]
        t2ilist = [script.name for script in scripts.scripts_txt2img.scripts if script.name is not None]
        i2ilist = [script.name for script in scripts.scripts_img2img.scripts if script.name is not None]

        return models.ScriptsList(txt2img=t2ilist, img2img=i2ilist)

    def get_script_info(self):
        res = []

        for script_list in [scripts.scripts_txt2img.scripts, scripts.scripts_img2img.scripts]:
            res += [script.api_info for script in script_list if script.api_info is not None]

        return res

    def get_script(self, script_name, script_runner):
        if script_name is None or script_name == "":
            return None, None
+19 −2
Original line number Diff line number Diff line
@@ -287,6 +287,23 @@ class MemoryResponse(BaseModel):
    ram: dict = Field(title="RAM", description="System memory stats")
    cuda: dict = Field(title="CUDA", description="nVidia CUDA memory stats")


class ScriptsList(BaseModel):
    txt2img: list = Field(default=None, title="Txt2img", description="Titles of scripts (txt2img)")
    img2img: list = Field(default=None, title="Img2img", description="Titles of scripts (img2img)")


class ScriptArg(BaseModel):
    label: str = Field(default=None, title="Label", description="Name of the argument in UI")
    value: Optional[Any] = Field(default=None, title="Value", description="Default value of the argument")
    minimum: Optional[Any] = Field(default=None, title="Minimum", description="Minimum allowed value for the argumentin UI")
    maximum: Optional[Any] = Field(default=None, title="Minimum", description="Maximum allowed value for the argumentin UI")
    step: Optional[Any] = Field(default=None, title="Minimum", description="Step for changing value of the argumentin UI")
    choices: Optional[List[str]] = Field(default=None, title="Choices", description="Possible values for the argument")


class ScriptInfo(BaseModel):
    name: str = Field(default=None, title="Name", description="Script name")
    is_alwayson: bool = Field(default=None, title="IsAlwayson", description="Flag specifying whether this script is an alwayson script")
    is_img2img: bool = Field(default=None, title="IsImg2img", description="Flag specifying whether this script is an img2img script")
    args: List[ScriptArg] = Field(title="Arguments", description="List of script's arguments")
+28 −1
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@ class PostprocessImageArgs:


class Script:
    name = None
    """script's internal name derived from title"""

    filename = None
    args_from = None
    args_to = None
@@ -25,8 +28,8 @@ class Script:
    is_txt2img = False
    is_img2img = False

    """A gr.Group component that has all script's UI inside it"""
    group = None
    """A gr.Group component that has all script's UI inside it"""

    infotext_fields = None
    """if set in ui(), this is a list of pairs of gradio component + text; the text will be used when
@@ -38,6 +41,9 @@ class Script:
    various "Send to <X>" buttons when clicked
    """

    api_info = None
    """Generated value of type modules.api.models.ScriptInfo with information about the script for API"""

    def title(self):
        """this function should return the title of the script. This is what will be displayed in the dropdown menu."""

@@ -313,6 +319,8 @@ class ScriptRunner:
                self.selectable_scripts.append(script)

    def setup_ui(self):
        import modules.api.models as api_models

        self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts]

        inputs = [None]
@@ -327,9 +335,28 @@ class ScriptRunner:
            if controls is None:
                return

            script.name = wrap_call(script.title, script.filename, "title", default=script.filename).lower()
            api_args = []

            for control in controls:
                control.custom_script_source = os.path.basename(script.filename)

                arg_info = api_models.ScriptArg(label=control.label or "")

                for field in ("value", "minimum", "maximum", "step", "choices"):
                    v = getattr(control, field, None)
                    if v is not None:
                        setattr(arg_info, field, v)

                api_args.append(arg_info)

            script.api_info = api_models.ScriptInfo(
                name=script.name,
                is_img2img=script.is_img2img,
                is_alwayson=script.alwayson,
                args=api_args,
            )

            if script.infotext_fields is not None:
                self.infotext_fields += script.infotext_fields