Python SDK
Aholo OpenAPI 官方 Python SDK。
- 运行要求: Python ≥ 3.9
- PyPI: manycore-aholo-sdk-*
- GitHub: manycoretech/aholo-spatial-sdk
安装
按需安装,只装你用到的包:
pip install manycore-aholo-sdk-asset # 文件上传
pip install manycore-aholo-sdk-world # 世界重建与生成(v1.3.0+ 支持 insv)
pip install manycore-aholo-sdk-lux3d # Lux3D 3D 生成
鉴权
推荐: 通过环境变量设置,SDK 自动读取 AHOLO_API_KEY:
export AHOLO_API_KEY=your_api_key_here
也可在代码中显式传入:
from manycore.aholo_sdk_world import create_world_client
from manycore.aholo_sdk_core import AholoClientConfig
world = create_world_client(AholoClientConfig(api_key='your_api_key_here', region='cn'))
安全提示
请勿将 API Key 硬编码到源代码、安装包或公开仓库中。
区域
| 值 | 说明 | API 接入点 |
|---|---|---|
cn | 中国区 | https://api.aholo3d.cn |
com | 海外区 | https://api.aholo3d.com |
通用上传(Asset)
from manycore.aholo_sdk_asset import create_asset_client
asset = create_asset_client(region='cn')
上传文件
result = asset.upload_file('video.mp4')
print(result.url) # 公开访问 URL
上传字节
with open('image.jpg', 'rb') as f:
data = f.read()
result = asset.upload_bytes(data, filename='image.jpg')
带进度回调
def on_progress(uploaded: int, total: int) -> None:
pct = round(uploaded / total * 100)
print(f'\r上传进度: {pct}%', end='', flush=True)
result = asset.upload_file('video.mp4', on_progress=on_progress)
UploadResult 返回值
| 字段 | 类型 | 说明 |
|---|---|---|
url | str | 文件公开访问 URL |
md5 | str | 文件 MD5 |
upload_key | str | None | OUS upload key |
obs_task_id | str | None | OUS 任务 ID |
世界(World)
from manycore.aholo_sdk_world import create_world_client
world = create_world_client(region='cn')
重建 resources 的 type 支持 image、video、insv(manycore-aholo-sdk-world v1.3.0+)。生成 resources 仅支持 image(至多 1 条)。
3DGS 重建(从视频 / 图像)
op = world.reconstructions.create(
name='客厅',
resources=[{'url': 'https://cdn.example.com/room.mp4', 'type': 'video'}],
task_quality='normal', # 'low' | 'normal' | 'high'
scene='model', # 'model' | 'space'
use_mask=False, # 可选:true 时对上传资源抠图
)
detail = world.wait_for(op['worldId'])
print(detail.get('assets', {}).get('splats', {}).get('urls', {}).get('plyPath'))
图片重建要求
使用图片重建时,resources 中图片类资源须 ≥ 20 条(type 为 image,扩展名 .jpg/.jpeg/.png/.webp)。普通视频用 type=video(.mp4/.mov);Insta360 全景用 type=insv(.insv)。URL 扩展名须与 type 一致。
Insta360 示例:
op = world.reconstructions.create(
name='全景客厅',
resources=[{'url': 'https://cdn.example.com/room.insv', 'type': 'insv'}],
task_quality='high',
scene='space',
)
3DGS 生成(从文字描述)
生成接口 resources 仅支持图片(type 为 image,至多 1 条),不支持 video / insv。
op = world.generations.create(
name='森林小屋',
prompt='森林中的现代风格小木屋',
# resources=[{'url': 'https://cdn.example.com/ref.jpg', 'type': 'image'}], # 可选,至多 1 张
)
detail = world.wait_for(op['worldId'])
查询世界详情
detail = world.retrieve(world_id)
print(detail.get('status'))
任务状态与轮询
| 阶段 | 状态值 | 说明 |
|---|---|---|
| 进行中 | PENDING | 排队中 |
| 进行中 | PREPROCESSING | 预处理中 |
| 进行中 | RUNNING | 执行中 |
| 成功终态 | SUCCEEDED | 成功 |
| 失败终态 | FAILED | 失败 |
| 失败终态 | CANCELED | 已取消 |
| 失败终态 | TIMEOUT | 超时 |
| 失败终态 | REJECTED | 被拒绝 |
world.wait_for(world_id) 在 SUCCEEDED 时返回详情;遇到失败终态时抛出 PollingFailedError。
WorldDetail 主要字段
| 字段 | 类型 | 说明 |
|---|---|---|
worldId | str | 世界 ID |
status | str | 任务状态 |
assets.splats.urls.plyPath | str | None | PLY 下载 URL |
assets.splats.urls.spzPath | str | None | SPZ 下载 URL |
assets.splats.urls.lodMetaPath | str | None | LOD 元数据 URL |
assets.imagery.panoUrl | str | None | AI 生成全景图 URL |
assets.semanticsMetadata.upAxis | str | None | 世界上轴(Y / Z) |
Lux3D
以下接口需要 manycore-aholo-sdk-lux3d 1.7.0 或更高版本。
from manycore.aholo_sdk_lux3d import create_lux3d_client
lux3d = create_lux3d_client(region='cn')
多模态生图
img 与 prompt 至少一个。
task_id = lux3d.multimodal_to_image.create(
prompt='木椅产品图,白色背景',
img='https://example.com/object.jpg',
)
result = lux3d.tasks.wait_for(task_id)
task_id = lux3d.multimodal_to_image.create_from_file(
'./object.jpg',
prompt='木椅产品图,白色背景',
)
生成四视图
img 与 prompt 至少一个;可只传文案,也可图文组合。
task_id = lux3d.image_to_four_view.create(
img='https://example.com/object.jpg',
prompt='产品四视图,白色背景',
)
result = lux3d.tasks.wait_for(task_id)
图像转 3D
task_id = lux3d.img_to_3d.create(
img='https://example.com/object.jpg',
version='G1', # 必填:G1 或 G1-Turbo
face_count=200_000,
output_format=['zip', 'glb', 'ply'],
ai_predict_size=True,
)
# 从本地文件
task_id = lux3d.img_to_3d.create_from_file('./object.jpg', version='G1-Turbo')
result = lux3d.tasks.wait_for(task_id)
print(result['outputs'][0]['content']) # 下载 URL
文字转 3D
task_id = lux3d.text_to_3d.create(
prompt='带雕花腿的木椅',
version='G1',
style='photorealistic', # 见下方风格列表
)
result = lux3d.tasks.wait_for(task_id)
文字转 3D 风格:
photorealistic(写实,默认)| cartoon(卡通)| anime(动漫)| hand_painted(手绘)| cyberpunk(赛博朋克)| fantasy(奇幻)| glass(玻璃)
多格式导出
task_id = lux3d.multi_format_export.create(
model_url='https://example.com/model.glb',
output_format=['usdz', 'obj_zip', 'stl'], # GLB 输入时不能为空;另支持 fbx_zip、3mf
)
result = lux3d.tasks.wait_for(task_id)
查询历史任务
page = lux3d.tasks.list(
page=1,
page_size=20,
status=3, # 可选筛选:0 初始化、1 进行中、3 成功、4 失败;结果中仍可能出现 6 已取消
# start_time / end_time:可选 Unix 毫秒时间戳
)
for task in page['items']:
print(task['taskId'], task['status'])
材质迁移
task_id = lux3d.material_transfer.create(
img='https://example.com/material.jpg',
mesh_url='https://example.com/model.glb',
version='v3.0-standard',
ai_predict_size=True,
)
result = lux3d.tasks.wait_for(task_id)
生成参数
- 图生/文生 3D 的
version必填:G1或G1-Turbo。 face_count范围 10_000–300_000,默认 200_000;不影响 PLY。output_format支持zip/glb/ply;ai_predict_size默认True。- G1-Turbo 的 ZIP/GLB 输出可用
enable_pbr控制材质;图生 3D 的img/imgs必须二选一。
Lux3dTaskResult 返回值
| 字段 | 类型 | 说明 |
|---|---|---|
taskId | int | 任务 ID |
status | int | 0 初始化;1 进行中;3 成功;4 失败;6 已取消 |
outputs | list |