Docfile commited on
Commit
3733555
·
verified ·
1 Parent(s): a84494d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -33
app.py CHANGED
@@ -5,12 +5,39 @@ from PIL import Image
5
  import tempfile
6
  import PIL.Image
7
  import subprocess
8
-
 
 
 
 
 
9
 
10
  app = Flask(__name__)
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  # Configuration de l'API Gemini
13
  token = os.environ.get("TOKEN")
 
 
 
 
14
  genai.configure(api_key=token)
15
 
16
  generation_config = {
@@ -25,14 +52,11 @@ safety_settings = [
25
  {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
26
  ]
27
 
28
-
29
  @app.route('/')
30
  def generale():
 
31
  return render_template("generale.html")
32
 
33
-
34
-
35
-
36
  def upload_and_process_file(file_path):
37
  """Upload et traite un fichier avec l'API Gemini avec gestion des erreurs améliorée"""
38
  max_retries = 3
@@ -40,19 +64,21 @@ def upload_and_process_file(file_path):
40
 
41
  for attempt in range(max_retries):
42
  try:
43
- print(f"Tentative d'upload {attempt + 1}/{max_retries} pour {file_path}")
44
 
45
  # Vérification du fichier
46
  if not os.path.exists(file_path):
 
47
  raise FileNotFoundError(f"Le fichier {file_path} n'existe pas")
48
 
49
  file_size = os.path.getsize(file_path)
50
  if file_size == 0:
 
51
  raise ValueError(f"Le fichier {file_path} est vide")
52
 
53
  # Upload du fichier
54
  uploaded_file = genai.upload_file(path=file_path)
55
- print(f"Upload réussi: {uploaded_file.uri}")
56
 
57
  # Attente du traitement
58
  timeout = 300 # 5 minutes
@@ -60,61 +86,56 @@ def upload_and_process_file(file_path):
60
 
61
  while uploaded_file.state.name == "PROCESSING":
62
  if time.time() - start_time > timeout:
 
63
  raise TimeoutError("Timeout pendant le traitement du fichier")
64
 
65
- print(f"En attente du traitement... Temps écoulé: {int(time.time() - start_time)}s")
66
  time.sleep(10)
67
  uploaded_file = genai.get_file(uploaded_file.name)
68
 
69
  if uploaded_file.state.name == "FAILED":
 
70
  raise ValueError(f"Échec du traitement: {uploaded_file.state.name}")
71
 
72
- print(f"Traitement terminé avec succès: {uploaded_file.uri}")
73
  return uploaded_file
74
 
75
  except ssl.SSLError as e:
76
- print(f"Erreur SSL lors de l'upload (tentative {attempt + 1}): {e}")
77
  if attempt < max_retries - 1:
78
  time.sleep(retry_delay * (attempt + 1))
79
  else:
80
  raise
81
 
82
  except Exception as e:
83
- print(f"Erreur lors de l'upload (tentative {attempt + 1}): {e}")
84
  if attempt < max_retries - 1:
85
  time.sleep(retry_delay * (attempt + 1))
86
  else:
87
  raise
88
-
89
-
90
 
91
  def is_youtube_url(url):
92
  """Vérifie si l'URL est une URL YouTube"""
93
  parsed = urlparse(url)
94
  return any(domain in parsed.netloc for domain in ['youtube.com', 'youtu.be'])
95
 
96
-
97
-
98
-
99
  def download_youtube_video(url):
100
  """Télécharge une vidéo YouTube en utilisant subprocess avec youtube-dl"""
101
  try:
102
  with tempfile.TemporaryDirectory() as temp_dir:
103
  output_template = os.path.join(temp_dir, '%(title)s.%(ext)s')
104
 
105
- # Commande youtube-dl avec options
106
  command = [
107
  'youtube-dl',
108
- '--format', 'best[filesize<500M]', # Limite la taille du fichier
109
  '--quiet',
110
  '--no-warnings',
111
  '--output', output_template,
112
  url
113
  ]
114
 
115
- print(f"Téléchargement de la vidéo: {url}")
116
 
117
- # Exécution de la commande
118
  process = subprocess.Popen(
119
  command,
120
  stdout=subprocess.PIPE,
@@ -122,42 +143,43 @@ def download_youtube_video(url):
122
  universal_newlines=True
123
  )
124
 
125
- # Attente et récupération du résultat
126
  stdout, stderr = process.communicate()
127
 
128
  if process.returncode != 0:
 
129
  raise Exception(f"Erreur youtube-dl: {stderr}")
130
 
131
- # Recherche du fichier téléchargé dans le dossier temporaire
132
  downloaded_files = os.listdir(temp_dir)
133
  if not downloaded_files:
 
134
  raise FileNotFoundError("Aucun fichier n'a été téléchargé")
135
 
136
  video_path = os.path.join(temp_dir, downloaded_files[0])
137
 
138
- # Copie vers un fichier temporaire permanent
139
  temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(video_path)[1])
140
  with open(video_path, 'rb') as f:
141
  temp_file.write(f.read())
142
 
143
- print(f"Vidéo téléchargée avec succès: {temp_file.name}")
144
  return temp_file.name
145
 
146
  except Exception as e:
147
- print(f"Erreur lors du téléchargement de la vidéo: {e}")
148
  return None
149
 
150
  def telecharger_pdf(url):
151
  """Télécharge un PDF et retourne le chemin du fichier"""
152
  try:
 
153
  response = requests.get(url)
154
  response.raise_for_status()
155
 
156
  with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as temp_file:
157
  temp_file.write(response.content)
 
158
  return temp_file.name
159
  except Exception as e:
160
- print(f"Erreur lors du téléchargement du PDF : {e}")
161
  return None
162
 
163
  def allowed_file(filename):
@@ -167,11 +189,15 @@ def allowed_file(filename):
167
 
168
  @app.route('/submit', methods=['POST'])
169
  def submit_question():
 
170
  question = request.form.get('question')
171
  urls = request.form.getlist('urls')
172
  files = request.files.getlist('files')
173
 
174
- print("URLs reçues:", urls)
 
 
 
175
  content = [question]
176
  temp_files = []
177
 
@@ -179,51 +205,62 @@ def submit_question():
179
  # Traitement des fichiers uploadés
180
  for file in files:
181
  if file and allowed_file(file.filename):
 
182
  with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(file.filename)[1]) as temp_file:
