From 7bd04e0b5cd9c0c0dbcf0924df32054dca6ef0a9 Mon Sep 17 00:00:00 2001 From: vladmandic Date: Sat, 6 Dec 2025 12:33:52 +0100 Subject: [PATCH] add /detailers api endpoint Signed-off-by: vladmandic --- CHANGELOG.md | 10 ++++++---- modules/api/api.py | 3 ++- modules/api/endpoints.py | 8 ++++++-- modules/api/models.py | 2 +- modules/postprocess/gfpgan_model.py | 2 ++ modules/postprocess/yolo.py | 1 + wiki | 2 +- 7 files changed, 19 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a811c3087..99f1772e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,12 @@ # Change Log for SD.Next -## Update for 2025-12-04 +## Update for 2025-12-06 ### TBD Merge commit: `f903a36d9` -### Highlights for 2025-12-04 +### Highlights for 2025-12-06 New native [kanvas](https://vladmandic.github.io/sdnext-docs/Kanvas/) module for image manipulation that fully replaces img2img, inpaint and outpaint controls New generation of **Flux.2** large image model, new **Z-Image** model that is creating a lot of buzz and a first cloud model with **Google's Nano Banana** *2.5 Flash and 3.0 Pro* plus new **Photoroom PRX** model @@ -15,7 +15,7 @@ New generation of **Flux.2** large image model, new **Z-Image** model that is cr [ReadMe](https://github.com/vladmandic/automatic/blob/master/README.md) | [ChangeLog](https://github.com/vladmandic/automatic/blob/master/CHANGELOG.md) | [Docs](https://vladmandic.github.io/sdnext-docs/) | [WiKi](https://github.com/vladmandic/automatic/wiki) | [Discord](https://discord.com/invite/sd-next-federal-batch-inspectors-1101998836328697867) | [Sponsor](https://github.com/sponsors/vladmandic) -### Details for 2025-12-04 +### Details for 2025-12-06 - **Models** - [Black Forest Labs FLUX.2 Dev](https://bfl.ai/blog/flux-2) and prequantized variation [SDNQ-SVD-Uint4](https://huggingface.co/Disty0/FLUX.2-dev-SDNQ-uint4-svd-r32) @@ -48,9 +48,11 @@ New generation of **Flux.2** large image model, new **Z-Image** model that is cr - **sdnq**: improve dequant logic - **gallery**: significant performance improvements, thanks @awsr - **API** - - `/control` endpoint is now fully compatible with scripts + - `/control` endpoint is now fully compatible with scripts - `/control` additional params to to control *xyz grid* see `cli/api-xyz.py` for simple example + - `/detailers` new endpoint to list available detailers, both built-in and any custom downloaded + - `/face-restorers` expanded to list model folders - **Internal** - sdnq: multiple improvements to quantization and dequantization logic - torch: update to `torch==2.9.1` for *cuda, ipex, openvino, rocm* backends diff --git a/modules/api/api.py b/modules/api/api.py index 1dafa60a8..56e9bee76 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -81,7 +81,8 @@ class Api: self.add_api_route("/sdapi/v1/upscalers", endpoints.get_upscalers, methods=["GET"], response_model=List[models.ItemUpscaler]) self.add_api_route("/sdapi/v1/sd-models", endpoints.get_sd_models, methods=["GET"], response_model=List[models.ItemModel]) self.add_api_route("/sdapi/v1/controlnets", endpoints.get_controlnets, methods=["GET"], response_model=List[str]) - self.add_api_route("/sdapi/v1/face-restorers", endpoints.get_detailers, methods=["GET"], response_model=List[models.ItemDetailer]) + self.add_api_route("/sdapi/v1/face-restorers", endpoints.get_restorers, methods=["GET"], response_model=List[models.ItemDetailer]) + self.add_api_route("/sdapi/v1/detailers", endpoints.get_detailers, methods=["GET"], response_model=List[models.ItemDetailer]) self.add_api_route("/sdapi/v1/prompt-styles", endpoints.get_prompt_styles, methods=["GET"], response_model=List[models.ItemStyle]) self.add_api_route("/sdapi/v1/embeddings", endpoints.get_embeddings, methods=["GET"], response_model=models.ResEmbeddings) self.add_api_route("/sdapi/v1/sd-vae", endpoints.get_sd_vaes, methods=["GET"], response_model=List[models.ItemVae]) diff --git a/modules/api/endpoints.py b/modules/api/endpoints.py index c00648ade..7c7b28f81 100644 --- a/modules/api/endpoints.py +++ b/modules/api/endpoints.py @@ -28,8 +28,12 @@ def get_controlnets(model_type: Optional[str] = None): from modules.control.units.controlnet import api_list_models return api_list_models(model_type) +def get_restorers(): + return [{"name":x.name(), "path": getattr(x, "cmd_dir", None)} for x in shared.face_restorers] + def get_detailers(): - return [{"name":x.name(), "cmd_dir": getattr(x, "cmd_dir", None)} for x in shared.detailers] + shared.yolo.enumerate() + return [{"name": k, "path": v} for k, v in shared.yolo.list.items()] def get_prompt_styles(): return [{ 'name': v.name, 'prompt': v.prompt, 'negative_prompt': v.negative_prompt, 'extra': v.extra, 'filename': v.filename, 'preview': v.preview} for v in shared.prompt_styles.styles.values()] @@ -91,7 +95,7 @@ def post_interrogate(req: models.ReqInterrogate): if not req.analyze: return models.ResInterrogate(caption=caption) else: - medium, artist, movement, trending, flavor = analyze_image(image, clip_model=req.clip_model, blip_model=req.blip_model) + medium, artist, movement, trending, flavor, _ = analyze_image(image, clip_model=req.clip_model, blip_model=req.blip_model) return models.ResInterrogate(caption=caption, medium=medium, artist=artist, movement=movement, trending=trending, flavor=flavor) def post_vqa(req: models.ReqVQA): diff --git a/modules/api/models.py b/modules/api/models.py index fa6ef0e15..9bd5ac5e4 100644 --- a/modules/api/models.py +++ b/modules/api/models.py @@ -115,7 +115,7 @@ class ItemHypernetwork(BaseModel): class ItemDetailer(BaseModel): name: str = Field(title="Name") - cmd_dir: Optional[str] = Field(title="Path") + path: Optional[str] = Field(title="Path") class ItemGAN(BaseModel): name: str = Field(title="Name") diff --git a/modules/postprocess/gfpgan_model.py b/modules/postprocess/gfpgan_model.py index b291890d8..8763f411e 100644 --- a/modules/postprocess/gfpgan_model.py +++ b/modules/postprocess/gfpgan_model.py @@ -102,6 +102,8 @@ def setup_model(dirname): gfpgan_constructor = gfpgan.GFPGANer class FaceRestorerGFPGAN(modules.detailer.Detailer): + cmd_dir = model_path + def name(self): return "GFPGAN" diff --git a/modules/postprocess/yolo.py b/modules/postprocess/yolo.py index 8646c38df..b34259e82 100644 --- a/modules/postprocess/yolo.py +++ b/modules/postprocess/yolo.py @@ -48,6 +48,7 @@ class YoloRestorer(Detailer): self.models = {} # cache loaded models self.list = {} self.ui_mode = True + self.cmd_dir = shared.opts.yolo_dir self.enumerate() def name(self): diff --git a/wiki b/wiki index 9abbfcfa3..f7289d6c0 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 9abbfcfa333a982b63c8462da534a39ec82991ef +Subproject commit f7289d6c03899f519de8692efe8ea2731779607c