From 1fe2dcaa2a5c7f6f4864a94ffb65f8eedd8a0129 Mon Sep 17 00:00:00 2001 From: AnyISalIn Date: Sat, 22 Jul 2023 10:00:27 +0800 Subject: [bug] If txt2img/img2img raises an exception, finally call state.end() Signed-off-by: AnyISalIn --- modules/api/api.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 2a4cd8a2..9d73083f 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -333,14 +333,16 @@ class Api: p.outpath_grids = opts.outdir_txt2img_grids p.outpath_samples = opts.outdir_txt2img_samples - shared.state.begin(job="scripts_txt2img") - if selectable_scripts is not None: - p.script_args = script_args - processed = scripts.scripts_txt2img.run(p, *p.script_args) # Need to pass args as list here - else: - p.script_args = tuple(script_args) # Need to pass args as tuple here - processed = process_images(p) - shared.state.end() + try: + shared.state.begin(job="scripts_txt2img") + if selectable_scripts is not None: + p.script_args = script_args + processed = scripts.scripts_txt2img.run(p, *p.script_args) # Need to pass args as list here + else: + p.script_args = tuple(script_args) # Need to pass args as tuple here + processed = process_images(p) + finally: + shared.state.end() b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else [] @@ -390,14 +392,16 @@ class Api: p.outpath_grids = opts.outdir_img2img_grids p.outpath_samples = opts.outdir_img2img_samples - shared.state.begin(job="scripts_img2img") - if selectable_scripts is not None: - p.script_args = script_args - processed = scripts.scripts_img2img.run(p, *p.script_args) # Need to pass args as list here - else: - p.script_args = tuple(script_args) # Need to pass args as tuple here - processed = process_images(p) - shared.state.end() + try: + shared.state.begin(job="scripts_img2img") + if selectable_scripts is not None: + p.script_args = script_args + processed = scripts.scripts_img2img.run(p, *p.script_args) # Need to pass args as list here + else: + p.script_args = tuple(script_args) # Need to pass args as tuple here + processed = process_images(p) + finally: + shared.state.end() b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else [] -- cgit v1.2.3 From 1cbfafafd2dc68c4985da2ae88d7e30f7074fed9 Mon Sep 17 00:00:00 2001 From: AnyISalIn Date: Mon, 24 Jul 2023 19:45:08 +0800 Subject: feat: add refresh vae api Signed-off-by: AnyISalIn --- modules/api/api.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 9d73083f..09166df2 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -15,7 +15,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 +from modules import sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing, errors, restart, shared_items from modules.api import models from modules.shared import opts from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images @@ -197,6 +197,7 @@ class Api: self.add_api_route("/sdapi/v1/prompt-styles", self.get_prompt_styles, methods=["GET"], response_model=List[models.PromptStyleItem]) self.add_api_route("/sdapi/v1/embeddings", self.get_embeddings, methods=["GET"], response_model=models.EmbeddingsResponse) self.add_api_route("/sdapi/v1/refresh-checkpoints", self.refresh_checkpoints, methods=["POST"]) + self.add_api_route("/sdapi/v1/refresh-vae", self.refresh_vae, methods=["POST"]) self.add_api_route("/sdapi/v1/create/embedding", self.create_embedding, methods=["POST"], response_model=models.CreateResponse) self.add_api_route("/sdapi/v1/create/hypernetwork", self.create_hypernetwork, methods=["POST"], response_model=models.CreateResponse) self.add_api_route("/sdapi/v1/preprocess", self.preprocess, methods=["POST"], response_model=models.PreprocessResponse) @@ -608,6 +609,10 @@ class Api: with self.queue_lock: shared.refresh_checkpoints() + def refresh_vae(self): + with self.queue_lock: + shared_items.refresh_vae_list() + def create_embedding(self, args: dict): try: shared.state.begin(job="create_embedding") -- cgit v1.2.3 From 6cc5a886ae9ff30148c43a95904accd191922afc Mon Sep 17 00:00:00 2001 From: caoxipeng Date: Fri, 28 Jul 2023 11:40:10 +0800 Subject: Add total_tqdm clear in the end of txt2img & img2img api. --- modules/api/api.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 606db179..909ea976 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -343,6 +343,7 @@ class Api: processed = process_images(p) finally: shared.state.end() + shared.total_tqdm.clear() b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else [] @@ -402,6 +403,7 @@ class Api: processed = process_images(p) finally: shared.state.end() + shared.total_tqdm.clear() b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else [] -- cgit v1.2.3 From 353c876172a48c5044130249370c9303e611dd8b Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Mon, 14 Aug 2023 10:43:18 +0300 Subject: fix API always using -1 as seed --- modules/api/api.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 908c4514..fb2c2ce9 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -330,6 +330,7 @@ class Api: with self.queue_lock: with closing(StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args)) as p: + p.is_api = True p.scripts = script_runner p.outpath_grids = opts.outdir_txt2img_grids p.outpath_samples = opts.outdir_txt2img_samples @@ -390,6 +391,7 @@ class Api: with self.queue_lock: with closing(StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args)) as p: p.init_images = [decode_base64_to_image(x) for x in init_images] + p.is_api = True p.scripts = script_runner p.outpath_grids = opts.outdir_img2img_grids p.outpath_samples = opts.outdir_img2img_samples -- cgit v1.2.3 From 959f8b32d5994b981845bde051ca74139a12d78b Mon Sep 17 00:00:00 2001 From: Cade Schlaefli Date: Thu, 17 Aug 2023 20:48:17 -0500 Subject: fix issues with model refresh --- modules/api/api.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index fb2c2ce9..51207648 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -24,7 +24,6 @@ from modules.textual_inversion.preprocess import preprocess from modules.hypernetworks.hypernetwork import create_hypernetwork, train_hypernetwork from PIL import PngImagePlugin,Image from modules.sd_models import checkpoints_list, unload_model_weights, reload_model_weights, checkpoint_aliases -from modules.sd_vae import vae_dict from modules.sd_models_config import find_checkpoint_config_near_filename from modules.realesrgan_model import get_realesrgan_models from modules import devices @@ -567,10 +566,12 @@ class Api: ] def get_sd_models(self): - return [{"title": x.title, "model_name": x.model_name, "hash": x.shorthash, "sha256": x.sha256, "filename": x.filename, "config": find_checkpoint_config_near_filename(x)} for x in checkpoints_list.values()] + import modules.sd_models as sd_models + return [{"title": x.title, "model_name": x.model_name, "hash": x.shorthash, "sha256": x.sha256, "filename": x.filename, "config": find_checkpoint_config_near_filename(x)} for x in sd_models.checkpoints_list.values()] def get_sd_vaes(self): - return [{"model_name": x, "filename": vae_dict[x]} for x in vae_dict.keys()] + import modules.sd_vae as sd_vae + return [{"model_name": x, "filename": sd_vae.vae_dict[x]} for x in sd_vae.vae_dict.keys()] def get_hypernetworks(self): return [{"name": name, "path": shared.hypernetworks[name]} for name in shared.hypernetworks] -- cgit v1.2.3 From f9c2216ffaa72e2c435e38ca221fd8707936a9d5 Mon Sep 17 00:00:00 2001 From: Cade Schlaefli Date: Thu, 17 Aug 2023 21:14:14 -0500 Subject: remove unused import --- modules/api/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 51207648..da1fdbca 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -23,7 +23,7 @@ from modules.textual_inversion.textual_inversion import create_embedding, train_ from modules.textual_inversion.preprocess import preprocess from modules.hypernetworks.hypernetwork import create_hypernetwork, train_hypernetwork from PIL import PngImagePlugin,Image -from modules.sd_models import checkpoints_list, unload_model_weights, reload_model_weights, checkpoint_aliases +from modules.sd_models import unload_model_weights, reload_model_weights, checkpoint_aliases from modules.sd_models_config import find_checkpoint_config_near_filename from modules.realesrgan_model import get_realesrgan_models from modules import devices -- cgit v1.2.3 From 4760c3c0b58059e9c655a6ea8360c65a4586a71b Mon Sep 17 00:00:00 2001 From: SpenserCai Date: Sat, 19 Aug 2023 12:19:21 +0800 Subject: api support get image from url --- modules/api/api.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index fb2c2ce9..4abfd9bd 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -57,6 +57,15 @@ def setUpscalers(req: dict): def decode_base64_to_image(encoding): + if encoding.startswith("http://") or encoding.startswith("https://"): + import requests + response = requests.get(encoding, timeout=30, headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}) + try: + image = Image.open(BytesIO(response.content)) + return image + except Exception as e: + raise HTTPException(status_code=500, detail="Invalid image url") from e + if encoding.startswith("data:image/"): encoding = encoding.split(";")[1].split(",")[1] try: -- cgit v1.2.3 From 268dc9b30813a62b7a2c6f666505696ceee40c09 Mon Sep 17 00:00:00 2001 From: akiba Date: Sun, 20 Aug 2023 21:41:27 +0800 Subject: fix potential ssrf attack in #12663 --- modules/api/api.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 6e8d21a3..fed83f8f 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -4,6 +4,8 @@ import os import time import datetime import uvicorn +import ipaddress +import requests import gradio as gr from threading import Lock from io import BytesIO @@ -56,8 +58,27 @@ def setUpscalers(req: dict): def decode_base64_to_image(encoding): + def verify_url(url): + import socket + from urllib.parse import urlparse + try: + parsed_url = urlparse(url) + domain_name = parsed_url.netloc + host = socket.gethostbyname_ex(domain_name) + for ip in host[2]: + ip_addr = ipaddress.ip_address(ip) + # https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Address.is_global + if not ip_addr.is_global: + return False + except Exception: + return False + + return True + if encoding.startswith("http://") or encoding.startswith("https://"): - import requests + if not verify_url(encoding): + raise HTTPException(status_code=500, detail="Invalid image url") + response = requests.get(encoding, timeout=30, headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}) try: image = Image.open(BytesIO(response.content)) -- cgit v1.2.3 From 76ae1019b96c4673231a116f0b20bb85ebec5666 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Mon, 21 Aug 2023 07:38:07 +0300 Subject: add settings for http/https URLs in source images in api --- modules/api/api.py | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index fed83f8f..42fbbe3d 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -57,29 +57,35 @@ def setUpscalers(req: dict): return reqDict -def decode_base64_to_image(encoding): - def verify_url(url): - import socket - from urllib.parse import urlparse - try: - parsed_url = urlparse(url) - domain_name = parsed_url.netloc - host = socket.gethostbyname_ex(domain_name) - for ip in host[2]: - ip_addr = ipaddress.ip_address(ip) - # https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Address.is_global - if not ip_addr.is_global: - return False - except Exception: - return False - - return True +def verify_url(url): + """Returns True if the url refers to a global resource.""" + + import socket + from urllib.parse import urlparse + try: + parsed_url = urlparse(url) + domain_name = parsed_url.netloc + host = socket.gethostbyname_ex(domain_name) + for ip in host[2]: + ip_addr = ipaddress.ip_address(ip) + if not ip_addr.is_global: + return False + except Exception: + return False + return True + + +def decode_base64_to_image(encoding): if encoding.startswith("http://") or encoding.startswith("https://"): - if not verify_url(encoding): - raise HTTPException(status_code=500, detail="Invalid image url") + if not opts.api_enable_requests: + raise HTTPException(status_code=500, detail="Requests not allowed") + + if opts.api_forbid_local_requests and not verify_url(encoding): + raise HTTPException(status_code=500, detail="Request to local resource not allowed") - response = requests.get(encoding, timeout=30, headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}) + headers = {'user-agent': opts.api_useragent} if opts.api_useragent else {} + response = requests.get(encoding, timeout=30, headers=headers) try: image = Image.open(BytesIO(response.content)) return image -- cgit v1.2.3 From b4d21e7113384bbb592bbd79bca06aeb9e4d640a Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Mon, 21 Aug 2023 07:59:57 +0300 Subject: prevent API options from being changed via API --- modules/api/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 42fbbe3d..e6edffe7 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -570,7 +570,7 @@ class Api: raise RuntimeError(f"model {checkpoint_name!r} not found") for k, v in req.items(): - shared.opts.set(k, v) + shared.opts.set(k, v, is_api=True) shared.opts.save(shared.config_filename) return -- cgit v1.2.3 From 3369fb27df6c1badd39bcb59b3f71c61a47d3d91 Mon Sep 17 00:00:00 2001 From: SpenserCai Date: Fri, 25 Aug 2023 22:15:35 +0800 Subject: support installed extensions list api --- modules/api/api.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index e6edffe7..0bcf5497 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -243,6 +243,7 @@ class Api: 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.add_api_route("/sdapi/v1/extensions", self.get_extensions_list, methods=["GET"], response_model=List[models.ExtensionItem]) if shared.cmd_opts.api_server_stop: self.add_api_route("/sdapi/v1/server-kill", self.kill_webui, methods=["POST"]) @@ -769,6 +770,25 @@ class Api: except Exception as err: cuda = {'error': f'{err}'} return models.MemoryResponse(ram=ram, cuda=cuda) + + def get_extensions_list(self): + from modules import extensions + extensions.list_extensions() + ext_list = [] + for ext in extensions.extensions: + ext: extensions.Extension + ext.read_info_from_repo() + if ext.remote is not None: + ext_list.append({ + "name": ext.name, + "remote": ext.remote, + "branch": ext.branch, + "commit_hash":ext.commit_hash, + "commit_date":ext.commit_date, + "version":ext.version, + "enabled":ext.enabled + }) + return ext_list def launch(self, server_name, port, root_path): self.app.include_router(self.router) -- cgit v1.2.3 From dd07b5193efa547929629b310ef5c9ff0fc83a19 Mon Sep 17 00:00:00 2001 From: SpenserCai Date: Fri, 25 Aug 2023 22:23:17 +0800 Subject: fix format error --- modules/api/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 0bcf5497..785ee828 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -770,7 +770,7 @@ class Api: except Exception as err: cuda = {'error': f'{err}'} return models.MemoryResponse(ram=ram, cuda=cuda) - + def get_extensions_list(self): from modules import extensions extensions.list_extensions() -- cgit v1.2.3 From 72ee347eabf04d1a238a738a03e7973cc2a46ca3 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 26 Aug 2023 06:52:18 +0300 Subject: update pnginfo checkpoint to return dict with parsed values --- modules/api/api.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'modules/api/api.py') diff --git a/modules/api/api.py b/modules/api/api.py index 785ee828..844e31ee 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -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 +from modules import sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing, errors, restart, shared_items, script_callbacks, generation_parameters_copypaste from modules.api import models from modules.shared import opts from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images @@ -474,9 +474,6 @@ class Api: return models.ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1]) def pnginfoapi(self, req: models.PNGInfoRequest): - if(not req.image.strip()): - return models.PNGInfoResponse(info="") - image = decode_base64_to_image(req.image.strip()) if image is None: return models.PNGInfoResponse(info="") @@ -485,9 +482,10 @@ class Api: if geninfo is None: geninfo = "" - items = {**{'parameters': geninfo}, **items} + params = generation_parameters_copypaste.parse_generation_parameters(geninfo) + script_callbacks.infotext_pasted_callback(geninfo, params) - return models.PNGInfoResponse(info=geninfo, items=items) + return models.PNGInfoResponse(info=geninfo, items=items, parameters=params) def progressapi(self, req: models.ProgressRequest = Depends()): # copy from check_progress_call of ui.py -- cgit v1.2.3