Files
hair/docs/网关待改动.md
T
2026-06-23 23:26:40 +08:00

147 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 网关侧改动清单(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`,已改):
```python
# 原: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`
接口5 `hairline_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 的同路径:
```python
# gateway/app.py
@app.post("/api/v1/hair/grow-v2", tags=["生发"])
async def hair_grow_v2(request: Request):
"""接口7C端生发 v2add_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 | string | **是** | 发型序号,**逗号分隔多选**(如 `1,2,3`)。female: 15male: 14 |
| beauty_enabled | bool | 否 | 美颜开关(本期不生效) |
| use_mask | bool | 否 | 默认 `true``false` 跳过遮罩 |
| prompt | string | 否 | ComfyUI 提示词 |
### 出参(与接口 2 一致)
```json
{
"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` |
| 输入/遮罩节点 | 26LoadImage |
| 输出节点 | 75SaveImage,自动检测) |
| 提示词节点 | 60JjkText |
### 🔲【可选·仅影响 /docs】OpenAPI 表单声明
若想让网关 `/docs` 展示准确,在 `gateway/app.py` 新增 `_GROW_V2_FORMS`(或复用 `_GROW_FORMS` 并补充 `gender`/`hair_style` 字段),然后将路由函数签名改为显式声明 Form 参数(参考接口 4 的写法)。不改也不影响实际转发。
---
## 6. ✅【已完成】接口6 四庭七眼测量 v2`/api/v1/face/measure-v2`
**背景**worker 侧接口 6 是接口 1 的**去顶庭变体**(不再完全一致):不画头顶横线/不返回顶庭数据、竖线范围发际线→下巴尖、不画人头最左/最右端线。worker 侧与接口 1 共用 `_face_measure_impl(variant="v6")`
**网关已新增路由**`gateway/app.py` 已实现,网关机器 pull 后生效):
```python
# gateway/app.py
@app.post("/api/v1/face/measure-v2", tags=["人脸分析"])
async def face_measure_v2(request: Request):
"""接口6:四庭七眼测量 v2(去顶庭 + 去头部端线)"""
return await _proxy(request, "/api/v1/face/measure-v2")
```
**无需额外改动**
- 入参:与接口 1 完全相同(image_file/url/base64 三选一)
- 出参:`annotated_image_base64` → 经现有 `rewrite_base64_to_url` 自动改写为 `annotated_image_url`
- worker 侧 v6 差异(去顶庭字段、变体标注)由 `_face_measure_impl` 内部处理,网关透明转发
---
## 已经做好、无需再动的
- **接口4 在网关本机实现**(调豆包,不转发 worker)——已完成;config 里配 `ark`
- **接口4 业务错误 HTTP 状态**已统一为 200(与其余接口一致)。
- **接口3 去 original / best_hairline**——网关盲转发,无需改(映射表里也没有 best_hairline)。
---
> 对外字段映射总表见 [`实现说明.md`](实现说明.md) §1;契约以 [`接口文档.md`](接口文档.md) 为准。