CSVからのアセット一括インポート
このガイドでは、CSVファイルからtwin内にRealityAssetを一括作成する方法を示します。各行はアセット名と、twin空間内の向き付きバウンディングボックスを定義します。このワークフローでは、Client Credentialsフローと write:asset スコープを使用します。
- Client Credentials 用に設定されたOAuthアプリケーション
- スコープ:
read:basic、read:hierarchy、write:asset client_idとclient_secret- 対象twinへのコンテンツアクセスと編集権限
- アセットを作成するtwin ID
このパターンを使用する場合
Section titled “このパターンを使用する場合”Prevu3D外で既にアセット定義を持っている場合に、CSV駆動のインポートを使用します。例:
- 3D座標付きでCMMSやERPシステムからエクスポートされた機器リスト
- 外部ツールからの調査またはタグ付け結果
- twin座標でアセットが配置されていた別プラットフォームからの移行
各API呼び出しで1つのアセットが作成されます。スクリプトはCSV行をループし、各エントリに対して POST /v1/twin/{twinId}/assets を呼び出します。
スプレッドシートにはヘッダー行が必要です。必須列:
| 列 | マッピング先 | 説明 |
|---|---|---|
Description | アセット name | RealityAssetの表示名 |
Manual_X | ボックス中心 x | twin空間におけるボックス中心のX座標 |
Manual_Y | ボックス中心 y | twin空間におけるボックス中心のY座標 |
Manual_Z | ボックス中心 z | twin空間におけるボックス中心のZ座標 |
Manual_Box_X | ボックスサイズ x | バウンディングボックスの幅 |
Manual_Box_Y | ボックスサイズ y | バウンディングボックスの奥行き |
Manual_Box_Z | ボックスサイズ z | バウンディングボックスの高さ |
例:
Description,Manual_X,Manual_Z,Manual_Y,Manual_Box_X,Manual_Box_Z,Manual_Box_YPump A,6.27,-5.10,187.12,0.35,0.64,0.33Valve B,8.84,-3.14,189.41,2.99,1.11,4.69座標はtwinと同じ座標系である必要があります。RealityTwinでアセットを手動配置した場合は、twin空間の値をエクスポートまたは記録してください。回転はデフォルトで単位クォータニオンです。向き付きボリュームが必要な場合は、各ボックスにオプションの rotation クォータニオンを指定できます。
エンドツーエンドのフロー
Section titled “エンドツーエンドのフロー”flowchart LR A["1. 認証"] --> B["2. CSV行を読み取り"] B --> C["3. workingStructureを構築"] C --> D["4. 行ごとにアセットをPOST"] D --> E["5. 結果を確認"]
| ステップ | エンドポイント | 取得内容 |
|---|---|---|
| 認証 | POST /oauth/token | アクセストークン |
| API URLの解決 | GET /oauth/api-info | リージョンの apiUrl |
| アセットの作成 | POST /v1/twin/{twinId}/assets | 行ごとの新しいアセットID |
アセットペイロードの形式
Section titled “アセットペイロードの形式”各行は、単一の向き付きボックスを含む workingStructure を持つ1つのアセットになります:
{ "name": "Pump A", "workingStructure": { "boxes": [ { "center": { "x": 6.27, "y": 187.12, "z": -5.10 }, "size": { "x": 0.35, "y": 0.33, "z": 0.64 }, "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 } } ] }}作成時にアセットタイプを割り当てるには、組織で設定されたタイプのUUIDを assetTypeId に追加します。RealityPlatformでタイプが定義される方法については、アセットタイプを参照してください。
ステップ1 — 認証
Section titled “ステップ1 — 認証”Client Credentialsでアクセストークンを取得します:
POST https://cloud-api.prevu3d.com/oauth/tokenAuthorization: Basic base64(client_id:client_secret)Content-Type: application/x-www-form-urlencoded
grant_type=client_credentialsGET https://cloud-api.prevu3d.com/oauth/api-infoAuthorization: Bearer {access_token}ステップ2 — CSVからアセットを作成
Section titled “ステップ2 — CSVからアセットを作成”POST {api_url}/v1/twin/{twinId}/assetsAuthorization: Bearer {access_token}Content-Type: application/json
{ "name": "Pump A", "workingStructure": { "boxes": [ { "center": { "x": 6.27, "y": 187.12, "z": -5.10 }, "size": { "x": 0.35, "y": 0.33, "z": 0.64 }, "rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 } } ] }}成功レスポンスには、作成されたアセットとその id が返されます。各CSV行に対して繰り返してください。
import base64import csvfrom pathlib import Path
import requests
CLIENT_ID = "your-client-id"CLIENT_SECRET = "your-client-secret"CLOUD_API_BASE = "https://cloud-api.prevu3d.com"TWIN_ID = "your-twin-id"CSV_FILE = Path("assets.csv")
credentials = base64.b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode()token_response = requests.post( f"{CLOUD_API_BASE}/oauth/token", data={"grant_type": "client_credentials"}, headers={"Authorization": f"Basic {credentials}"},)token_response.raise_for_status()access_token = token_response.json()["access_token"]headers = {"Authorization": f"Bearer {access_token}"}
api_info = requests.get(f"{CLOUD_API_BASE}/oauth/api-info", headers=headers).json()api_url = api_info["apiUrl"].rstrip("/")
def api_post(path: str, body: dict) -> dict: response = requests.post(f"{api_url}{path}", json=body, headers=headers) response.raise_for_status() return response.json()
def oriented_box(cx: float, cy: float, cz: float, sx: float, sy: float, sz: float) -> dict: return { "center": {"x": cx, "y": cy, "z": cz}, "size": {"x": sx, "y": sy, "z": sz}, "rotation": {"x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0}, }
with CSV_FILE.open(newline="", encoding="utf-8") as handle: rows = list(csv.DictReader(handle))
created = []errors = []
for row in rows: name = row["Description"].strip() body = { "name": name, "workingStructure": { "boxes": [ oriented_box( cx=float(row["Manual_X"]), cy=float(row["Manual_Y"]), cz=float(row["Manual_Z"]), sx=float(row["Manual_Box_X"]), sy=float(row["Manual_Box_Y"]), sz=float(row["Manual_Box_Z"]), ) ] }, }
try: asset = api_post(f"/v1/twin/{TWIN_ID}/assets", body) print(f"[OK] {name} -> {asset['id']}") created.append(asset) except requests.HTTPError as error: print(f"[ERR] {name} -> {error.response.status_code} {error.response.text}") errors.append(name)
print(f"\nCreated: {len(created)} / Errors: {len(errors)}")twin IDの見つけ方
Section titled “twin IDの見つけ方”twin IDは、コンテンツ階層内のtwinノードのUUIDです。次の方法で取得できます:
- twinを開いたときのRealityPlatform URLからコピー
GET /v1/nodes/{organizationId}/browseで階層を参照し、type: "Twin"のノードを見つける
大量インポートのヒント
Section titled “大量インポートのヒント”- 適切なバッチ処理。 APIはリクエストごとに1つのアセットを作成します。数百行の場合は、レート制限に達したら短い遅延やバックオフを追加してください。
- 座標を先に検証。 ファイル全体を実行する前に、1行だけテストインポートしてください。
- RealityTwinのDraft Mode を使用すると、他のユーザーに表示される前にアセットを確認できます。統合がドラフトワークフローを対象としない限り、API経由で作成されたアセットはtwinにすぐに表示されます。
- メタデータは後から添付。 作成後は
PATCH /v1/twin/{twinId}/assets/{assetId}/metadataを使用してプロパティ値を追加します。アセットエンドポイントについてはAPIリファレンスを参照してください。
次のステップ
Section titled “次のステップ”- Client Credentialsフローガイドで認証を設定します。
- twinワークスペースでのアセットの仕組みを学ぶ: RealityAssetの操作。
- APIリファレンスでアセットエンドポイントを参照します。