Documentation de l'API de gestion des tâches asynchrones (Jobs) dans Devana.ai.
Base URL: https://api.devana.ai
Préfixe: /v1/jobs
Authentification: API Key requise
L'API Jobs permet de suivre l'état des tâches asynchrones dans Devana.ai. Ces tâches incluent :
Caractéristiques principales :
Toutes les requêtes nécessitent une clé API dans le header Authorization :
Authorization: Bearer YOUR_API_KEY
Récupère la liste des tâches asynchrones de l'utilisateur avec possibilité de filtrage.
| Paramètre | Type | Requis | Description | Valeur par défaut |
|---|---|---|---|---|
targetId | String | Non | ID de la ressource cible (document, dossier, etc.) | - |
type | String (Enum) | Non | Filtrer par statut : PENDING, IN_PROGRESS, DONE, ERROR | - |
limit | Number | Non | Nombre maximum de résultats | 25 |
offset | Number | Non | Décalage pour la pagination | 0 |
GET /v1/jobs?targetId=cm4doc123&type=IN_PROGRESS&limit=10
Authorization: Bearer YOUR_API_KEY
{
"success": true,
"data": [
{
"id": "cm4job789xyz123",
"userId": "cm4user456abc",
"targetId": "cm4doc123abc456",
"type": "EXTRACTION",
"status": "IN_PROGRESS",
"progress": 65,
"metadata": {
"fileName": "rapport-2024.pdf",
"fileSize": 2456789,
"pageCount": 45
},
"startedAt": "2024-10-28T10:30:00.000Z",
"createdAt"
Récupérer toutes les tâches récentes :
curl -X GET https://api.devana.ai/v1/jobs \
-H "Authorization: Bearer YOUR_API_KEY"
Filtrer par document spécifique :
curl -X GET "https://api.devana.ai/v1/jobs?targetId=cm4doc123abc456" \
-H "Authorization: Bearer YOUR_API_KEY"
Récupérer les tâches en erreur :
curl -X GET "https://api.devana.ai/v1/jobs?type=ERROR" \
-H "Authorization: Bearer YOUR_API_KEY"
Pagination des résultats :
curl -X GET "https://api.devana.ai/v1/jobs?limit=50&offset=50" \
-H "Authorization: Bearer YOUR_API_KEY"
Les différents types de tâches trackées par le système :
| Type | Description | Durée typique |
|---|---|---|
EXTRACTION | Extraction de contenu de documents (PDF, DOCX, etc.) | 5s - 5min |
EMBEDDING | Génération de vecteurs pour la recherche sémantique | 10s - 10min |
SYNC | Synchronisation de dossiers externes (SharePoint, etc.) | 1min - 30min |
IMPORT | Import batch de fichiers | 30s - 15min |
TRANSCRIPTION | Transcription audio (STT) | 10s - 5min |
GENERATION | Génération de contenu ou résumés | 5s - 2min |
| Statut | Description | Action recommandée |
|---|---|---|
PENDING | Tâche en attente dans la queue | Attendre, vérifier régulièrement |
IN_PROGRESS | Tâche en cours d'exécution | Continuer le polling |
DONE | Tâche terminée avec succès | Récupérer les résultats |
ERROR | Échec de la tâche | Vérifier les logs, réessayer |
KILLED | Tâche annulée (non retourné par l'API) | - |
Note : Les jobs avec statut KILLED sont automatiquement filtrés et ne sont jamais retournés.
// Récupérer les jobs d'un dossier spécifique
async function getFolderJobs(folderId) {
const response = await fetch(
`https://api.devana.ai/v1/jobs?targetId=${folderId}`,
{
headers: {
Authorization: `Bearer ${API_KEY}`,
},
}
);
const data = await response.json();
return data.data;
}
// Filtrer les jobs par multiple critères
async function getFilteredJobs(filters) {
const params = new URLSearchParams();
if (filters.targetId) params.append("targetId", filters.targetId);
if (filters.type) params.append("type", filters.type);
if (filters.limit) params.append("limit", filters.limit);
if (filters.offset) params.append("offset", filters.offset);
response = (
,
{
: {
: ,
},
}
);
response.();
}
interface Job {
id: string; // Identifiant unique du job
userId: string; // ID de l'utilisateur propriétaire
targetId: string; // ID de la ressource cible
type: JobType; // Type de tâche
status: JobStatus; // Statut actuel
progress?: number; // Progression (0-100)
metadata?: {
// Métadonnées spécifiques au type
[key: string]: any;
};
error?: string; // Message d'erreur si échec
startedAt?: Date; // Début de l'exécution
completedAt?: Date; // Fin de l'exécution
createdAt: Date; // Création du job
updatedAt: Date; // Dernière mise à jour
}
EXTRACTION:
{
"fileName": "document.pdf",
"fileSize": 1234567,
"mimeType": "application/pdf",
"pageCount": 10,
"extractionMethod": "ODIN"
}
EMBEDDING:
{
"folderName": "Knowledge Base",
"filesProcessed": 15,
"totalChunks": 450,
"chunkSize": 500,
"model": "text-embedding-ada-002"
}
#!/bin/bash
# Upload un document et suivre son extraction
DOCUMENT_ID="cm4doc123abc456"
# Fonction pour vérifier le statut
check_job_status() {
local doc_id=$1
while true; do
# Récupérer le job d'extraction
JOB=$(curl -s -X GET "https://api.devana.ai/v1/jobs?targetId=$doc_id&type=EXTRACTION" \
-H "Authorization: Bearer YOUR_API_KEY" | jq -r '.data[0]')
if [ "$JOB" = "null" ]; then
echo "Aucun job trouvé pour le document $doc_id"
break
fi
STATUS=$(echo $JOB | jq -r '.status')
PROGRESS=$(echo $JOB | jq -r '.progress // 0')
echo "Status: $STATUS - Progress: $PROGRESS%"
case $STATUS in
"DONE")
echo "Extraction terminée avec succès!"
break
;;
"ERROR")
ERROR=$(echo $JOB | jq -r '.error')
1
;;
*)
2
;;
}
check_job_status
import requests
import time
from typing import Dict, Optional
class JobMonitor:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.devana.ai/v1"
self.headers = {"Authorization": f"Bearer {api_key}"}
def wait_for_job(self, target_id: str, job_type: str = None,
timeout: int = 300) -> Optional[Dict]:
"""
Attend la fin d'un job avec timeout
Args:
target_id: ID de la ressource cible
job_type: Type de job à filtrer (optionnel)
timeout: Timeout en secondes
Returns:
Job terminé ou None si timeout
"""
start_time = time.time()
while time.time() - start_time < timeout:
# Récupérer les jobs
params = {"targetId": target_id}
if job_type:
params["type"] = job_type
response = requests.get(
f"{self.base_url}/jobs",
headers=self.headers,
params=params
)
if response.status_code != 200:
Exception()
jobs = response.json()[]
jobs:
()
job = jobs[]
status = job[]
progress = job.get(, )
()
status == :
job
status == :
Exception()
time.sleep()
TimeoutError()
() -> :
response = requests.get(
,
headers=.headers,
params={: }
)
jobs = response.json()[]
stats = {
: (jobs),
: ( j jobs j[] == ),
: ( j jobs j[] == ),
: ( j jobs j[] == ),
: ( j jobs j[] == ),
: {}
}
job jobs:
job_type = job.get(, )
job_type stats[]:
stats[][job_type] =
stats[][job_type] +=
stats
monitor = JobMonitor()
:
completed_job = monitor.wait_for_job(
,
job_type=,
timeout=
)
()
TimeoutError:
()
Exception e:
()
stats = monitor.get_job_statistics()
()
// Créer un dashboard de suivi des jobs
class JobDashboard {
constructor(apiKey) {
this.apiKey = apiKey;
this.jobs = new Map();
this.updateInterval = null;
}
async fetchJobs() {
const response = await fetch("https://api.devana.ai/v1/jobs?limit=50", {
headers: {
Authorization: `Bearer ${this.apiKey}`,
},
});
const data = await response.json();
return data.data;
}
async updateDashboard() {
const jobs = await this.fetchJobs();
// Mettre à jour le cache local
jobs.forEach((job) => {
const existing = this.jobs.get(job.id);
if (!existing || existing. !== job.) {
.(job, existing);
}
..(job., job);
});
.();
}
() {
(oldJob && oldJob. !== newJob.) {
.(
);
(newJob. === ) {
.(newJob);
} (newJob. === ) {
.(newJob);
}
}
}
() {
stats = .();
.();
.();
.();
.();
.();
.();
.();
.();
.(..())
.( job. === )
.( {
.();
});
}
() {
jobs = .(..());
{
: jobs.,
: jobs.( j. === ).,
: jobs.( j. === ).,
: jobs.( j. === ).,
: jobs.( j. === ).,
};
}
() {
.();
}
() {
.();
}
() {
.();
. = ( {
.();
}, );
}
() {
(.) {
(.);
}
}
}
dashboard = ();
dashboard.();
#!/bin/bash
# Script de retry automatique pour les jobs en échec
API_KEY="YOUR_API_KEY"
MAX_RETRIES=3
retry_failed_jobs() {
echo "Recherche des jobs en échec..."
# Récupérer les jobs en erreur
FAILED_JOBS=$(curl -s -X GET "https://api.devana.ai/v1/jobs?type=ERROR" \
-H "Authorization: Bearer $API_KEY" | jq -r '.data[]')
if [ -z "$FAILED_JOBS" ]; then
echo "Aucun job en échec trouvé"
return
fi
echo "$FAILED_JOBS" | jq -c '.' | while read -r job; do
JOB_ID=$(echo $job | jq -r '.id')
TARGET_ID=$(echo $job | jq -r '.targetId')
JOB_TYPE=$(echo $job | jq -r '.type')
echo "Retry du job $JOB_ID (Type: $JOB_TYPE, Target: $TARGET_ID)"
case $JOB_TYPE in
"EXTRACTION")
# Relancer l'extraction
curl -X POST "https://api.devana.ai/v1/documents//reextract" \
-H
;;
)
curl -X POST \
-H
;;
*)
;;
2
}
;
retry_failed_jobs
300
Pour recevoir des notifications en temps réel sur les changements de statut des jobs, configurez des webhooks :
// Exemple de webhook handler
app.post("/webhook/job-status", (req, res) => {
const { jobId, status, targetId, type, metadata } = req.body;
console.log(`Job ${jobId} updated: ${status}`);
switch (status) {
case "DONE":
// Traiter la fin du job
handleJobComplete(targetId, type, metadata);
break;
case "ERROR":
// Gérer l'erreur
handleJobError(jobId, metadata.error);
break;
}
res.status(200).send("OK");
});
Rétention des données
Rate limiting
Performance
Pour toute question ou problème concernant l'API Jobs :