构建 · 隐形模特自动化
为您的商品目录实现隐形模特自动提取
一句话总结
拉取自上次运行以来的目录增量,将包含单一样式的 product_images 数组(每项包含一个图像 URL 以及可选的 back_image)POST 提交至 /api/v1/ghost-mannequin/batch,每 3 秒轮询一次批次 ID,直到所有项目状态变为 completed 或 failed,然后使用对应的 output_url 更新每个商品行。并发批次数量受套餐限制。
- Credits: 2K 分辨率 4 credits · 4K 分辨率 5 credits
- 常规耗时: 1.5–4 min
- 处理方式: 异步,轮询
本页所有数据均来自 Photta API 文档 · 已验证
无需设计师介入,即可去除每张 PDP 照片中的模特。Photta 的隐形模特 endpoint 天生支持批处理——每晚运行的定时任务可在数小时内(而非数周)将包含 50K SKU 的商品源转换为隐形模特目录。
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/ghost-mannequin \
-H "Authorization: Bearer $PHOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')const res = await fetch("https://api.photta.app/api/v1/ghost-mannequin", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
}),
});
const { data } = await res.json(); // data.id, data.statusimport os, requests
res = requests.post(
"https://api.photta.app/api/v1/ghost-mannequin",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
},
)
data = res.json()["data"] # data["id"], data["status"]工作原理
全目录每晚运行
实现无人值守自动化所需的五个环节。
步骤 1
映射您的商品目录
明确哪些商品行需要隐形模特图像、哪些已经生成、哪些属于受限类别。存储 last_photographed_at 时间戳,以便每晚的任务仅处理增量数据。
步骤 2
按类别选择 3D 或平铺(flat-lay)
`3d` 适用于需要立体感的服装——外套、牛仔裤、剪裁服饰。`flat_lay` 适用于平铺拍摄效果更好的配饰和针织衫。按商品类别存储样式,以便批次构建器无需人工干预即可选取正确样式。
步骤 3
批量提交增量数据
向 /api/v1/ghost-mannequin/batch 发送 POST 请求,附带 product_images 数组——每个项目包含 image、可选的 back_image 和 image_side——并为整个批次指定一个 style、background_color 和 resolution。自行维护一份数组索引到商品 ID 的映射;响应会按相同顺序为每个项目返回一个生成 ID。
步骤 4
轮询父批次
批次 endpoint 会返回聚合计数器(total、processing、completed、failed)。每 3 秒轮询一次,直到 completed + failed 等于 total。Photta 会在批次内并行处理各个项目,因此您无需单独轮询各个生成任务。
步骤 5
持久化存储到您的数据库
按顺序遍历 status.data.items——批次会保持您的数组顺序——并使用对应的 output_url 更新每个商品行。记录失败项——它们几乎总是指向数据源中损坏的原图,您可以在修复后于下一次运行时重新提交。
Python 三步走
提取增量、批量提交、父批次轮询——最小可行目录自动化。
from datetime import datetime, timedelta
yesterday = datetime.utcnow() - timedelta(days=1)
rows = db.execute(
"SELECT id, source_image_url FROM products WHERE updated_at > %s",
(yesterday,),
).fetchall()import os, requests
res = requests.post(
"https://api.photta.app/api/v1/ghost-mannequin/batch",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"product_images": [
{
"image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front"
},
{
"image": "https://cdn.yourstore.com/products/shirt-front.jpg",
"image_side": "front"
},
{
"image": "https://cdn.yourstore.com/products/trousers-front.jpg",
"image_side": "front"
}
],
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, buttoned up",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
},
)
data = res.json()["data"] # data["id"], data["status"]import os, time, requests
BASE = "https://api.photta.app/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"}
# data["items"] comes back in the order of the product_images you submitted.
batch_id = data["batch_id"]
for _ in range(240): # 240 × 3s = 12 minutes
status = requests.get(f"{BASE}/ghost-mannequin/batch/{batch_id}", headers=HEADERS).json()["data"]
if status["completed"] + status["failed"] == status["total"]:
break
time.sleep(3)
for row, item in zip(rows, status["items"]):
if item["status"] == "completed":
db.execute(
"UPDATE products SET ghost_image_url = %s WHERE id = %s",
(item["output_url"], row.id),
)开发者常见问题
在商品目录规模下运行隐形模特
单个批次最大支持多大?
根据文档,批次 endpoint 每次调用最多可接受几百个项目。对于 50K SKU 的每晚运行,请将增量拆分为 100–200 个项目的批次并按顺序触发,以便轻松保持在套餐的 rate limit 之下。
一个批次可以混合 3D 和平铺吗?
可以——style 是单项级别的字段,因此单个批次可以同时包含两者。在实践中,大多数团队仍会按类别拆分,因为当批次中的每一行都写入同一个数据库列时,下游的持久化逻辑会更简单。
失败的项目会如何处理?
批次中失败的项目会自动退还其 credits,并在最终的项目 payload 中携带 error_code + error_message。记录这些失败,并在团队有机会修复原图或将该行标记为永久无效输入后,于次日晚上重试。
如何将结果映射回我的商品 ID?
提交时请自行维护一份数组索引到商品 ID 的映射:批次响应会按与 product_images 相同的顺序为每个项目返回一个生成 ID,批次状态也会按该顺序列出各个项目。
我可以将其配置为每日定时任务(cron)吗?
可以——对于处理目录级规模资产的团队,标准的承重架构模式就是配置一个简单的每日 cron:拉取过去 24 小时的增量数据,分块,批量提交任务,并将结果写入数据库。请确保执行器具备幂等性,以便在某夜任务失败时能够安全重放。