183
  file.save(temp_file.name)
184
  temp_files.append(temp_file.name)
185
  if file.filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
186
  content.append(PIL.Image.open(temp_file.name))
 
187
  else:
188
  uploaded_file = upload_and_process_file(temp_file.name)
189
  content.append(uploaded_file)
 
190
 
191
  # Traitement des URLs
192
  for url in urls:
193
- print(f"Traitement de l'URL : {url}")
194
  if is_youtube_url(url):
195
  video_path = download_youtube_video(url)
196
  if video_path:
197
  temp_files.append(video_path)
198
  uploaded_file = upload_and_process_file(video_path)
199
  content.append(uploaded_file)
 
200
  elif url.lower().endswith('.pdf'):
201
  pdf_path = telecharger_pdf(url)
202
  if pdf_path:
203
  temp_files.append(pdf_path)
204
  uploaded_file = upload_and_process_file(pdf_path)
205
  content.append(uploaded_file)
206
-
207
-
208
-
209
 
210
  # Génération de contenu avec Gemini
 
211
  model = genai.GenerativeModel(
212
  model_name="models/gemini-2.0-flash-exp",
213
  safety_settings=safety_settings,
214
  system_instruction="Tu es un assistant intelligent. ton but est d'assister au mieux que tu peux. tu as été créé par Aenir et tu t'appelles Mariam."
215
  )
 
 
216
  response = model.generate_content(content, request_options={"timeout": 600})
 
 
217
  return jsonify({"response": response.text})
218
 
219
  except Exception as e:
 
220
  return jsonify({"error": str(e)}), 500
221
  finally:
222
  # Nettoyage des fichiers temporaires
223
  for temp_file in temp_files:
224
  try:
225
  os.unlink(temp_file)
 
226
  except Exception as e:
227
- print(f"Erreur lors de la suppression du fichier temporaire {temp_file}: {e}")
228
-
229
 
 
 
 
 
5
  import tempfile
6
  import PIL.Image
7
  import subprocess
8
+ import logging
9
+ from urllib.parse import urlparse
10
+ import requests
11
+ import time
12
+ import ssl
13
+ from logging.handlers import RotatingFileHandler
14
 
15
  app = Flask(__name__)
16
 
17
+ # Configuration des logs
18
+ log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
19
+ log_file = 'app.log'
20
+
21
+ # Handler pour fichier avec rotation
22
+ file_handler = RotatingFileHandler(log_file, maxBytes=10485760, backupCount=5) # 10MB par fichier, max 5 fichiers
23
+ file_handler.setFormatter(log_formatter)
24
+
25
+ # Handler pour console
26
+ console_handler = logging.StreamHandler()
27
+ console_handler.setFormatter(log_formatter)
28
+
29
+ # Configuration du logger principal
30
+ logger = logging.getLogger(__name__)
31
+ logger.setLevel(logging.INFO)
32
+ logger.addHandler(file_handler)
33
+ logger.addHandler(console_handler)
34
+
35
  # Configuration de l'API Gemini
