feat(comfyui): ComfyUI 改 8188 + HTTP Basic Auth

本机 ComfyUI 开了 Basic Auth(user admin),端口 8182→8188:
- hairline/comfyui.py: 默认 URL 8188;所有 httpx 请求带 auth=(user,password)
  密码来源 环境变量 COMFYUI_PASSWORD → worker_config.json.comfyui_password → password.txt
- password.txt 入 .gitignore(含密码不入 git);worker_config.example 加 comfyui_password
- 实现说明文档同步(8188 + Basic Auth)
实测:ping + 实跑一张生发图均通过(带鉴权)。pytest 44 全绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
xsl
2026-06-15 23:10:09 +08:00
co-authored by Claude Opus 4.8
parent a3f4c822cb
commit e3c67fc8cf
4 changed files with 39 additions and 7 deletions
+3
View File
@@ -10,6 +10,9 @@ gateway/config.json
# worker 配置(含鉴权密码,不入 git)
worker_config.json
# ComfyUI Basic Auth 密码(不入 git
password.txt
# worker 运行期文件(PID / 日志)
worker.pid
worker.log
+3 -1
View File
@@ -84,7 +84,9 @@
- ⚠️ 本机 **RTX 5090(sm_120)**pinned `torch 2.2.2(cu121)` 只到 sm_90 → GPU 算子报 "no kernel image"
代码已自动**回退 CPU**BiSeNet/SegFormer CPU 推理可用)。要用 5090 GPU 需换 torch cu128(≥2.7)。
- 模型权重/字体见 [`../OFFLINE_ASSETS.md`](../OFFLINE_ASSETS.md)BiSeNet/SegFormer/face_landmarker.task 本地。
- 生发接口依赖本机 **ComfyUI(8182)**Flux-2,它自带支持 5090 的 torch);worker 只调其 HTTP API,不跑 Flux。
- 生发接口依赖本机 **ComfyUI(8188)**Flux-2,它自带支持 5090 的 torch);worker 只调其 HTTP API,不跑 Flux。
ComfyUI 开了 **HTTP Basic Auth**user `admin` + 密码);密码放 `password.txt`(不入 git) /
`worker_config.json.comfyui_password` / 环境变量 `COMFYUI_PASSWORD`URL 用 `COMFYUI_URL`
- `worker_config.json`(不入 git)`accept_passwords`(鉴权) + 鉴权头 `X-Internal-Token`
**网关机**
+31 -4
View File
@@ -1,7 +1,8 @@
"""ComfyUI 客户端:用 add_hair.json 工作流跑生发图(Flux-2 inpaint)。
worker 不跑 Flux,只把「划线图 + 遮罩」的 RGBA 上传到本机 ComfyUI(默认 8182)
worker 不跑 Flux,只把「划线图 + 遮罩」的 RGBA 上传到本机 ComfyUI(默认 8188)
替换工作流节点 26 的输入图、随机 seed,提交 /prompt,轮询 /history,取回 /view 输出。
ComfyUI 开启了 HTTP Basic Authuser `admin` + 密码),所有请求都带凭据。
"""
from __future__ import annotations
@@ -14,12 +15,13 @@ import uuid
import httpx
COMFYUI_URL = os.getenv("COMFYUI_URL", "http://127.0.0.1:8182").rstrip("/")
COMFYUI_URL = os.getenv("COMFYUI_URL", "http://127.0.0.1:8188").rstrip("/")
WORKFLOW_PATH = os.getenv(
"ADD_HAIR_WORKFLOW",
os.path.join(os.path.dirname(os.path.dirname(__file__)), "add_hair.json"),
)
COMFY_TIMEOUT = float(os.getenv("COMFYUI_TIMEOUT", "600")) # 单张出图最长等待(秒)
_REPO = os.path.dirname(os.path.dirname(__file__))
_INPUT_NODE = "26" # LoadImage:外部输入图(含 alpha 遮罩)
_SEED_NODE = "6" # RandomNoise
@@ -28,6 +30,31 @@ _OUTPUT_NODE = "17" # SaveImage
_workflow = None
def _comfy_auth():
"""ComfyUI Basic Auth 凭据 (user, password)。
user:环境变量 COMFYUI_USER,默认 admin。
password:环境变量 COMFYUI_PASSWORD → worker_config.json.comfyui_password → password.txt。
无密码则返回 None(不带鉴权,兼容未开启 auth 的实例)。
"""
user = os.getenv("COMFYUI_USER", "admin")
pw = os.getenv("COMFYUI_PASSWORD")
if not pw:
cfg = os.path.join(_REPO, "worker_config.json")
if os.path.isfile(cfg):
try:
with open(cfg, encoding="utf-8") as f:
pw = json.load(f).get("comfyui_password")
except Exception: # noqa: BLE001
pw = None
if not pw:
pwfile = os.path.join(_REPO, "password.txt")
if os.path.isfile(pwfile):
with open(pwfile, encoding="utf-8") as f:
pw = f.read().strip()
return (user, pw) if pw else None
def _load_workflow() -> dict:
global _workflow
if _workflow is None:
@@ -39,7 +66,7 @@ def _load_workflow() -> dict:
def run(rgba_png_bytes: bytes, timeout: float = COMFY_TIMEOUT) -> bytes:
"""提交一次生发任务,返回输出 PNG 字节。失败抛异常。"""
client_id = uuid.uuid4().hex
with httpx.Client(base_url=COMFYUI_URL, timeout=30.0) as cli:
with httpx.Client(base_url=COMFYUI_URL, timeout=30.0, auth=_comfy_auth()) as cli:
# 1. 上传输入图(含 alpha 遮罩)到 ComfyUI input 目录
fname = f"hair_{client_id}.png"
r = cli.post("/upload/image", files={"image": (fname, rgba_png_bytes, "image/png")},
@@ -92,7 +119,7 @@ def run(rgba_png_bytes: bytes, timeout: float = COMFY_TIMEOUT) -> bytes:
def ping() -> bool:
"""探测 ComfyUI 是否在线(/system_stats)。"""
try:
with httpx.Client(base_url=COMFYUI_URL, timeout=3.0) as cli:
with httpx.Client(base_url=COMFYUI_URL, timeout=3.0, auth=_comfy_auth()) as cli:
return cli.get("/system_stats").status_code == 200
except Exception: # noqa: BLE001
return False
+2 -2
View File
@@ -1,5 +1,5 @@
{
"_comment": "复制为 worker_config.json(不入 git)。accept_passwordsworker 内网鉴权密码列表,网关带 X-Internal-Token: <其中之一>(也可用环境变量 WORKER_ACCEPT_PASSWORDS 覆盖)。ark_api_key:接口4 火山方舟豆包视觉模型的 API Key(也可用环境变量 ARK_API_KEY 覆盖)。",
"_comment": "复制为 worker_config.json(不入 git)。accept_passwordsworker 内网鉴权密码列表,网关带 X-Internal-Token: <其中之一>(也可用环境变量 WORKER_ACCEPT_PASSWORDS 覆盖)。comfyui_password:本机 ComfyUI(8188) Basic Auth 密码(user 默认 admin;也可放 password.txt 或环境变量 COMFYUI_PASSWORD)。注:接口4 火山方舟 ark_api_key 已迁到网关配置。",
"accept_passwords": ["change-me-to-a-strong-secret"],
"ark_api_key": "your-volcengine-ark-api-key"
"comfyui_password": "your-comfyui-basic-auth-password"
}