开始使用
快速开始
完成鉴权、提交 Rodin 任务、轮询状态并下载结果。
准备工作
先在 API 控制台创建 API key。
不要在代码中保留凭据
切勿将 API key 或其他凭据硬编码到代码中或提交到代码仓库。请改用环境变量或密钥管理服务加载凭据,例如:
export RODIN_API_KEY='replace-with-your-api-key'所有受保护的请求都使用以下请求头:
Authorization: Bearer YOUR_RODIN_API_KEY1. 提交生成任务
下面的示例向 Rodin Gen-2.5 提交一张图片。最多可上传五张图片;多图请求需要重复提交 images 表单字段。
curl --fail-with-body --request POST 'https://api.hyper3d.com/api/v2/rodin' \
--header "Authorization: Bearer ${RODIN_API_KEY}" \
--form 'images=@./input.png' \
--form 'tier=Gen-2.5-Medium' \
--form 'mesh_mode=Raw' \
--form 'quality=medium'
响应中有两个用途不同的标识:
jobs.subscription_key:传给/status。- 顶层
uuid:作为task_uuid传给/download。
{
"message": "Submitted.",
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"jobs": {
"uuids": ["223e4567-e89b-12d3-a456-426614174000"],
"subscription_key": "subscription-key-from-generation-response"
},
"consumed": 0.5
}
2. 查询状态
首次查询前至少等待 5 秒,后续请求逐步退避;收到 HTTP 429 时遵循 Retry-After。任一 job 为 Failed 时立即停止;仅当所有 job 都为 Done 时进入下载步骤。
curl --fail-with-body --request POST 'https://api.hyper3d.com/api/v2/status' \
--header "Authorization: Bearer ${RODIN_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{"subscription_key":"subscription-key-from-generation-response"}'
3. 下载结果
全部 job 完成后,使用生成响应顶层的 uuid 调用 /download。
curl --fail-with-body --request POST 'https://api.hyper3d.com/api/v2/download' \
--header "Authorization: Bearer ${RODIN_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{"task_uuid":"123e4567-e89b-12d3-a456-426614174000"}'
完整 Python 流程
这个示例在 5 秒后开始轮询,逐步增加到最长 30 秒的间隔,总期限为 20 分钟;它会处理 HTTP 429、在 job 失败时终止,并且只在全部完成后下载。
import os
import time
from email.utils import parsedate_to_datetime
from pathlib import Path
import requests
BASE_URL = "https://api.hyper3d.com/api/v2"
DEADLINE_SECONDS = 20 * 60
def request_with_rate_limit(session, method, url, **kwargs):
while True:
response = session.request(method, url, timeout=60, **kwargs)
if response.status_code != 429:
response.raise_for_status()
return response.json()
retry_after = response.headers.get("Retry-After", "5")
try:
delay = max(1, int(retry_after))
except ValueError:
delay = max(1, int((parsedate_to_datetime(retry_after) - parsedate_to_datetime(response.headers["Date"])).total_seconds()))
time.sleep(delay)
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['RODIN_API_KEY']}"
with Path("input.png").open("rb") as image_file:
generation = request_with_rate_limit(
session,
"POST",
f"{BASE_URL}/rodin",
files={"images": ("input.png", image_file, "image/png")},
data={"tier": "Gen-2.5-Medium", "mesh_mode": "Raw", "quality": "medium"},
)
subscription_key = generation["jobs"]["subscription_key"]
task_uuid = generation["uuid"]
started_at = time.monotonic()
delay = 5
while True:
if time.monotonic() - started_at >= DEADLINE_SECONDS:
raise TimeoutError("Generation did not finish within 20 minutes")
time.sleep(delay)
status = request_with_rate_limit(
session,
"POST",
f"{BASE_URL}/status",
json={"subscription_key": subscription_key},
)
states = [job["status"] for job in status["jobs"]]
if "Failed" in states:
raise RuntimeError(f"Generation failed: {status}")
if states and all(state == "Done" for state in states):
break
delay = min(delay + 5, 30)
downloads = request_with_rate_limit(
session,
"POST",
f"{BASE_URL}/download",
json={"task_uuid": task_uuid},
)
print(downloads)