36
  token = os.environ.get("TOKEN")
37
+ if not token:
38
+ logger.error("Token API non trouvé dans les variables d'environnement")
39
+ raise ValueError("Token API manquant")
40
+
41
  genai.configure(api_key=token)
42
 
43
  generation_config = {
 
52
  {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
53
  ]
54
 
 
55
  @app.route('/')
56
  def generale():
57
+ logger.info("Accès à la page principale")
58
  return render_template("generale.html")
59
 
 
 
 
60
  def upload_and_process_file(file_path):
61
  """Upload et traite un fichier avec l'API Gemini avec gestion des erreurs améliorée"""
62
  max_retries = 3
 
64
 
65
  for attempt in range(max_retries):
66
  try:
67
+ logger.info(f"Tentative d'upload {attempt + 1}/{max_retries} pour {file_path}")
68
 
69
  # Vérification du fichier
70
  if not os.path.exists(file_path):
71
+ logger.error(f"Fichier non trouvé: {file_path}")
72
  raise FileNotFoundError(f"Le fichier {file_path} n'existe pas")
73
 
74
  file_size = os.path.getsize(file_path)
75
  if file_size == 0:
76
+ logger.error(f"Fichier vide: {file_path}")
77
  raise ValueError(f"Le fichier {file_path} est vide")
78
 
79
  # Upload du fichier
80
  uploaded_file = genai.upload_file(path=file_path)
81
+ logger.info(f"Upload réussi: {uploaded_file.uri}")
82
 
83
  # Attente du traitement
84
  timeout = 300 # 5 minutes
 
86
 
87
  while uploaded_file.state.name == "PROCESSING":
88
  if time.time() - start_time > timeout:
89
+ logger.error("Timeout pendant le traitement du fichier")
90
  raise TimeoutError("Timeout pendant le traitement du fichier")
91
 
92
+ logger.debug(f"En attente du traitement... Temps écoulé: {int(time.time() - start_time)}s")
93
  time.sleep(10)
94
  uploaded_file = genai.get_file(uploaded_file.name)
95
 
96
  if uploaded_file.state.name == "FAILED":
97
+ logger.error(f"Échec du traitement: {uploaded_file.state.name}")
98
  raise ValueError(f"Échec du traitement: {uploaded_file.state.name}")
99
 
100
+ logger.info(f"Traitement terminé avec succès: {uploaded_file.uri}")
101
  return uploaded_file
102
 
103
  except ssl.SSLError as e:
104
+ logger.error(f"Erreur SSL lors de l'upload (tentative {attempt + 1}): {e}")
105
  if attempt < max_retries - 1:
106
  time.sleep(retry_delay * (attempt + 1))
107
  else:
108
  raise
109
 
110
  except Exception as e:
111
+ logger.error(f"Erreur lors de l'upload (tentative {attempt + 1}): {e}")
112
  if attempt < max_retries - 1:
113
  time.sleep(retry_delay * (attempt + 1))
114
  else:
115
  raise
 
 
116
 
117
  def is_youtube_url(url):
118
  """Vérifie si l'URL est une URL YouTube"""
119
  parsed = urlparse(url)
120
  return any(domain in parsed.netloc for domain in ['youtube.com', 'youtu.be'])
121
 
 
 
 
122
  def download_youtube_video(url):
123
  """Télécharge une vidéo YouTube en utilisant subprocess avec youtube-dl"""
124
  try:
125
  with tempfile.TemporaryDirectory() as temp_dir:
126
  output_template = os.path.join(temp_dir, '%(title)s.%(ext)s')
127
 
 
128
  command = [
129
  'youtube-dl',
130
+ '--format', 'best[filesize<50M]',
131
  '--quiet',
132
  '--no-warnings',
133
  '--output', output_template,
134
  url
135
  ]
136
 
137
+ logger.info(f"Début du téléchargement de la vidéo: {url}")
138
 
 
139
  process = subprocess.Popen(
140
  command,
141
  stdout=subprocess.PIPE,
 
143
  universal_newlines=True
144
  )
145
 
 
146
  stdout, stderr = process.communicate()
147
 
148
  if process.returncode != 0:
149
+ logger.error(f"Erreur youtube-dl: {stderr}")
150
  raise Exception(f"Erreur youtube-dl: {stderr}")
151
 
 
152
  downloaded_files = os.listdir(temp_dir)
153
  if not downloaded_files:
154
+ logger.error("Aucun fichier n'a été téléchargé")
155
  raise FileNotFoundError("Aucun fichier n'a été téléchargé")
156
 
157
  video_path = os.path.join(temp_dir, downloaded_files[0])
158
 
 
159
  temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(video_path)[1])
