Aller au contenu

Traitement et suivi

Une fois les fichiers d’entrée téléversés, la plateforme peut générer des sorties traitées (nuages de points standardisés, maillages HLOD, photosphères, etc.). Ce guide explique comment lister les options de traitement, lancer le traitement et interroger la progression jusqu’à que chaque sortie atteigne un état terminal.

Il suppose que vous avez un bundle avec au moins une session de téléversement complétée et que vous disposez des scopes read:bundle et write:bundle.


Le traitement est de type fire-and-forget : l’API met en file d’attente une tâche de traitement et retourne immédiatement.

sequenceDiagram
  participant Client as Client
  participant RCAPI as RCAPI

  Client->>RCAPI: GET processing/options
  RCAPI-->>Client: options + metadata

  Client->>RCAPI: POST processing
  RCAPI-->>Client: accepté ou erreur typée

  loop jusqu'à que tout soit terminal
    Client->>RCAPI: GET bundle/processings
    RCAPI-->>Client: enregistrements de traitement (status, progress)
  end
MéthodeCheminScopeObjectif
GET/v1/bundles/{bundleId}/processing/optionsread:bundleLister les types de sortie possibles et leurs métadonnées
POST/v1/bundles/{bundleId}/processingwrite:bundleLancer le traitement pour les sorties demandées
GET/v1/bundles/{bundleId}/processingsread:bundleLister les enregistrements de traitement du bundle pour interroger la progression
GET/v1/site/{siteId}/bundles/{bundleId}read:hierarchyObtenir le bundle avec ses composants de sortie traités (liens signés)

Avant de lancer, découvrez quelles sorties le bundle peut produire et le coût de chacune.

GET {api_url}/v1/bundles/{bundleId}/processing/options?page=1&limit=20&sortBy=type&sortDir=ASC
Authorization: Bearer {access_token}
ParamètreTypeDescription
pagenumberIndex de page basé sur 1 (défaut 1)
limitnumberTaille de page (défaut 20, maximum 20)
sortBystringtype ou cost (défaut type)
sortDirstringASC ou DESC (défaut ASC)

La réponse est une liste paginée ({ items, total }). Chaque option décrit un type de sortie :

ChampSignification
typeType de composant de sortie à transmettre lors du démarrage du traitement (ex. StandardizedPointCloud, OgcPointCloudHlod)
hasProcessingtrue lorsqu’un traitement pour cette sortie a déjà été lancé
costCoût de traitement en octets pour les sorties payantes ; 0 pour les sorties du niveau gratuit

Exemple :

{
"items": [
{
"type": "StandardizedPointCloud",
"hasProcessing": false,
"cost": 734003200
},
{
"type": "OgcPointCloudHlod",
"hasProcessing": false,
"cost": 734003200
}
],
"total": 2
}

Ignorez les sorties où hasProcessing est true, sauf si vous avez l’intention de retraiter.

Transmettez la liste des types de composants de sortie que vous souhaitez que le pipeline produise, plus un champ cost qui reconnaît le coût total de traitement. Le serveur additionne les valeurs cost de l’étape 1 pour chaque type dans requestedComponents et rejette la requête lorsque votre reconnaissance ne correspond pas.

Le traitement démarre de manière asynchrone une fois le coût accepté.

POST {api_url}/v1/bundles/{bundleId}/processing
Authorization: Bearer {access_token}
Content-Type: application/json
{
"requestedComponents": [
"StandardizedPointCloud",
"OgcPointCloudHlod"
],
"cost": 1468006400
}

Dans l’exemple ci-dessus, cost est 734003200 + 734003200 depuis la liste d’options de l’étape 1.

204 No Content : le traitement a été accepté et mis en file d’attente.

Lorsque le traitement ne peut pas être lancé, l’API retourne 409 Conflict avec une error typée :

Valeur errorSignification
ProcessingCostMismatchLe cost soumis ne correspond pas au total calculé pour les sorties demandées
InsufficientProcessingCapacityLa limite de traitement de l’organisation serait dépassée
NoInputDataFoundForProcessingAucun fichier d’entrée finalisé est disponible sur le bundle
FailedToLaunchProcessingLa soumission au pipeline a échoué pour une raison inattendue

Exemple :

{
"error": "ProcessingCostMismatch"
}

La validation structurelle du lot téléversé (types obligatoires, extensions, dépendances) est appliquée par le pipeline de traitement après le lancement. Si votre session de téléversement s’est complétée mais a violé le contrat requirements, le traitement peut échouer plus tard même si chaque fichier s’est téléversé avec succès et que l’appel de démarrage a retourné 204.

Après un démarrage réussi, interrogez les enregistrements de traitement du bundle jusqu’à que chacun atteigne un état terminal.

GET {api_url}/v1/bundles/{bundleId}/processings
Authorization: Bearer {access_token}

La réponse est une liste ({ items, total }) avec chaque enregistrement de traitement du bundle. Il n’y a pas de paramètres de requête ; tous les enregistrements sont retournés en un seul appel.

Chaque item suit une tâche de traitement :

ChampSignification
idIdentifiant de l’enregistrement de traitement
statusStatut du pipeline (voir le tableau ci-dessous)
progressPourcentage d’achèvement (0100) pendant l’activité
createdAtDate de création de la tâche
updatedAtDate de la dernière modification d’état
launchedByIdId de l’utilisateur qui a lancé la tâche, ou null
knownErrorsÉchecs structurés, chacun avec un errorCode et les errorFilepaths affectés (null lorsque non spécifique à un fichier)
StatutTerminal ?Signification
PendingnonEn file d’attente, pas encore démarré
ProcessingnonLe pipeline est en cours d’exécution
RestartednonLa tâche a été relancée et est en cours d’exécution
ReadyouiSortie produite avec succès
FailedouiÉchec non structuré du pipeline
FailedToLaunchouiLa tâche n’a jamais entré le pipeline
KnownErrorouiErreur structurée de validation ou de format

