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:
@@ -10,6 +10,9 @@ gateway/config.json
|
|||||||
# worker 配置(含鉴权密码,不入 git)
|
# worker 配置(含鉴权密码,不入 git)
|
||||||
worker_config.json
|
worker_config.json
|
||||||
|
|
||||||
|
# ComfyUI Basic Auth 密码(不入 git)
|
||||||
|
password.txt
|
||||||
|
|
||||||
# worker 运行期文件(PID / 日志)
|
# worker 运行期文件(PID / 日志)
|
||||||
worker.pid
|
worker.pid
|
||||||
worker.log
|
worker.log
|
||||||
|
|||||||
+3
-1
@@ -84,7 +84,9 @@
|
|||||||
- ⚠️ 本机 **RTX 5090(sm_120)**,pinned `torch 2.2.2(cu121)` 只到 sm_90 → GPU 算子报 "no kernel image",
|
- ⚠️ 本机 **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)。
|
代码已自动**回退 CPU**(BiSeNet/SegFormer CPU 推理可用)。要用 5090 GPU 需换 torch cu128(≥2.7)。
|
||||||
- 模型权重/字体见 [`../OFFLINE_ASSETS.md`](../OFFLINE_ASSETS.md);BiSeNet/SegFormer/face_landmarker.task 本地。
|
- 模型权重/字体见 [`../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`。
|
- `worker_config.json`(不入 git):`accept_passwords`(鉴权) + 鉴权头 `X-Internal-Token`。
|
||||||
|
|
||||||
**网关机**
|
**网关机**
|
||||||
|
|||||||
+31
-4
@@ -1,7 +1,8 @@
|
|||||||
"""ComfyUI 客户端:用 add_hair.json 工作流跑生发图(Flux-2 inpaint)。
|
"""ComfyUI 客户端:用 add_hair.json 工作流跑生发图(Flux-2 inpaint)。
|
||||||
|
|
||||||
worker 不跑 Flux,只把「划线图 + 遮罩」的 RGBA 上传到本机 ComfyUI(默认 8182),
|
worker 不跑 Flux,只把「划线图 + 遮罩」的 RGBA 上传到本机 ComfyUI(默认 8188),
|
||||||
替换工作流节点 26 的输入图、随机 seed,提交 /prompt,轮询 /history,取回 /view 输出。
|
替换工作流节点 26 的输入图、随机 seed,提交 /prompt,轮询 /history,取回 /view 输出。
|
||||||
|
ComfyUI 开启了 HTTP Basic Auth(user `admin` + 密码),所有请求都带凭据。
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
@@ -14,12 +15,13 @@ import uuid
|
|||||||
|
|
||||||
import httpx
|
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(
|
WORKFLOW_PATH = os.getenv(
|
||||||
"ADD_HAIR_WORKFLOW",
|
"ADD_HAIR_WORKFLOW",
|
||||||
os.path.join(os.path.dirname(os.path.dirname(__file__)), "add_hair.json"),
|
os.path.join(os.path.dirname(os.path.dirname(__file__)), "add_hair.json"),
|
||||||
)
|
)
|
||||||
COMFY_TIMEOUT = float(os.getenv("COMFYUI_TIMEOUT", "600")) # 单张出图最长等待(秒)
|
COMFY_TIMEOUT = float(os.getenv("COMFYUI_TIMEOUT", "600")) # 单张出图最长等待(秒)
|
||||||
|
_REPO = os.path.dirname(os.path.dirname(__file__))
|
||||||
|
|
||||||
_INPUT_NODE = "26" # LoadImage:外部输入图(含 alpha 遮罩)
|
_INPUT_NODE = "26" # LoadImage:外部输入图(含 alpha 遮罩)
|
||||||
_SEED_NODE = "6" # RandomNoise
|
_SEED_NODE = "6" # RandomNoise
|
||||||
@@ -28,6 +30,31 @@ _OUTPUT_NODE = "17" # SaveImage
|
|||||||
_workflow = None
|
_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:
|
def _load_workflow() -> dict:
|
||||||
global _workflow
|
global _workflow
|
||||||
if _workflow is None:
|
if _workflow is None:
|
||||||
@@ -39,7 +66,7 @@ def _load_workflow() -> dict:
|
|||||||
def run(rgba_png_bytes: bytes, timeout: float = COMFY_TIMEOUT) -> bytes:
|
def run(rgba_png_bytes: bytes, timeout: float = COMFY_TIMEOUT) -> bytes:
|
||||||
"""提交一次生发任务,返回输出 PNG 字节。失败抛异常。"""
|
"""提交一次生发任务,返回输出 PNG 字节。失败抛异常。"""
|
||||||
client_id = uuid.uuid4().hex
|
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 目录
|
# 1. 上传输入图(含 alpha 遮罩)到 ComfyUI input 目录
|
||||||
fname = f"hair_{client_id}.png"
|
fname = f"hair_{client_id}.png"
|
||||||
r = cli.post("/upload/image", files={"image": (fname, rgba_png_bytes, "image/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:
|
def ping() -> bool:
|
||||||
"""探测 ComfyUI 是否在线(/system_stats)。"""
|
"""探测 ComfyUI 是否在线(/system_stats)。"""
|
||||||
try:
|
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
|
return cli.get("/system_stats").status_code == 200
|
||||||
except Exception: # noqa: BLE001
|
except Exception: # noqa: BLE001
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_comment": "复制为 worker_config.json(不入 git)。accept_passwords:worker 内网鉴权密码列表,网关带 X-Internal-Token: <其中之一>(也可用环境变量 WORKER_ACCEPT_PASSWORDS 覆盖)。ark_api_key:接口4 火山方舟豆包视觉模型的 API Key(也可用环境变量 ARK_API_KEY 覆盖)。",
|
"_comment": "复制为 worker_config.json(不入 git)。accept_passwords:worker 内网鉴权密码列表,网关带 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"],
|
"accept_passwords": ["change-me-to-a-strong-secret"],
|
||||||
"ark_api_key": "your-volcengine-ark-api-key"
|
"comfyui_password": "your-comfyui-basic-auth-password"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user