Ir al contenido

Importación masiva de activos desde un CSV

Esta guía muestra cómo crear RealityAssets de forma masiva en un twin a partir de un archivo CSV. Cada fila define el nombre de un activo y un cuadro delimitador orientado en el espacio del twin. El flujo de trabajo usa el flujo de Client Credentials y el ámbito write:asset.


  • Una aplicación OAuth configurada para Client Credentials
  • Ámbitos: read:basic, read:hierarchy, write:asset
  • Tu client_id y client_secret
  • Acceso al contenido y permisos de edición sobre el twin de destino
  • El ID del twin donde deben crearse los activos

Usa una importación basada en CSV cuando ya tengas definiciones de activos fuera de Prevu3D, por ejemplo:

  • Listas de equipos exportadas desde un sistema CMMS o ERP con coordenadas 3D
  • Resultados de inspección o etiquetado desde una herramienta externa
  • Migración desde otra plataforma donde los activos se posicionaron en coordenadas del twin

Cada llamada a la API crea un activo. Un script recorre las filas del CSV y llama a POST /v1/twin/{twinId}/assets por cada entrada.

La hoja de cálculo debe incluir una fila de encabezado. Columnas obligatorias:

ColumnaSe asigna aDescripción
Descriptionname del activoNombre para mostrar del RealityAsset
Manual_Xx del centro del cuadroCoordenada X del centro del cuadro en el espacio del twin
Manual_Yy del centro del cuadroCoordenada Y del centro del cuadro en el espacio del twin
Manual_Zz del centro del cuadroCoordenada Z del centro del cuadro en el espacio del twin
Manual_Box_Xx del tamaño del cuadroAncho del cuadro delimitador
Manual_Box_Yy del tamaño del cuadroProfundidad del cuadro delimitador
Manual_Box_Zz del tamaño del cuadroAltura del cuadro delimitador

Ejemplo:

Description,Manual_X,Manual_Z,Manual_Y,Manual_Box_X,Manual_Box_Z,Manual_Box_Y
Pump A,6.27,-5.10,187.12,0.35,0.64,0.33
Valve B,8.84,-3.14,189.41,2.99,1.11,4.69

Las coordenadas deben estar en el mismo sistema de coordenadas que el twin. Si posicionaste los activos manualmente en RealityTwin, exporta o registra los valores en el espacio del twin. La rotación adopta por defecto la identidad; la API acepta un cuaternión rotation opcional en cada cuadro si necesitas volúmenes orientados.

flowchart LR
  A["1. Authenticate"] --> B["2. Read CSV rows"]
  B --> C["3. Build workingStructure"]
  C --> D["4. POST asset per row"]
  D --> E["5. Review results"]
PasoEndpointQué obtienes
AutenticarPOST /oauth/tokenToken de acceso
Resolver la URL de la APIGET /oauth/api-infoapiUrl regional
Crear activoPOST /v1/twin/{twinId}/assetsUn nuevo ID de activo por fila

Cada fila se convierte en un activo con una workingStructure que contiene un único cuadro orientado:

{
"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 }
}
]
}
}

Para asignar un tipo de activo en el momento de la creación, añade assetTypeId con el UUID de un tipo configurado en tu organización. Consulta Tipos de activo para saber cómo se definen los tipos en RealityPlatform.

Obtén un token de acceso con Client Credentials:

POST https://cloud-api.prevu3d.com/oauth/token
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
GET https://cloud-api.prevu3d.com/oauth/api-info
Authorization: Bearer {access_token}
POST {api_url}/v1/twin/{twinId}/assets
Authorization: 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 }
}
]
}
}

Una respuesta correcta devuelve el activo creado, incluido su id. Repite para cada fila del CSV.

import base64
import csv
from 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)}")

El ID del twin es el UUID del nodo del twin en tu jerarquía de contenido. Puedes:

  • Copiarlo de la URL de RealityPlatform cuando el twin está abierto
  • Explorar la jerarquía con GET /v1/nodes/{organizationId}/browse y localizar un nodo con type: "Twin"
  • Agrupa de forma responsable. La API crea un activo por solicitud. Para cientos de filas, añade un breve retraso o backoff si alcanzas los límites de tasa.
  • Valida las coordenadas primero. Importa una única fila de prueba antes de ejecutar el archivo completo.
  • Usa el modo borrador en RealityTwin cuando quieras revisar los activos antes de que otros usuarios los vean. Los activos creados a través de la API aparecen en el twin de inmediato, salvo que tu integración apunte a un flujo de borrador.
  • Adjunta metadatos más tarde. Después de la creación, usa PATCH /v1/twin/{twinId}/assets/{assetId}/metadata para añadir valores de propiedades. Consulta los endpoints de activos en la referencia de la API.