Interrogez jusqu’à que chaque enregistrement soit dans un état terminal (Ready, Failed, FailedToLaunch ou KnownError).

Exemple de réponse en cours :

{
"items": [
{
"id": "3f2b1c4d-8e7a-4b2c-9d1e-0a1b3c4d4e6f",
"status": "Processing",
"progress": 42,
"createdAt": "2026-06-01T14:05:00Z",
"updatedAt": "2026-06-01T14:12:00Z",
"launchedById": "b1a2c3d4-5e6f-7a8b-9c0d-1e2f3a2b2c1d",
"knownErrors": []
},
{
"id": "9c0d1e2f-3a4b-5c6d-7e8f-9a0b2c3d3e4f",
"status": "Pending",
"progress": 0,
"createdAt": "2026-06-01T14:05:00Z",
"updatedAt": "2026-06-01T14:05:00Z",
"launchedById": "b1a2c3d4-5e6f-7a8b-9c0d-1e2f3a3b1c1d",
"knownErrors": []
}
],
"total": 2
}

Exemple avec une erreur connue :

{
"items": [
{
"id": "3f2b1c4d-8e7a-4b2c-9d1e-0a1b3c4d4e5f",
"status": "KnownError",
"progress": 100,
"createdAt": "2026-06-01T14:05:00Z",
"updatedAt": "2026-06-01T14:48:00Z",
"launchedById": "b1a2c3d4-5e6f-7a8b-1c0d-2e6f3a4b5c6d",
"knownErrors": [
{
"errorCode": "MissingTrajectory",
"errorFilepaths": ["scan.las"]
}
]
}
],
"total": 1
}

La liste de traitement n’inclut pas le type de sortie par enregistrement. Pour mapper les sorties terminées à leurs types de composants et liens signés, obtenez les composants du bundle (voir Récupération des sorties traitées).

  • Intervalle : 1 à 5 minutes est une valeur par défaut raisonnable. Le traitement peut durer plusieurs minutes à plusieurs heures selon la taille des entrées.
  • Limites de taux : les points de terminaison de bundle partagent un compartiment de limite de taux avec plusieurs autres points de terminaison. Évitez une interrogation à moins d’une minute.

Une fois qu’un enregistrement de traitement atteint Ready, obtenez le bundle pour accéder à ses composants de sortie et leurs liens de téléchargement signés. Les détails du bundle se trouvent sur le point de terminaison de hiérarchie :

GET {api_url}/v1/site/{siteId}/bundles/{bundleId}
Authorization: Bearer {access_token}

Ce point de terminaison requiert le scope read:hierarchy et retourne le bundle avec son tableau components :

ChampSignification
idId du bundle
nameNom du bundle
componentsUne entrée par composant disponible (entrées et sorties traitées)

Chaque composant porte :

ChampSignification
idId du composant
typeType de composant, ex. StandardizedPointCloud, OgcPointCloudHlod
versionVersion du composant
signedLinkURL signée pour télécharger le composant ; aucun en-tête d’authentification requis
rootsChemins de point d’entrée dans le composant, lorsque applicable

Exemple :

{
"id": "a6f75b3c-f261-4b27-9a2a-9a6cc4178a13",
"name": "ZF capture 2026-06-01",
"components": [
{
"id": "5d6e7f8a-9b0c-1d2e-3f4a-1b3c7d4e8f0a",
"type": "StandardizedPointCloud",
"version": "1",
"signedLink": "https://cdn…/components/…?X-Amz-…"
}
]
}

Un projet RealityPlan expose le même bundle via GET /v1/reality-plan/{projectId}/bundles/{bundleId} (scope read:twin).

import time
import requests
API_URL = "https://<your-regional-api-url>"
TOKEN = "<access_token>"
BUNDLE_ID = "<bundleId>"
headers = {"Authorization": f"Bearer {TOKEN}"}
base = f"{API_URL}/v1/bundles/{BUNDLE_ID}"
# 1. Discover outputs.
options = requests.get(
f"{base}/processing/options",
headers=headers,
params={"page": 1, "limit": 20},
).json()
options_by_type = {item["type"]: item for item in options["items"]}
to_process = [
item["type"]
for item in options["items"]
if not item["hasProcessing"]
]
total_cost = sum(options_by_type[t]["cost"] for t in to_process)
print(f"Launching: {to_process} (cost: {total_cost})")
# 2. Start processing.
response = requests.post(
f"{base}/processing",
headers=headers,
json={"requestedComponents": to_process, "cost": total_cost},
)
if response.status_code == 409:
raise RuntimeError(
f"Processing failed to start: {response.json().get('error')}"
)
response.raise_for_status() # expect 204
# 3. Poll until every job is terminal.
TERMINAL = {"Ready", "Failed", "FailedToLaunch", "KnownError"}
POLL_SECONDS = 15
TIMEOUT_SECONDS = 3600
deadline = time.time() + TIMEOUT_SECONDS
while time.time() < deadline:
listing = requests.get(
f"{base}/processings",
headers=headers,
).json()
processings = listing.get("items", [])
for p in processings:
print(f" {p['id']}: {p['status']} ({p['progress']}%)")
if processings and all(p["status"] in TERMINAL for p in processings):
break
time.sleep(POLL_SECONDS)
else:
raise TimeoutError("Processing did not finish within the timeout")

Pour récupérer les fichiers d’entrée bruts qui ont été téléversés (archivage, retraitement ou audit), consultez Téléchargement des fichiers d’entrée.