优化 img 转3D 相应代码

This commit is contained in:
zcr
2026-04-14 17:23:30 +08:00
parent 417c6f01b5
commit 70ddf97484
2 changed files with 76 additions and 40 deletions

View File

@@ -234,21 +234,39 @@ async def triop_api_img_to_3D(request_data: Tripo3dApiModel, background_tasks: B
}
}
```
### 错误输出
参考文档: https://platform.tripo3d.ai/docs/error-handling
```json
{
"code": 2010,
"msg": "OK!",
"data": {
"code": 2010,
"message": "You don't have enough credit to create this task",
"suggestion": "Please purchase more credit",
"success": false
}
}
```
"""
logger.info(f"img_to_3D_v2 request: {json.dumps(request_data.model_dump(), indent=4)}")
if request_data.model == "single":
api_task_id = await create_single_task(input_data=request_data)
task_resp = await create_single_task(input_data=request_data)
else:
api_task_id = await create_multi_task(input_data=request_data)
task_resp = await create_multi_task(input_data=request_data)
background_tasks.add_task(get_task_result_async, request_data, request_data.task_id, api_task_id, request_data.callback_url)
result = {
"state": "success",
"task_id": request_data.task_id,
"message": "任务已成功提交,正在后台处理...",
}
state_code = 200
return ResponseModel(data=result, code=state_code)
if task_resp.get("state") == "success":
api_task_id = task_resp.get("task_id")
background_tasks.add_task(get_task_result_async, request_data, request_data.task_id, api_task_id, request_data.callback_url)
result = {
"state": "success",
"task_id": request_data.task_id,
"message": "任务已成功提交,正在后台处理...",
}
state_code = 200
return ResponseModel(data=result, code=state_code)
else:
return ResponseModel(data=task_resp, code=task_resp.get("code"))
# @router.post("/img_to_3D")
# async def img_to_3D(request_data: ImageTo3DRequest):

View File

@@ -44,26 +44,29 @@ class Triop3dApiServer:
return self.async_client
async def request_json(self, method: str, endpoint: str, request_timeout: float, **kwargs) -> Dict[str, Any]:
"""异步请求核心方法"""
"""异步请求核心方法 - 直接返回原始 resp成功或失败都不抛异常"""
url = f"{self.base_url}{endpoint}"
client = await self._get_client()
try:
resp = await client.request(method=method, url=url, timeout=request_timeout, **kwargs)
except httpx.RequestError as e:
raise TripoAPIError(f"请求失败: {method} {url} | {e}") from e
if not resp.is_success:
try:
err_payload = resp.json()
except Exception:
err_payload = resp.text
raise TripoAPIError(f"HTTP {resp.status_code} | {method} {url} | {extract_error_message(err_payload)}")
# 网络层错误也包装成类似 API 的格式返回
return {
"code": -1,
"message": f"网络请求失败: {method} {url}",
"detail": str(e)
}
try:
return resp.json()
except Exception as e:
raise TripoAPIError(f"响应不是合法 JSON: {method} {url}") from e
except Exception:
# 非 JSON 返回也包装返回
return {
"code": -2,
"message": f"响应不是合法 JSON: HTTP {resp.status_code}",
"raw": resp.text[:500] # 截取一部分避免过长
}
async def upload_image(self, image_path: str, request_timeout: float) -> str:
"""
@@ -107,7 +110,6 @@ class Triop3dApiServer:
request_timeout=request_timeout,
files=files
)
data = payload.get("data") or {}
file_token = data.get("image_token")
@@ -152,13 +154,34 @@ class Triop3dApiServer:
return file_tokens
async def create_task(self, payload: Dict[str, Any], request_timeout: float) -> str:
async def create_task(self, payload: Dict[str, Any], request_timeout: float) -> Dict[str, Any]:
"""
创建任务
- 成功时返回原始响应(包含 code: 0 和 data.task_id
- 失败时也返回原始响应并确保错误码code被带上
"""
resp = await self.request_json("POST", "/task", request_timeout=request_timeout, json=payload)
data = resp.get("data") or {}
task_id = data.get("task_id")
if not task_id:
raise TripoAPIError(f"未返回 task_id: {json.dumps(resp, ensure_ascii=False)}")
return task_id
# 如果是成功响应(通常 code == 0直接返回
if isinstance(resp, dict) and resp.get("code") == 0:
return resp
# 失败情况:确保错误码存在,并返回完整响应(不抛异常)
if not isinstance(resp, dict):
resp = {"code": -3, "message": "未知错误", "raw_response": str(resp)}
# 如果响应中没有 code 字段,补充一个
if "code" not in resp:
resp["code"] = resp.get("error", {}).get("code") or -999
# 可选:统一加上一个更明显的错误标识(方便上层判断)
if resp.get("code") != 0:
resp.setdefault("success", False)
# 如果有 suggestion可以保留
if "suggestion" not in resp and isinstance(resp.get("error"), dict):
resp["suggestion"] = resp["error"].get("suggestion")
return resp
# step 3 查询任务状态
async def poll_task(self, task_id: str, poll_interval: float, poll_timeout: float, request_timeout: float, callback_url: str) -> Dict[str, Any]:
@@ -456,7 +479,7 @@ def load_mesh_from_minio(object_name: str, bucket_name: str = "fida-user"):
return vertices
async def create_single_task(input_data: Tripo3dApiModel) -> str:
async def create_single_task(input_data: Tripo3dApiModel):
"""
异步版本:创建单个图片转 3D 的任务
"""
@@ -490,19 +513,17 @@ async def create_single_task(input_data: Tripo3dApiModel) -> str:
payload = input_payload | input_data.model_dump(exclude_unset=True)
# Step 3: 提交任务(异步)
print("正在提交 Tripo3D 任务...")
logger.info("正在提交 Tripo3D 任务...")
task_id = await server.create_task(
resp = await server.create_task(
payload=payload,
request_timeout=input_data.request_timeout
)
print(f"✅ 任务创建成功 | task_id: {task_id}")
logger.info(f"✅ 任务创建成功 | task_id: {task_id}")
return task_id
return resp
async def create_multi_task(input_data: Tripo3dApiModel) -> str:
async def create_multi_task(input_data: Tripo3dApiModel):
"""
异步版本:创建多图转 3D 的任务
"""
@@ -546,12 +567,9 @@ async def create_multi_task(input_data: Tripo3dApiModel) -> str:
# Step 3: 提交任务(异步)
logger.info(f"正在提交多图 Tripo3D 任务...{payload}")
print(f"正在提交多图 Tripo3D 任务...{payload}")
task_id = await server.create_task(payload=payload, request_timeout=input_data.request_timeout)
resp = await server.create_task(payload=payload, request_timeout=input_data.request_timeout)
logger.info(f"✅ 多图任务创建成功 | task_id: {task_id}")
print(f"✅ 多图任务创建成功 | task_id: {task_id}")
return task_id
return resp
async def get_task_result_async(input_data: Tripo3dApiModel, task_id: str, api_task_id: str, callback_url: str):