api validation

Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
Vladimir Mandic
2024-11-14 11:18:24 -05:00
parent 94b71003e0
commit 4f1c9cf5c7
7 changed files with 47 additions and 23 deletions
-4
View File
@@ -90,7 +90,3 @@ def create_redocs(app: FastAPI):
redoc_favicon_url='/file=html/favicon.svg',
)
return res
"""
https://github.com/Amoenus/SwaggerDark/blob/master/SwaggerDark.css
"""
+5 -2
View File
@@ -14,7 +14,7 @@ def validate_sampler_name(name):
return name
def decode_base64_to_image(encoding):
def decode_base64_to_image(encoding, quiet=False):
if encoding.startswith("data:image/"):
encoding = encoding.split(";")[1].split(",")[1]
try:
@@ -22,7 +22,10 @@ def decode_base64_to_image(encoding):
return image
except Exception as e:
shared.log.warning(f'API cannot decode image: {e}')
raise HTTPException(status_code=500, detail="Invalid encoded image") from e
if not quiet:
raise HTTPException(status_code=500, detail="Invalid encoded image") from e
else:
return None
def encode_pil_to_base64(image):
+9 -3
View File
@@ -194,8 +194,10 @@ ReqTxt2Img = PydanticModelGenerator(
"StableDiffusionProcessingTxt2Img",
StableDiffusionProcessingTxt2Img,
[
{"key": "sampler_index", "type": str, "default": "UniPC"},
{"key": "script_name", "type": str, "default": None},
{"key": "sampler_index", "type": int, "default": 0},
{"key": "sampler_name", "type": str, "default": "UniPC"},
{"key": "hr_sampler_name", "type": str, "default": "Same as primary"},
{"key": "script_name", "type": str, "default": "none"},
{"key": "script_args", "type": list, "default": []},
{"key": "send_images", "type": bool, "default": True},
{"key": "save_images", "type": bool, "default": False},
@@ -216,7 +218,11 @@ ReqImg2Img = PydanticModelGenerator(
"StableDiffusionProcessingImg2Img",
StableDiffusionProcessingImg2Img,
[
{"key": "sampler_index", "type": str, "default": "UniPC"},
{"key": "sampler_index", "type": int, "default": 0},
{"key": "sampler_name", "type": str, "default": "UniPC"},
{"key": "hr_sampler_name", "type": str, "default": "Same as primary"},
{"key": "script_name", "type": str, "default": "none"},
{"key": "script_args", "type": list, "default": []},
{"key": "init_images", "type": list, "default": None},
{"key": "denoising_strength", "type": float, "default": 0.5},
{"key": "mask", "type": str, "default": None},
+11 -2
View File
@@ -3,18 +3,25 @@ from fastapi.exceptions import HTTPException
import gradio as gr
from modules.api import models
from modules import scripts
from modules.errors import log
def script_name_to_index(name, scripts_list):
if name is None or len(name) == 0:
return None
try:
return [script.title().lower() for script in scripts_list].index(name.lower())
except Exception as e:
raise HTTPException(status_code=422, detail=f"Script '{name}' not found") from e
except Exception:
log.error(f'API: script={name} not found')
return None
# raise HTTPException(status_code=422, detail=f"Script '{name}' not found") from e
def get_selectable_script(script_name, script_runner):
if script_name is None or script_name == "":
return None, None
script_idx = script_name_to_index(script_name, script_runner.selectable_scripts)
if script_idx is None:
return None, None
script = script_runner.selectable_scripts[script_idx]
return script, script_idx
@@ -36,6 +43,8 @@ def get_script(script_name, script_runner):
if script_name is None or script_name == "":
return None, None
script_idx = script_name_to_index(script_name, script_runner.scripts)
if script_idx is None:
return None
return script_runner.scripts[script_idx]
def init_default_script_args(script_runner):
+4 -1
View File
@@ -6,9 +6,11 @@ import time
import inspect
import torch
import numpy as np
from PIL import Image
from modules import shared, errors, sd_models, processing, processing_vae, processing_helpers, sd_hijack_hypertile, prompt_parser_diffusers, timer
from modules.processing_callbacks import diffusers_callback_legacy, diffusers_callback, set_callbacks_p
from modules.processing_helpers import resize_hires, fix_prompts, calculate_base_steps, calculate_hires_steps, calculate_refiner_steps, get_generator, set_latents, apply_circular # pylint: disable=unused-import
from modules.api import helpers
debug = shared.log.trace if os.environ.get('SD_DIFFUSERS_DEBUG', None) is not None else lambda *args, **kwargs: None
@@ -18,7 +20,8 @@ def task_specific_kwargs(p, model):
task_args = {}
is_img2img_model = bool('Zero123' in shared.sd_model.__class__.__name__)
if len(getattr(p, 'init_images', [])) > 0:
p.init_images = [p.convert('RGB') for p in p.init_images]
p.init_images = [helpers.decode_base64_to_image(i, quiet=True) for i in p.init_images if isinstance(i, str)]
p.init_images = [i.convert('RGB') for i in p.init_images if isinstance(i, Image.Image)]
if sd_models.get_diffusers_task(model) == sd_models.DiffusersTaskType.TEXT_2_IMAGE or len(getattr(p, 'init_images', [])) == 0 and not is_img2img_model:
p.ops.append('txt2img')
if hasattr(p, 'width') and hasattr(p, 'height'):
+1 -1
View File
@@ -21,7 +21,7 @@ class StableDiffusionProcessing:
sd_model=None, # pylint: disable=unused-argument # local instance of sd_model
# base params
prompt: str = "",
negative_prompt: str = None,
negative_prompt: str = "",
seed: int = -1,
subseed: int = -1,
subseed_strength: float = 0,
+17 -10
View File
@@ -47,16 +47,23 @@ def apply_overlay(image: Image, paste_loc, index, overlays):
return image
debug(f'Apply overlay: image={image} loc={paste_loc} index={index} overlays={overlays}')
overlay = overlays[index]
if paste_loc is not None:
x, y, w, h = paste_loc
if image.width != w or image.height != h or x != 0 or y != 0:
base_image = Image.new('RGBA', (overlay.width, overlay.height))
image = images.resize_image(2, image, w, h)
base_image.paste(image, (x, y))
image = base_image
image = image.convert('RGBA')
image.alpha_composite(overlay)
image = image.convert('RGB')
if not isinstance(image, Image.Image) or not isinstance(overlay, Image.Image):
return image
try:
if paste_loc is not None and (isinstance(paste_loc, tuple) or isinstance(paste_loc, list)):
x, y, w, h = paste_loc
if x is None or y is None or w is None or h is None:
return image
if image.width != w or image.height != h or x != 0 or y != 0:
base_image = Image.new('RGBA', (overlay.width, overlay.height))
image = images.resize_image(2, image, w, h)
base_image.paste(image, (x, y))
image = base_image
image = image.convert('RGBA')
image.alpha_composite(overlay)
image = image.convert('RGB')
except Exception as e:
shared.log.error(f'Apply overlay: {e}')
return image