benyelles0mehdi0dris commited on
Commit
0000915
·
1 Parent(s): e9c59f4
Files changed (2) hide show
  1. Dockerfile +17 -10
  2. frontend/script.js +55 -9
Dockerfile CHANGED
@@ -1,37 +1,44 @@
1
  FROM python:3.9-slim
2
 
3
- # Installation des outils essentiels
4
  RUN apt-get update && apt-get install -y \
5
  poppler-utils \
6
  pandoc \
7
  && apt-get clean \
8
  && rm -rf /var/lib/apt/lists/*
9
 
10
- # Définir le répertoire de travail
11
  WORKDIR /app
12
 
13
- # Copier d'abord les fichiers de dépendances
14
  COPY requirements.txt ./
15
 
16
- # Installer les dépendances avec mise en cache
17
  RUN pip install --no-cache-dir -r requirements.txt \
18
- && pip install python-multipart uvicorn fastapi pydantic requests matplotlib pandas seaborn
19
 
20
- # Créer les répertoires nécessaires avec les bonnes permissions
21
  RUN mkdir -p /app/frontend \
22
  && mkdir -p /tmp/.matplotlib \
23
  && chmod 777 /tmp/.matplotlib
24
 
25
- # Variables d'environnement
26
  ENV MPLCONFIGDIR=/tmp/.matplotlib
27
  ENV PYTHONUNBUFFERED=1
 
 
28
 
29
- # Copier le code de l'application et les fichiers statiques
30
  COPY backend_fastapi.py ./
31
  COPY frontend ./frontend/
32
 
33
- # Exposer le port
 
 
 
 
 
34
  EXPOSE 7860
35
 
36
- # Commande de démarrage
37
  CMD ["uvicorn", "backend_fastapi:app", "--host", "0.0.0.0", "--port", "7860"]
 
1
  FROM python:3.9-slim
2
 
3
+ # Install essential tools
4
  RUN apt-get update && apt-get install -y \
5
  poppler-utils \
6
  pandoc \
7
  && apt-get clean \
8
  && rm -rf /var/lib/apt/lists/*
9
 
10
+ # Set working directory
11
  WORKDIR /app
12
 
13
+ # Copy requirements file first for better caching
14
  COPY requirements.txt ./
15
 
16
+ # Install dependencies
17
  RUN pip install --no-cache-dir -r requirements.txt \
18
+ && pip install python-multipart uvicorn fastapi pydantic requests jinja2
19
 
20
+ # Create directories and set permissions
21
  RUN mkdir -p /app/frontend \
22
  && mkdir -p /tmp/.matplotlib \
23
  && chmod 777 /tmp/.matplotlib
24
 
25
+ # Set environment variables
26
  ENV MPLCONFIGDIR=/tmp/.matplotlib
27
  ENV PYTHONUNBUFFERED=1
28
+ # Uncomment and set your HF API key if needed
29
+ # ENV HF_API_KEY=your_huggingface_api_key
30
 
31
+ # Copy application code and static files
32
  COPY backend_fastapi.py ./
33
  COPY frontend ./frontend/
34
 
35
+ # Create requirements.txt if it doesn't exist yet
36
+ RUN if [ ! -f requirements.txt ]; then \
37
+ echo "fastapi==0.103.1\nuvicorn==0.23.2\npython-multipart==0.0.6\nrequests==2.31.0\nJinja2==3.1.2\npydantic==2.4.2" > requirements.txt; \
38
+ fi
39
+
40
+ # Expose port
41
  EXPOSE 7860
42
 
43
+ # Start command
44
  CMD ["uvicorn", "backend_fastapi:app", "--host", "0.0.0.0", "--port", "7860"]
frontend/script.js CHANGED
@@ -1,10 +1,10 @@
1
  // Constante pour l'URL de base
2
- const BASE_URL = ""; // Laisser vide pour utiliser l'URL relative (important pour Hugging Face)
3
 
4
  // Gestion des onglets
5
  function openTab(tabName) {
6
- // Liste des onglets que nous utilisons (uniquement summarize et answer-question)
7
- const tabs = ['summarize', 'answer-question'];
8
 
9
  // Cacher/montrer les sections appropriées
10
  tabs.forEach(tab => {
@@ -87,6 +87,9 @@ document.addEventListener('DOMContentLoaded', () => {
87
  // Configurer les uploads de fichiers
88
  setupFileUpload('summarize-file');
89
  setupFileUpload('answer-question-file');
 
 
 
90
 
91
  // Configurer les onglets
92
  document.querySelectorAll('.tab-btn').forEach(btn => {
@@ -113,6 +116,19 @@ document.addEventListener('DOMContentLoaded', () => {
113
  handleQASubmit();
114
  });
115
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
  } catch (error) {
118
  console.error('Erreur d\'initialisation:', error);
@@ -137,13 +153,19 @@ async function handleSummarizeSubmit() {
137
  const formData = new FormData();
138
  formData.append('file', fileInput.files[0]);
139
 
 
 
 
 
140
  const response = await fetch(`${BASE_URL}/summarize`, {
141
  method: 'POST',
142
  body: formData,
143
- });
 
144
 
145
  if (!response.ok) {
146
- throw new Error(`Erreur: ${response.status} ${response.statusText}`);
 
147
  }
148
 
149
  const data = await response.json();
@@ -168,7 +190,16 @@ async function handleSummarizeSubmit() {
168
  }
169
  } catch (error) {
170
  console.error('Erreur lors du résumé:', error);
171
- showError(resultDiv, `Erreur lors du traitement du fichier: ${error.message}`);
 
 
 
 
 
 
 
 
 
172
  }
173
  }
174
 
@@ -195,13 +226,19 @@ async function handleQASubmit() {
195
  formData.append('file', fileInput.files[0]);
196
  }
197
 
 
 
 
 
198
  const response = await fetch(`${BASE_URL}/answer-question`, {
199
  method: 'POST',
200
  body: formData,
201
- });
 
202
 
203
  if (!response.ok) {
204
- throw new Error(`Erreur: ${response.status} ${response.statusText}`);
 
205
  }
206
 
207
  const data = await response.json();
@@ -226,6 +263,15 @@ async function handleQASubmit() {
226
  }
227
  } catch (error) {
228
  console.error('Erreur de question-réponse:', error);
229
- showError(resultDiv, `Erreur lors du traitement de la question: ${error.message}`);
 
 
 
 
 
 
 
 
 
230
  }
231
  }
 
1
  // Constante pour l'URL de base
2
+ const BASE_URL = window.location.origin; // Utiliser l'URL complète pour éviter les erreurs CORS
3
 
4
  // Gestion des onglets
5
  function openTab(tabName) {
6
+ // Liste des onglets disponibles
7
+ const tabs = ['summarize', 'answer-question', 'interpret-image', 'generate-visualization', 'translate-document'];
8
 
9
  // Cacher/montrer les sections appropriées
10
  tabs.forEach(tab => {
 
87
  // Configurer les uploads de fichiers
88
  setupFileUpload('summarize-file');
89
  setupFileUpload('answer-question-file');
90
+ setupFileUpload('interpret-image-file');
91
+ setupFileUpload('visualization-file');
92
+ setupFileUpload('translate-file');
93
 
94
  // Configurer les onglets
95
  document.querySelectorAll('.tab-btn').forEach(btn => {
 
116
  handleQASubmit();
117
  });
118
  }
119
+
120
+ // Désactiver temporairement les onglets non implémentés
121
+ document.querySelectorAll('.tab-btn').forEach(btn => {
122
+ const tabName = btn.getAttribute('data-tab');
123
+ if (tabName !== 'summarize' && tabName !== 'answer-question') {
124
+ btn.addEventListener('click', (e) => {
125
+ e.preventDefault();
126
+ alert("Cette fonctionnalité n'est pas encore implémentée.");
127
+ // Ne pas changer d'onglet
128
+ return false;
129
+ });
130
+ }
131
+ });
132
 
133
  } catch (error) {
134
  console.error('Erreur d\'initialisation:', error);
 
153
  const formData = new FormData();
154
  formData.append('file', fileInput.files[0]);
155
 
156
+ // Utiliser fetch avec timeout et gestion d'erreur améliorée
157
+ const controller = new AbortController();
158
+ const timeoutId = setTimeout(() => controller.abort(), 60000); // 60s timeout
159
+
160
  const response = await fetch(`${BASE_URL}/summarize`, {
161
  method: 'POST',
162
  body: formData,
163
+ signal: controller.signal
164
+ }).finally(() => clearTimeout(timeoutId));
165
 
166
  if (!response.ok) {
167
+ const errorText = await response.text();
168
+ throw new Error(`Erreur: ${response.status} ${response.statusText}\n${errorText}`);
169
  }
170
 
171
  const data = await response.json();
 
190
  }
191
  } catch (error) {
192
  console.error('Erreur lors du résumé:', error);
193
+
194
+ // Message d'erreur plus descriptif
195
+ let errorMessage = error.message;
196
+ if (error.name === 'AbortError') {
197
+ errorMessage = "La requête a pris trop de temps. Veuillez réessayer avec un fichier plus petit.";
198
+ } else if (error.message.includes("Failed to fetch")) {
199
+ errorMessage = "Impossible de contacter le serveur. Veuillez vérifier votre connexion ou contactez l'administrateur.";
200
+ }
201
+
202
+ showError(resultDiv, `Erreur: ${errorMessage}`);
203
  }
204
  }
205
 
 
226
  formData.append('file', fileInput.files[0]);
227
  }
228
 
229
+ // Utiliser fetch avec timeout et gestion d'erreur améliorée
230
+ const controller = new AbortController();
231
+ const timeoutId = setTimeout(() => controller.abort(), 60000); // 60s timeout
232
+
233
  const response = await fetch(`${BASE_URL}/answer-question`, {
234
  method: 'POST',
235
  body: formData,
236
+ signal: controller.signal
237
+ }).finally(() => clearTimeout(timeoutId));
238
 
239
  if (!response.ok) {
240
+ const errorText = await response.text();
241
+ throw new Error(`Erreur: ${response.status} ${response.statusText}\n${errorText}`);
242
  }
243
 
244
  const data = await response.json();
 
263
  }
264
  } catch (error) {
265
  console.error('Erreur de question-réponse:', error);
266
+
267
+ // Message d'erreur plus descriptif
268
+ let errorMessage = error.message;
269
+ if (error.name === 'AbortError') {
270
+ errorMessage = "La requête a pris trop de temps. Veuillez réessayer avec une question plus courte ou un fichier plus petit.";
271
+ } else if (error.message.includes("Failed to fetch")) {
272
+ errorMessage = "Impossible de contacter le serveur. Veuillez vérifier votre connexion ou contactez l'administrateur.";
273
+ }
274
+
275
+ showError(resultDiv, `Erreur: ${errorMessage}`);
276
  }
277
  }