Zeggai/Question_Answer_Dataset
0
1<!DOCTYPE html>2<html lang="fr">3<head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>Générateur de Questions sur les Vaccins</title>7 <script src="https://cdn.tailwindcss.com"></script>8</head>9<body class="bg-gray-100 font-sans">10 <div class="container mx-auto p-6">11 <!-- Header -->12 <h1 class="text-3xl font-bold text-center mb-8">🧬 Générateur de Questions sur les Vaccins</h1>13 14 <!-- API Keys Status Section -->15 <section class="bg-white p-6 rounded-lg shadow-md mb-8">16 <h2 class="text-2xl font-semibold mb-4">🔑 État des Clés API</h2>17 <div id="api-keys-status" class="text-gray-700">18 Vérification des clés API...19 </div>20 <button id="check-api-keys" class="mt-4 bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">21 Vérifier les Clés22 </button>23 </section>24 25 <!-- Question Generation Section -->26 <section class="bg-white p-6 rounded-lg shadow-md mb-8">27 <h2 class="text-2xl font-semibold mb-4">🚀 Génération de Questions</h2>28 <p class="mb-4">Générez des questions à partir du guide de vaccination avec gestion multi-clés et suivi en temps réel.</p>29 <div class="flex space-x-4">30 <button id="generate-questions" class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600">31 Générer des Questions32 </button>33 <a id="download-progress" class="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600" href="#" style="display: none;">34 Télécharger Progrès35 </a>36 <button id="view-failed-chunks" class="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600">37 Voir Échecs38 </button>39 </div>40 41 <!-- Generation Status -->42 <div id="generation-status" class="mt-4 text-gray-700">43 Initialisation de la génération...44 </div>45 46 <!-- Progress Bar -->47 <div class="mt-4">48 <div class="w-full bg-gray-200 rounded-full h-4">49 <div id="progress-bar" class="bg-blue-500 h-4 rounded-full" style="width: 0%;"></div>50 </div>51 <p id="progress-text" class="text-center mt-2">0%</p>52 </div>53 54 <!-- Generation Details -->55 <div id="generation-details" class="mt-4 text-gray-700">56 <p>Chunks traités: <span id="processed-chunks">0</span>/<span id="total-chunks">0</span></p>57 <p>Questions générées: <span id="questions-generated">0</span></p>58 <p>Clé API actuelle: <span id="current-api-key">-</span></p>59 <p>Échecs: <span id="failed-chunks-count">0</span></p>60 </div>61 62 <!-- Estimated Time -->63 <div id="estimated-time" class="mt-4 text-gray-700">64 ⏱️ Temps estimé restant: Calcul en cours...65 </div>66 67 <!-- Failed Chunks -->68 <div id="failed-chunks" class="mt-4 hidden">69 <h3 class="text-lg font-semibold">❌ Chunks Échoués</h3>70 <ul id="failed-chunks-list" class="list-disc pl-5"></ul>71 <button id="retry-failed" class="mt-4 bg-yellow-500 text-white px-4 py-2 rounded hover:bg-yellow-600">72 Réessayer les Chunks Échoués73 </button>74 </div>75 </section>76 77 <!-- Results Section -->78 <section class="bg-white p-6 rounded-lg shadow-md">79 <h2 class="text-2xl font-semibold mb-4">📊 Résultats de Génération</h2>80 <div id="results-status" class="text-gray-700 mb-4">81 Aucun résultat disponible pour le moment.82 </div>83 <a id="download-results" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600" href="#" style="display: none;">84 📥 Télécharger le Dataset Complet85 </a>86 87 <!-- Questions Preview -->88 <h3 class="text-lg font-semibold mt-6">👀 Aperçu des Questions</h3>89 <table class="w-full mt-4 border-collapse">90 <thead>91 <tr class="bg-gray-200">92 <th class="border p-2">Question</th>93 <th class="border p-2">Type</th>94 <th class="border p-2">Difficulté</th>95 <th class="border p-2">But d'Entraînement</th>96 <th class="border p-2">Chunk ID</th>97 <th class="border p-2">Clé API</th>98 </tr>99 </thead>100 <tbody id="questions-table"></tbody>101 </table>102 </section>103 </div>104 105 <script>106 // Utility function to fetch data from API107 async function fetchData(url) {108 try {109 const response = await fetch(url);110 if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);111 return await response.json();112 } catch (error) {113 console.error('Error fetching data:', error);114 return null;115 }116 }117 118 // Update API Keys Status119 async function updateApiKeysStatus() {120 const statusDiv = document.getElementById('api-keys-status');121 const data = await fetchData('/api-keys-status');122 if (data && data.status === 'success') {123 statusDiv.innerHTML = `${data.total_keys} clés API configurées pour rotation. Clé actuelle: ${data.current_key_index}`;124 } else {125 statusDiv.innerHTML = `Erreur: ${data?.message || 'Impossible de vérifier les clés API'}`;126 }127 }128 129 // Update Generation Status130 async function updateGenerationStatus() {131 const data = await fetchData('/generation-status');132 if (!data) return;133 134 const statusDiv = document.getElementById('generation-status');135 const progressBar = document.getElementById('progress-bar');136 const progressText = document.getElementById('progress-text');137 const processedChunks = document.getElementById('processed-chunks');138 const totalChunks = document.getElementById('total-chunks');139 const questionsGenerated = document.getElementById('questions-generated');140 const currentApiKey = document.getElementById('current-api-key');141 const failedChunksCount = document.getElementById('failed-chunks-count');142 const estimatedTime = document.getElementById('estimated-time');143 const downloadProgress = document.getElementById('download-progress');144 const failedChunksDiv = document.getElementById('failed-chunks');145 const failedChunksList = document.getElementById('failed-chunks-list');146 147 if (data.is_running) {148 statusDiv.innerHTML = 'Génération en cours...';149 } else if (data.completed) {150 statusDiv.innerHTML = 'Génération terminée!';151 } else if (data.error) {152 statusDiv.innerHTML = `Erreur: ${data.error}`;153 } else {154 statusDiv.innerHTML = 'Prêt à générer des questions.';155 }156 157 progressBar.style.width = `${data.progress_percentage || 0}%`;158 progressText.innerText = `${data.progress_percentage || 0}%`;159 processedChunks.innerText = data.processed_chunks || 0;160 totalChunks.innerText = data.total_chunks || 0;161 questionsGenerated.innerText = data.questions_generated || 0;162 currentApiKey.innerText = data.current_api_key_index || '-';163 failedChunksCount.innerText = data.failed_chunks?.length || 0;164 165 if (data.estimated_remaining_minutes) {166 estimatedTime.innerHTML = `⏱️ Temps estimé restant: ${data.estimated_remaining_minutes} minutes`;167 } else {168 estimatedTime.innerHTML = '⏱️ Temps estimé restant: Calcul en cours...';169 }170 171 // Update download progress link172 if (data.progress_file) {173 downloadProgress.href = `/download/${data.progress_file}`;174 downloadProgress.style.display = 'inline-block';175 } else {176 downloadProgress.style.display = 'none';177 }178 179 // Update failed chunks180 if (data.failed_chunks?.length > 0) {181 failedChunksDiv.classList.remove('hidden');182 failedChunksList.innerHTML = data.failed_chunks.map(chunk => 183 `<li>Chunk ${chunk.chunk_id}: ${chunk.error} (Tentatives: ${chunk.attempts})</li>`184 ).join('');185 } else {186 failedChunksDiv.classList.add('hidden');187 }188 189 // Update results190 updateResults(data);191 }192 193 // Update Results and Questions Preview194 async function updateResults(statusData) {195 const resultsStatus = document.getElementById('results-status');196 const downloadResults = document.getElementById('download-results');197 const questionsTable = document.getElementById('questions-table');198 199 if (statusData.completed && statusData.result_file) {200 resultsStatus.innerHTML = `Dataset généré avec ${statusData.questions_generated} questions.`;201 downloadResults.href = `/download/${statusData.result_file}`;202 downloadResults.style.display = 'inline-block';203 } else if (statusData.partial_results?.length > 0) {204 resultsStatus.innerHTML = `Résultats partiels disponibles (${statusData.partial_results.length} questions).`;205 downloadResults.style.display = 'none';206 } else {207 resultsStatus.innerHTML = 'Aucun résultat disponible pour le moment.';208 downloadResults.style.display = 'none';209 }210 211 // Update questions preview212 questionsTable.innerHTML = statusData.partial_results?.slice(0, 10).map(q => `213 <tr>214 <td class="border p-2">${q.question}</td>215 <td class="border p-2">${q.type}</td>216 <td class="border p-2">${q.difficulty}</td>217 <td class="border p-2">${q.training_purpose}</td>218 <td class="border p-2">${q.chunk_id}</td>219 <td class="border p-2">${q.api_key_used}</td>220 </tr>221 `).join('') || '';222 }223 224 // Start Generation225 async function startGeneration() {226 const generateButton = document.getElementById('generate-questions');227 generateButton.disabled = true;228 generateButton.innerText = 'Génération en cours...';229 230 const response = await fetchData('/generate-questions');231 if (response && response.status === 'started') {232 alert(response.message);233 // Start polling for status234 const interval = setInterval(() => {235 updateGenerationStatus().then(() => {236 if (!response.is_running && response.completed) {237 clearInterval(interval);238 generateButton.disabled = false;239 generateButton.innerText = 'Générer des Questions';240 }241 });242 }, 5000);243 } else {244 alert(response?.message || 'Erreur lors du démarrage de la génération.');245 generateButton.disabled = false;246 generateButton.innerText = 'Générer des Questions';247 }248 }249 250 // Retry Failed Chunks251 async function retryFailedChunks() {252 const retryButton = document.getElementById('retry-failed');253 retryButton.disabled = true;254 const response = await fetchData('/retry-failed');255 alert(response.message);256 retryButton.disabled = false;257 updateGenerationStatus();258 }259 260 // Event Listeners261 document.getElementById('check-api-keys').addEventListener('click', updateApiKeysStatus);262 document.getElementById('generate-questions').addEventListener('click', startGeneration);263 document.getElementById('view-failed-chunks').addEventListener('click', () => {264 document.getElementById('failed-chunks').classList.toggle('hidden');265 });266 document.getElementById('retry-failed').addEventListener('click', retryFailedChunks);267 268 // Initial Load269 updateApiKeysStatus();270 updateGenerationStatus();271 </script>272</body>273</html>