接口2 变更: - 新增必填 hair_style(int) 参数,按序号只生成一张(不再全量) - female:1-5 male:1-4,越界返回1007 接口7 新增: - POST /api/v1/hair/grow-v2,功能与接口2一致 - 使用 add_hair2.json 工作流(Flux-2 Klein 9b) - SaveImage输出节点自动检测(75) comfyui.py 重构: - run() 支持 workflow_path 参数,多工作流按路径缓存 - SaveImage 输出节点自动检测,不再硬编码 - 输入/种子/提示词节点ID两个工作流相同(26/6/60) 文档: - 接口文档、实现说明、网关待改动 三份同步更新 - 网关只需加一行路由,base64→URL改写无需改动 Co-Authored-By: Claude <noreply@anthropic.com>
5.2 KiB
网关侧改动清单(worker 近期变更引发)
给网关开发:以下是 worker/契约近期变化里与网关有关的点。标 ✅ 的我已在本仓库
gateway/改好(你 review/拉取即可);标 🔲 的是建议你确认或改。功能必需只有第 1 条。
1. ✅【功能必需】base64→URL 落盘扩展名按内容嗅探(支持 JPG)
背景:接口 2/3/5 的返回图改成了 JPG(体积约小 9×),接口 1 标注图仍是 PNG(含透明)。
网关把 *_base64 落盘时若硬编码 .png,JPG 会被存成 .png(内容是 JPG、扩展名错)。
改动(gateway/forward.py 的 rewrite_base64_to_url,已改):
# 原:filename = f"{uuid.uuid4().hex}.png"
ext = "png" if img_bytes[:8] == b"\x89PNG\r\n\x1a\n" else "jpg" # 按内容嗅探
filename = f"{uuid.uuid4().hex}.{ext}"
这样接口1 存
.png、接口2/3/5 存.jpg,对外 URL 后缀也就正确。若你的网关是独立部署/独立代码,按上面这两行改一下即可。
2. 🔲【建议】生发接口超时调大
接口 2(一次 N 张 Flux,~18s)/ 3(~6s) 经 ComfyUI 同步出图较慢。
gateway/config.json 的 dispatch.request_timeout_seconds 建议 ≥ 120,否则网关会先超时换 worker 重试。
3. 🔲【确认】base64→URL 通用改写仍覆盖这些场景
- 数组里的图片字段:接口2
results[].image_base64/results[].grown_image_base64、 接口5hairline_images[].image_base64在数组元素内——改写要递归进数组(你现有的递归实现已覆盖)。 - 可空字段:接口2/3 的生发图(ComfyUI 没起/失败时)
*_base64为 null → 保留 null、不落盘。
4. 🔲【可选·仅影响 /docs】OpenAPI 表单声明
纯文档展示,不影响转发功能(网关是盲转发)。若想让网关 /docs 准确:
- 接口2
/hair/grow、接口5/hairline/generate入参新增必填gender(male/female)。 - 接口3
/hair/grow-b入参只剩marked_image_*(已去掉original_image_*)。 - (
gateway/app.py里的_*_FORMS字典当前未被路由引用,所以不改也不影响实际行为。)
5. 🔲【新增】接口7 C端生发 v2(/api/v1/hair/grow-v2)
背景:worker 侧已新增接口 7,功能与接口 2 完全一致,区别仅在于 ComfyUI 工作流使用 add_hair2.json(而非 add_hair.json)。
网关需新增一个路由,代理转发到 worker 的同路径:
# gateway/app.py
@app.post("/api/v1/hair/grow-v2", tags=["生发"])
async def hair_grow_v2(request: Request):
"""接口7:C端生发 v2(add_hair2 工作流)"""
return await _proxy(request, "/api/v1/hair/grow-v2")
无需额外改动:
- 请求:multipart/form-data,参数与接口 2 完全相同(
image_file/url/base64三选一 +gender+hair_style+beauty_enabled+use_mask+prompt),网关盲转发即可 - 响应:结构与接口 2 完全一致,
results[].image_base64/results[].grown_image_base64经现有rewrite_base64_to_url自动改写为 URL - base64→URL:数组内图片字段递归改写已覆盖,无需修改
入参(与接口 2 一致)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| image_file / image_url / image_base64 | — | 三选一 | 用户正面照 |
| gender | string | 是 | male / female |
| hair_style | int | 是 | 发型序号。female: 1–5,male: 1–4 |
| beauty_enabled | bool | 否 | 美颜开关(本期不生效) |
| use_mask | bool | 否 | 默认 true,false 跳过遮罩 |
| prompt | string | 否 | ComfyUI 提示词 |
出参(与接口 2 一致)
{
"code": 0,
"message": "success",
"request_id": "gw-xxxxxxxx",
"data": {
"results": [
{
"image_url": "https://hair.xiangsilian.com/static/annotations/xxx.jpg",
"grown_image_url": "https://hair.xiangsilian.com/static/annotations/xxx.jpg",
"hairline_type": "ellipse",
"order": 1
}
]
}
}
worker 侧信息
| 项目 | 值 |
|---|---|
| worker 路径 | /api/v1/hair/grow-v2 |
| 工作流文件 | add_hair2.json |
| 输入/遮罩节点 | 26(LoadImage) |
| 输出节点 | 75(SaveImage,自动检测) |
| 提示词节点 | 60(JjkText) |
🔲【可选·仅影响 /docs】OpenAPI 表单声明
若想让网关 /docs 展示准确,在 gateway/app.py 新增 _GROW_V2_FORMS(或复用 _GROW_FORMS 并补充 gender/hair_style 字段),然后将路由函数签名改为显式声明 Form 参数(参考接口 4 的写法)。不改也不影响实际转发。
已经做好、无需再动的
- 接口4 在网关本机实现(调豆包,不转发 worker)——已完成;config 里配
ark。 - 接口4 业务错误 HTTP 状态已统一为 200(与其余接口一致)。
- 接口3 去 original / best_hairline——网关盲转发,无需改(映射表里也没有 best_hairline)。