160
  with open(video_path, 'rb') as f:
161
  temp_file.write(f.read())
162
 
163
+ logger.info(f"Vidéo téléchargée avec succès: {temp_file.name}")
164
  return temp_file.name
165
 
166
  except Exception as e:
167
+ logger.error(f"Erreur lors du téléchargement de la vidéo: {e}")
168
  return None
169
 
170
  def telecharger_pdf(url):
171
  """Télécharge un PDF et retourne le chemin du fichier"""
172
  try:
173
+ logger.info(f"Début du téléchargement du PDF: {url}")
174
  response = requests.get(url)
175
  response.raise_for_status()
176
 
177
  with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as temp_file:
178
  temp_file.write(response.content)
179
+ logger.info(f"PDF téléchargé avec succès: {temp_file.name}")
180
  return temp_file.name
181
  except Exception as e:
182
+ logger.error(f"Erreur lors du téléchargement du PDF: {e}")
183
  return None
184
 
185
  def allowed_file(filename):
 
189
 
190
  @app.route('/submit', methods=['POST'])
191
  def submit_question():
192
+ logger.info("Nouvelle soumission reçue")
193
  question = request.form.get('question')
194
  urls = request.form.getlist('urls')
195
  files = request.files.getlist('files')
196
 
197
+ logger.info(f"Question reçue: {question}")
198
+ logger.info(f"URLs reçues: {urls}")
199
+ logger.info(f"Nombre de fichiers reçus: {len(files)}")
200
+
201
  content = [question]
202
  temp_files = []
203
 
 
205
  # Traitement des fichiers uploadés
206
  for file in files:
207
  if file and allowed_file(file.filename):
208
+ logger.info(f"Traitement du fichier: {file.filename}")
209
  with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(file.filename)[1]) as temp_file:
210
  file.save(temp_file.name)
211
  temp_files.append(temp_file.name)
212
  if file.filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
213
  content.append(PIL.Image.open(temp_file.name))
214
+ logger.info(f"Image ajoutée au contenu: {file.filename}")
215
  else:
216
  uploaded_file = upload_and_process_file(temp_file.name)
217
  content.append(uploaded_file)
218
+ logger.info(f"Fichier uploadé et ajouté au contenu: {file.filename}")
219
 
220
  # Traitement des URLs
221
  for url in urls:
222
+ logger.info(f"Traitement de l'URL: {url}")
223
  if is_youtube_url(url):
224
  video_path = download_youtube_video(url)
225
  if video_path:
226
  temp_files.append(video_path)
227
  uploaded_file = upload_and_process_file(video_path)
228
  content.append(uploaded_file)
229
+ logger.info(f"Vidéo YouTube traitée et ajoutée au contenu: {url}")
230
  elif url.lower().endswith('.pdf'):
231
  pdf_path = telecharger_pdf(url)
232
  if pdf_path:
233
  temp_files.append(pdf_path)
234
  uploaded_file = upload_and_process_file(pdf_path)
235
  content.append(uploaded_file)
236
+ logger.info(f"PDF téléchargé et ajouté au contenu: {url}")
 
 
237
 
238
  # Génération de contenu avec Gemini
239
+ logger.info("Initialisation du modèle Gemini")
240
  model = genai.GenerativeModel(
241
  model_name="models/gemini-2.0-flash-exp",
242
  safety_settings=safety_settings,
243
  system_instruction="Tu es un assistant intelligent. ton but est d'assister au mieux que tu peux. tu as été créé par Aenir et tu t'appelles Mariam."
244
  )
245
+
246
+ logger.info("Génération de la réponse")
247
  response = model.generate_content(content, request_options={"timeout": 600})
248
+ logger.info("Réponse générée avec succès")
249
+
250
  return jsonify({"response": response.text})
251
 
252
  except Exception as e:
253
+ logger.error(f"Erreur lors du traitement de la requête: {e}", exc_info=True)
254
  return jsonify({"error": str(e)}), 500
255
  finally:
256
  # Nettoyage des fichiers temporaires
257
  for temp_file in temp_files:
258
  try:
259
  os.unlink(temp_file)
260
+ logger.debug(f"Fichier temporaire supprimé: {temp_file}")
261
  except Exception as e:
262
+ logger.error(f"Erreur lors de la suppression du fichier temporaire {temp_file}: {e}")
 
263
 
264
+ if __name__ == '__main__':
265
+ logger.info("Démarrage de l'application")
266
+ app.run()