add minimal webuiapi node
This commit is contained in:
+73
@@ -0,0 +1,73 @@
|
||||
from .autonode import node_wrapper, get_node_names_mappings, validate, anytype
|
||||
from .imgio.converter import PILHandlingHodes
|
||||
from .webuiapi.out_api import get_image_from_prompt, get_image_from_prompt_fallback
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
external_classes = []
|
||||
external_nodes = node_wrapper(external_classes)
|
||||
|
||||
|
||||
@external_nodes
|
||||
|
||||
class SDWebuiAPINode:
|
||||
FUNCTION = "get_image_from_prompt"
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"prompt": ("STRING", {"default": ""}),
|
||||
"api_endpoint": ("STRING", {"default": ""}),
|
||||
},
|
||||
"optional": {
|
||||
"auth": ("STRING", {"default": ""}),
|
||||
"seed": ("INT", {"default": -1}),
|
||||
"negative_prompt": ("STRING", {"default": ""}),
|
||||
"steps": ("INT", {"default": 28}),
|
||||
"width": ("INT", {"default": 1024}),
|
||||
"height": ("INT", {"default": 1024}),
|
||||
"hr_scale": ("FLOAT", {"default": 1.5}),
|
||||
"hr_upscale": ("STRING", {"default": "Latent"}),
|
||||
"enable_hr": ("BOOL", {"default": False}),
|
||||
"cfg_scale": ("INT", {"default": 7}),
|
||||
}
|
||||
}
|
||||
CATEGORY = "WebUI API"
|
||||
custom_name = "Get Image From Prompt"
|
||||
@PILHandlingHodes.output_wrapper
|
||||
def get_image_from_prompt(self, prompt, api_endpoint, auth="", seed=-1, negative_prompt="", steps=28, width=1024, height=1024, hr_scale=1.5, hr_upscale="Latent", enable_hr=False, cfg_scale=7):
|
||||
return (get_image_from_prompt(prompt, api_endpoint, auth, seed, negative_prompt, steps, width, height, hr_scale, hr_upscale, enable_hr, cfg_scale)[0],)
|
||||
@external_nodes
|
||||
class SDWebuiAPIFallbackNode:
|
||||
FUNCTION = "get_image_from_prompt_fallback"
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"prompt": ("STRING", {"default": ""}),
|
||||
"api_endpoint": ("STRING", {"default": ""}),
|
||||
},
|
||||
"optional": {
|
||||
"auth": ("STRING", {"default": ""}),
|
||||
"seed": ("INT", {"default": -1}),
|
||||
"negative_prompt": ("STRING", {"default": ""}),
|
||||
"steps": ("INT", {"default": 28}),
|
||||
"width": ("INT", {"default": 1024}),
|
||||
"height": ("INT", {"default": 1024}),
|
||||
"hr_scale": ("FLOAT", {"default": 1.5}),
|
||||
"hr_upscale": ("STRING", {"default": "Latent"}),
|
||||
"enable_hr": ("BOOL", {"default": False}),
|
||||
"cfg_scale": ("INT", {"default": 7}),
|
||||
}
|
||||
}
|
||||
CATEGORY = "WebUI API"
|
||||
custom_name = "Get Image From Prompt (Fallback)"
|
||||
@PILHandlingHodes.output_wrapper
|
||||
def get_image_from_prompt_fallback(self, prompt, api_endpoint, auth="", seed=-1, negative_prompt="", steps=28, width=1024, height=1024, hr_scale=1.5, hr_upscale="Latent", enable_hr=False, cfg_scale=7):
|
||||
return (get_image_from_prompt_fallback(prompt, api_endpoint, auth, seed, negative_prompt, steps, width, height, hr_scale, hr_upscale, enable_hr, cfg_scale)[0],)
|
||||
|
||||
CLASS_MAPPINGS, CLASS_NAMES = get_node_names_mappings(external_classes)
|
||||
validate(external_classes)
|
||||
@@ -1,24 +1,28 @@
|
||||
|
||||
from .logic_gates import CLASS_MAPPINGS as LogicMapping, CLASS_NAMES as LogicNames
|
||||
from .randomness import CLASS_MAPPINGS as RandomMapping, CLASS_NAMES as RandomNames
|
||||
from .conversion import CLASS_MAPPINGS as ConversionMapping, CLASS_NAMES as ConversionNames
|
||||
from .math_nodes import CLASS_MAPPINGS as MathMapping, CLASS_NAMES as MathNames
|
||||
from .io_node import CLASS_MAPPINGS as IOMapping, CLASS_NAMES as IONames
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
}
|
||||
NODE_CLASS_MAPPINGS.update(IOMapping)
|
||||
NODE_CLASS_MAPPINGS.update(LogicMapping)
|
||||
NODE_CLASS_MAPPINGS.update(RandomMapping)
|
||||
NODE_CLASS_MAPPINGS.update(ConversionMapping)
|
||||
NODE_CLASS_MAPPINGS.update(MathMapping)
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
|
||||
}
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(IONames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(LogicNames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(RandomNames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(ConversionNames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(MathNames)
|
||||
|
||||
from .logic_gates import CLASS_MAPPINGS as LogicMapping, CLASS_NAMES as LogicNames
|
||||
from .randomness import CLASS_MAPPINGS as RandomMapping, CLASS_NAMES as RandomNames
|
||||
from .conversion import CLASS_MAPPINGS as ConversionMapping, CLASS_NAMES as ConversionNames
|
||||
from .math_nodes import CLASS_MAPPINGS as MathMapping, CLASS_NAMES as MathNames
|
||||
from .io_node import CLASS_MAPPINGS as IOMapping, CLASS_NAMES as IONames
|
||||
|
||||
from .external import CLASS_MAPPINGS as ExternalMapping, CLASS_NAMES as ExternalNames
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
}
|
||||
NODE_CLASS_MAPPINGS.update(IOMapping)
|
||||
NODE_CLASS_MAPPINGS.update(LogicMapping)
|
||||
NODE_CLASS_MAPPINGS.update(RandomMapping)
|
||||
NODE_CLASS_MAPPINGS.update(ConversionMapping)
|
||||
NODE_CLASS_MAPPINGS.update(MathMapping)
|
||||
NODE_CLASS_MAPPINGS.update(ExternalMapping)
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
|
||||
}
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(IONames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(LogicNames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(RandomNames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(ConversionNames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(MathNames)
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(ExternalNames)
|
||||
@@ -0,0 +1,112 @@
|
||||
import requests
|
||||
import json
|
||||
from PIL import Image
|
||||
import io
|
||||
import base64
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def send_request(api_endpoint:str, auth:Optional[str], arguments:dict) -> list[Image.Image]:
|
||||
session = requests.Session()
|
||||
if auth:
|
||||
session.auth = (auth.split(":")[0], auth.split(":")[1])
|
||||
api_endpoint = api_endpoint.rstrip("/") + "/sdapi/v1/txt2img"
|
||||
response = session.post(api_endpoint, json=arguments)
|
||||
response.raise_for_status()
|
||||
response_json = response.json()
|
||||
if "images" in response_json.keys():
|
||||
images = [Image.open(io.BytesIO(base64.b64decode(i))) for i in response_json["images"]]
|
||||
elif "image" in response_json.keys():
|
||||
images = [Image.open(io.BytesIO(base64.b64decode(response_json["image"])))]
|
||||
else:
|
||||
raise ValueError("No image data in response")
|
||||
return images
|
||||
|
||||
def construct_args(
|
||||
prompt:str,
|
||||
seed:int=-1,
|
||||
negative_prompt:Optional[str] = None,
|
||||
steps:int = 28,
|
||||
width:int = 1024,
|
||||
height:int = 1024,
|
||||
hr_scale:float = 1.5,
|
||||
hr_upscale:str = "Latent",
|
||||
enable_hr:bool = False,
|
||||
cfg_scale:int = 7,
|
||||
):
|
||||
arguments = {
|
||||
"prompt": prompt,
|
||||
"seed": seed,
|
||||
"steps": steps,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"hr_scale": hr_scale,
|
||||
"hr_upscale": hr_upscale,
|
||||
"enable_hr": enable_hr,
|
||||
"cfg_scale": cfg_scale,
|
||||
}
|
||||
if negative_prompt:
|
||||
arguments["negative_prompt"] = negative_prompt
|
||||
else:
|
||||
arguments["negative_prompt"] = ""
|
||||
return arguments
|
||||
|
||||
def get_image_from_prompt(
|
||||
prompt:str,
|
||||
api_endpoint:str,
|
||||
auth:Optional[str]=None,
|
||||
seed:int=-1,
|
||||
negative_prompt:Optional[str] = None,
|
||||
steps:int = 28,
|
||||
width:int = 1024,
|
||||
height:int = 1024,
|
||||
hr_scale:float = 1.5,
|
||||
hr_upscale:str = "Latent",
|
||||
enable_hr:bool = False,
|
||||
cfg_scale:int = 7,
|
||||
):
|
||||
arguments = construct_args(
|
||||
prompt=prompt,
|
||||
seed=seed,
|
||||
negative_prompt=negative_prompt,
|
||||
steps=steps,
|
||||
width=width,
|
||||
height=height,
|
||||
hr_scale=hr_scale,
|
||||
hr_upscale=hr_upscale,
|
||||
enable_hr=enable_hr,
|
||||
cfg_scale=cfg_scale,
|
||||
)
|
||||
return send_request(api_endpoint, auth, arguments)
|
||||
|
||||
def get_image_from_prompt_fallback(
|
||||
prompt:str,
|
||||
api_endpoint:str,
|
||||
auth:Optional[str]=None,
|
||||
seed:int=-1,
|
||||
negative_prompt:Optional[str] = None,
|
||||
steps:int = 28,
|
||||
width:int = 1024,
|
||||
height:int = 1024,
|
||||
hr_scale:float = 1.5,
|
||||
hr_upscale:str = "Latent",
|
||||
enable_hr:bool = False,
|
||||
cfg_scale:int = 7,
|
||||
):
|
||||
arguments = construct_args(
|
||||
prompt=prompt,
|
||||
seed=seed,
|
||||
negative_prompt=negative_prompt,
|
||||
steps=steps,
|
||||
width=width,
|
||||
height=height,
|
||||
hr_scale=hr_scale,
|
||||
hr_upscale=hr_upscale,
|
||||
enable_hr=enable_hr,
|
||||
cfg_scale=cfg_scale,
|
||||
)
|
||||
try:
|
||||
return send_request(api_endpoint, auth, arguments)
|
||||
except Exception as e:
|
||||
# create blank image
|
||||
return [Image.new("RGB", (width, height), (255, 255, 255))]
|
||||
Reference in New Issue
Block a user