# SDK 调用

使用 Tripo 官方 SDK 提交文本生成模型任务、等待任务完成、验证终态，并下载生成的模型。以下安装来源已锁定为验证本页面时使用的版本。

## 支持的 SDK

| 语言 | API | 锁定版本 | 安装来源 |
| --- | --- | --- | --- |
| JavaScript / TypeScript | V3 | [`e351348`](https://github.com/VAST-AI-Research/tripo-js-sdk/tree/e35134801b339caac0b84f36fe02d08e73e217b2) | 官方 Git commit |
| Python | V2 + limited V3 | [`v0.4.2`](https://github.com/VAST-AI-Research/tripo-python-sdk/tree/v0.4.2) | PyPI `tripo3d==0.4.2` |
| Go | V3 | [`2c8c8d4`](https://github.com/VAST-AI-Research/tripo-go-sdk/tree/2c8c8d4e6a9e1fc9e49699fc055140eca689ee79) | Go 伪版本 `v0.0.0-20260713072120-2c8c8d4e6a9e` |
| Rust | V3 | [`f992f6a`](https://github.com/VAST-AI-Research/tripo-rust-sdk/tree/f992f6a7cf7a28c10781f9fa28e4630c7802291c) | Cargo Git 依赖 |
| Java | V3 | [`7b6a68d`](https://github.com/VAST-AI-Research/tripo-java-sdk/tree/7b6a68d855e01a0b098775b1ee14ce7f3c8ac7d9) | 源码构建；本地 Maven `0.1.0-SNAPSHOT` |

## 1. 配置 API Key 与地域

在 [Tripo 控制台](https://platform.tripo3d.ai/)创建密钥，并且只向服务端进程提供。不要将 API Key 放入浏览器代码或提交到源码仓库。

```bash
export TRIPO_API_KEY="tsk_..."
```

JavaScript、Go 和 Rust 在全球区域使用 `https://openapi.tripo3d.ai/v3`，在中国区域使用 `https://openapi.tripo3d.com/v3`。Java 选择 `TripoRegion.GLOBAL` 或 `TripoRegion.CN`；SDK 从对应的 `.ai` 或 `.com` 源站开始，并拼接 `/v3`。Python 0.4.2 的主 V2 客户端在全球区域使用 `https://api.tripo3d.ai/v2/openapi`，在中国区域使用 `https://api.tripo3d.com/v2/openapi`；其有限的 V3 分割流程还会使用对应的 `https://openapi.tripo3d.ai` 或 `.com` 源站。

## 2. 安装 SDK

从各 SDK 锁定的生产来源进行安装。

### JavaScript

```bash
npm install github:VAST-AI-Research/tripo-js-sdk#e35134801b339caac0b84f36fe02d08e73e217b2
```

### Python

```bash
python -m pip install tripo3d==0.4.2
```

### Go

```bash
go get github.com/VAST-AI-Research/tripo-go-sdk@v0.0.0-20260713072120-2c8c8d4e6a9e
```

### Rust

```toml
[dependencies]
tripo3d-sdk = { git = "https://github.com/VAST-AI-Research/tripo-rust-sdk.git", rev = "f992f6a7cf7a28c10781f9fa28e4630c7802291c" }
tokio = { version = "1", features = ["full"] }
anyhow = "1"
```

### Java

```bash
git clone https://github.com/VAST-AI-Research/tripo-java-sdk.git
cd tripo-java-sdk
git checkout 7b6a68d855e01a0b098775b1ee14ce7f3c8ac7d9
./mvnw install
```

Java 构建会将 `ai.tripo3d:tripo-sdk:0.1.0-SNAPSHOT` 安装到本地 Maven 仓库。源码构建完成后，在应用中添加该坐标。

## 3. 提交、等待并下载

每个服务端示例都会读取 `TRIPO_API_KEY`、提交文本生成模型任务、等待终态、检查任务是否成功，并立即保存主模型。生成的模型 URL 是临时地址。

### JavaScript

```javascript
import { writeFile } from 'node:fs/promises';
import { TripoClient, ModelVersion, TaskStatus } from 'tripo3d-sdk-js';

const apiKey = process.env.TRIPO_API_KEY;
if (!apiKey) throw new Error('TRIPO_API_KEY is required');

const client = new TripoClient({
  apiKey,
  baseUrl: 'https://openapi.tripo3d.ai/v3',
});

const taskId = await client.textToModel({
  prompt: 'a cute red panda holding bamboo',
  model: ModelVersion.H3_1,
  texture: true,
  pbr: true,
  texture_quality: 'detailed',
});

const task = await client.waitForTask(taskId, {
  pollingIntervalMs: 2000,
  onProgress: (value) => console.log(`${value.status} — ${value.progress ?? 0}%`),
});

if (task.status !== TaskStatus.SUCCESS) {
  throw new Error(`Task did not succeed: ${task.status}`);
}

const modelUrl = task.output.model_url ?? task.output.model;
if (!modelUrl) throw new Error('Task returned no model URL');

const response = await fetch(modelUrl);
if (!response.ok) throw new Error(`Download failed: HTTP ${response.status}`);

await writeFile(`tripo-${taskId}.glb`, Buffer.from(await response.arrayBuffer()));
```

### Python

```python
import asyncio
import os
import shutil
from urllib.request import urlopen

from tripo3d import TripoClient
from tripo3d.models import TaskStatus


def download_file(url, path):
    with urlopen(url) as response, open(path, "wb") as output:
        shutil.copyfileobj(response, output)


async def main():
    api_key = os.environ["TRIPO_API_KEY"]
    os.makedirs("./output", exist_ok=True)

    async with TripoClient(api_key=api_key) as client:
        task_id = await client.text_to_model(
            prompt="a cute red panda holding bamboo",
            model_version="v2.5-20250123",
        )
        task = await client.wait_for_task(task_id, verbose=True)

        if task.status != TaskStatus.SUCCESS:
            raise RuntimeError(f"Task did not succeed: {task.status}")

        model_url = task.output.model
        if not model_url:
            raise RuntimeError("Task returned no model URL")

        output_path = "./output/model.glb"
        await asyncio.to_thread(download_file, model_url, output_path)
        print(f"Downloaded model: {output_path}")


asyncio.run(main())
```

### Go

```go
package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	tripo3d "github.com/VAST-AI-Research/tripo-go-sdk"
)

func main() {
	apiKey := os.Getenv("TRIPO_API_KEY")
	if apiKey == "" {
		log.Fatal("TRIPO_API_KEY is required")
	}

	client, err := tripo3d.NewClient(tripo3d.ClientOptions{
		APIKey:  apiKey,
		BaseURL: "https://openapi.tripo3d.ai/v3",
	})
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	taskID, err := client.TextToModel(ctx, tripo3d.TextToModelParams{
		Prompt:         "a cute red panda holding bamboo",
		Model:          tripo3d.String(tripo3d.ModelVersionH31),
		Texture:        tripo3d.Bool(true),
		PBR:            tripo3d.Bool(true),
		TextureQuality: tripo3d.String("detailed"),
	})
	if err != nil {
		log.Fatal(err)
	}

	task, err := client.WaitForTask(ctx, taskID, tripo3d.WaitOptions{
		PollInterval: 2 * time.Second,
	})
	if err != nil {
		log.Fatal(err)
	}
	if task.Status != tripo3d.TaskStatusSuccess {
		log.Fatalf("Task did not succeed: %s", task.Status)
	}

	downloaded, err := client.DownloadModel(ctx, task)
	if err != nil {
		log.Fatal(err)
	}
	if downloaded == nil {
		log.Fatal("Task returned no model URL")
	}

	filename := fmt.Sprintf("tripo-%s.glb", taskID)
	if err := os.WriteFile(filename, downloaded.Data, 0o644); err != nil {
		log.Fatal(err)
	}
}
```

### Rust

```rust
use tokio::fs;
use tripo3d_sdk::{
    constants::model_version,
    params::TextToModelParams,
    ClientOptions,
    TaskStatus,
    TripoClient,
    WaitOptions,
};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let api_key = std::env::var("TRIPO_API_KEY")?;
    let client = TripoClient::new(ClientOptions {
        api_key: Some(api_key),
        base_url: Some("https://openapi.tripo3d.ai/v3".into()),
        ..Default::default()
    })?;

    let task_id = client
        .text_to_model(TextToModelParams {
            prompt: "a cute red panda holding bamboo".into(),
            model: Some(model_version::H3_1.to_string()),
            texture: Some(true),
            pbr: Some(true),
            texture_quality: Some("detailed".into()),
            ..Default::default()
        })
        .await?;

    let task = client
        .wait_for_task(&task_id, WaitOptions::default())
        .await?;
    if task.status != TaskStatus::Success {
        anyhow::bail!("Task did not succeed: {}", task.status);
    }

    let downloaded = client
        .download_model(&task)
        .await?
        .ok_or_else(|| anyhow::anyhow!("Task returned no model URL"))?;

    fs::write(format!("tripo-{task_id}.glb"), downloaded.data).await?;
    Ok(())
}
```

### Java

```java
import ai.tripo3d.sdk.api.TripoClient;
import ai.tripo3d.sdk.api.TripoClientConfig;
import ai.tripo3d.sdk.api.TripoRegion;
import ai.tripo3d.sdk.model.request.TaskRequestPayload;
import ai.tripo3d.sdk.model.response.TaskDetail;

import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Map;

public final class TripoQuickStart {
    public static void main(String[] args) throws Exception {
        String apiKey = System.getenv("TRIPO_API_KEY");
        if (apiKey == null || apiKey.trim().isEmpty()) {
            throw new IllegalStateException("TRIPO_API_KEY is required");
        }

        try (TripoClient client = TripoClient.create(
                TripoClientConfig.builder(apiKey)
                        .region(TripoRegion.GLOBAL)
                        .build())) {
            TaskDetail created = client.textToModel(TaskRequestPayload.builder()
                    .prompt("a wooden chair")
                    .model("v3.1-20260211")
                    .build());

            TaskDetail done = client.pollUntilTerminal(created.taskId());
            if (!"success".equalsIgnoreCase(done.status())) {
                throw new IllegalStateException(
                        "Task failed: status=" + done.status()
                                + ", message=" + done.errorMsg());
            }

            Map<String, Object> output = done.output();
            Object modelUrl = output == null ? null : output.get("model_url");
            if (!(modelUrl instanceof String)) {
                throw new IllegalStateException(
                        "Task output does not contain model_url");
            }

            try (InputStream input =
                         new URL((String) modelUrl).openStream()) {
                Files.copy(
                        input,
                        Paths.get("model.glb"),
                        StandardCopyOption.REPLACE_EXISTING);
            }
        }
    }
}
```

JavaScript、Python 和 Java 特意使用原生 HTTP 客户端获取签名模型 URL，并且不附加 `Authorization` 请求头。Go 和 Rust SDK 的下载方法同样不会在获取签名 URL 时携带 API Key。

## 4. V3 路由支持

该矩阵是上述锁定版本中五个 SDK 实现的并集。勾号表示某个公开 SDK 流程会直接或通过内部步骤访问最终的 V3 HTTP 路由；未使用的路由常量不计入支持。

| HTTP 路由 | 用途 | JavaScript | Python | Go | Rust | Java |
| --- | --- | :---: | :---: | :---: | :---: | :---: |
| `POST /v3/generation/text-to-model` | 根据文本生成模型 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/image-to-model` | 根据单张图像生成模型 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/multiview-to-model` | 根据多个视图生成模型 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/text-to-image` | 根据文本生成图像 | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-image` | 转换图像 | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-multiview` | 生成多视图图像 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/edit-multiview` | 编辑多视图输出 | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-splat` | 生成高斯泼溅模型 | — | — | — | — | ✓ |
| `POST /v3/models/refine` | 优化草模 | — | — | — | — | ✓ |
| `POST /v3/models/texture` | 应用或重新生成纹理 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/models/stylize` | 风格化模型 | — | — | — | — | ✓ |
| `POST /v3/models/convert` | 转换模型格式 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/models/import` | 导入外部模型 | — | — | — | — | ✓ |
| `POST /v3/mesh/segment` | 分割网格 | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/mesh/complete` | 补全或修复网格 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/mesh/decimate` | 减少面数 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/rig-check` | 检查模型是否可以绑定骨骼 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/rig` | 绑定骨骼 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/retarget` | 应用预设动画 | ✓ | — | ✓ | ✓ | ✓ |
| `GET /v3/tasks/{task_id}` | 获取单个任务 | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/tasks/list` | 获取多个任务 | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/files` | 上传文件 | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/files/presign` | 创建预签名上传 | — | — | — | — | ✓ |
| `GET /v3/account/balance` | 获取账户余额 | ✓ | — | ✓ | ✓ | ✓ |
| `GET /v3/account/usage` | 获取用量历史 | — | — | — | — | ✓ |

在该锁定版本中，只有 Java 公开了 image-to-splat、refine、stylize、import、presign 和 usage。Java 不提供 text-to-image、image-to-image 或 edit-multiview。其内部虽然声明了 `/v3/files/upload-credentials` 描述符，但没有对应的服务或公开客户端方法，因此不计为支持。

Python 仍以 V2 为主。仅当调用 `mesh_segmentation(..., model_version="v2.0-20260430")` 时，它还会使用 `POST /v3/mesh/segment`、`GET /v3/tasks/{task_id}`，并在需要上传本地 `ref_image` 时使用 `POST /v3/files`。

### Python V2 路由支持

Python 0.4.2 共公开五条最终 V2 HTTP 路由。`POST /v2/openapi/task` 由生成、模型处理、网格和动画任务方法共用，并不只用于文本生成模型。

| HTTP 路由 | 用途 |
| --- | --- |
| `POST /v2/openapi/task` | 提交任意受支持的 V2 任务 |
| `GET /v2/openapi/task/{task_id}` | 查询任务状态和输出 |
| `GET /v2/openapi/user/balance` | 获取账户余额 |
| `POST /v2/openapi/upload/sts/token` | 在 `boto3` 可用时获取 STS 上传凭证 |
| `POST /v2/openapi/upload` | SDK 使用旧版 multipart 回退方案时上传文件 |

Java 和其他 V3 SDK 通过各自的官方 V3 参数模型发送模型选择。Java 线上请求中的字段名为 `model`。

## 5. 故障排查

- **缺少密钥：** 在服务端进程中设置 `TRIPO_API_KEY`。请参阅[身份认证](./authentication)。
- **地域错误：** 根据正在使用的 SDK 和 API 版本选择匹配的全球或中国区域端点。
- **任务失败或超时：** 保留 `task_id`，检查任务终态，并参阅[任务生命周期](./task-lifecycle)和[错误处理](./error-handling)。
- **模型 URL 已过期：** 如果 SDK 支持，请重新查询任务，然后立即下载模型。不要将临时签名 URL 作为永久资源保存。

## 官方仓库

- [JavaScript SDK](https://github.com/VAST-AI-Research/tripo-js-sdk)
- [Python SDK](https://github.com/VAST-AI-Research/tripo-python-sdk)
- [Go SDK](https://github.com/VAST-AI-Research/tripo-go-sdk)
- [Rust SDK](https://github.com/VAST-AI-Research/tripo-rust-sdk)
- [Java SDK](https://github.com/VAST-AI-Research/tripo-java-sdk)
