tripocli v2.0.0:Tripo AI 3D 生成与加工 CLI(面向 Agent 与开发者,纯 Python 标准库、零第三方依赖)

覆盖文生 3D、图生 3D、多视图、批量生成,以及重拓扑、绑定、动画、智能分割、
纹理、PBR、智能 UV、部件补全、格式导出与下载。

代码组织:一个功能一个模块(tripo/features/),入口薄壳 tripocli.py。
This commit is contained in:
Mrpzx committed 2026-10-13 19:22:54 +08:00
commit 977f97995a
60 files changed
+5622

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
"""Direct-to-S3 upload with AWS SigV4, using only the standard library.
The studio hands out temporary AWS credentials via
``POST /v2/studio/storage/temporary_token``; the browser then PUTs the raw bytes
straight to S3 (``https://{bucket}.{host}/{key}``). No boto3 required.
"""
import datetime
import hashlib
import hmac
import urllib.request
REGION = "us-west-2"
SERVICE = "s3"
def _sign(key, message):
return hmac.new(key, message.encode("utf-8"), hashlib.sha256).digest()
def upload_bytes(sts, data, content_type="application/octet-stream", timeout=120):
"""PUT ``data`` to the S3 object described by the STS response.
``sts`` is the ``data`` block of ``/v2/studio/storage/temporary_token``:
``sts_ak``, ``sts_sk``, ``session_token``, ``host``, ``resource_bucket``,
``resource_uri``.
"""
access_key = sts["sts_ak"]
secret_key = sts["sts_sk"]
session_token = sts["session_token"]
host = sts.get("host", "s3.us-west-2.amazonaws.com")
bucket = sts["resource_bucket"]
key = sts["resource_uri"]
now = datetime.datetime.now(datetime.timezone.utc)
amz_date = now.strftime("%Y%m%dT%H%M%SZ")
date_stamp = now.strftime("%Y%m%d")
host_header = f"{bucket}.{host}"
payload_hash = hashlib.sha256(data).hexdigest()
canonical_headers = (
f"host:{host_header}\n"
f"x-amz-content-sha256:{payload_hash}\n"
f"x-amz-date:{amz_date}\n"
f"x-amz-security-token:{session_token}\n"
)
signed_headers = "host;x-amz-content-sha256;x-amz-date;x-amz-security-token"
canonical_request = f"PUT\n/{key}\n\n{canonical_headers}\n{signed_headers}\n{payload_hash}"
scope = f"{date_stamp}/{REGION}/{SERVICE}/aws4_request"
string_to_sign = (
f"AWS4-HMAC-SHA256\n{amz_date}\n{scope}\n"
f"{hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()}"
)
k_date = _sign(("AWS4" + secret_key).encode("utf-8"), date_stamp)
k_region = _sign(k_date, REGION)
k_service = _sign(k_region, SERVICE)
k_signing = _sign(k_service, "aws4_request")
signature = hmac.new(k_signing, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()
authorization = (
f"AWS4-HMAC-SHA256 Credential={access_key}/{scope}, "
f"SignedHeaders={signed_headers}, Signature={signature}"
)
request = urllib.request.Request(
f"https://{host_header}/{key}",
data=data,
method="PUT",
headers={
"Host": host_header,
"x-amz-date": amz_date,
"x-amz-content-sha256": payload_hash,
"x-amz-security-token": session_token,
"Authorization": authorization,
"Content-Type": content_type,
},
)
with urllib.request.urlopen(request, timeout=timeout) as response:
return response.status in (200, 204)