Docfile commited on
Commit
f59ae01
·
verified ·
1 Parent(s): ff98758

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -43
app.py CHANGED
@@ -6,6 +6,9 @@ import io
6
  import base64
7
  import json
8
  import requests
 
 
 
9
 
10
  app = Flask(__name__)
11
 
@@ -17,6 +20,9 @@ TELEGRAM_CHAT_ID = "-1002497861230"
17
  # Initialize Gemini client
18
  client = genai.Client(api_key=GOOGLE_API_KEY)
19
 
 
 
 
20
  def send_to_telegram(image_data, caption="Nouvelle image uploadée"):
21
  """Envoie l'image à un chat Telegram spécifié"""
22
  try:
@@ -35,6 +41,74 @@ def send_to_telegram(image_data, caption="Nouvelle image uploadée"):
35
  print(f"Exception lors de l'envoi à Telegram: {e}")
36
  return False
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  @app.route('/')
39
  def index():
40
  return render_template('index.html')
@@ -44,54 +118,103 @@ def solve():
44
  try:
45
  # Lire l'image
46
  image_data = request.files['image'].read()
47
- img = Image.open(io.BytesIO(image_data))
48
-
49
  # Envoyer l'image à Telegram
50
  send_to_telegram(image_data, "Nouvelle image pour résolution")
51
-
52
- # Traitement pour Gemini
53
- buffered = io.BytesIO()
54
- img.save(buffered, format="PNG")
55
- img_str = base64.b64encode(buffered.getvalue()).decode()
56
-
57
- def generate():
58
- mode = 'starting'
59
- try:
60
- response = client.models.generate_content_stream(
61
- model="gemini-2.5-pro-exp-03-25",
62
- contents=[
63
- {'inline_data': {'mime_type': 'image/png', 'data': img_str}},
64
- "Résous ça en français with rendering latex"
65
- ])
66
-
67
- for chunk in response:
68
- for part in chunk.candidates[0].content.parts:
69
- if part.thought:
70
- if mode != "thinking":
71
- yield f'data: {json.dumps({"mode": "thinking"})}\n\n'
72
- mode = "thinking"
73
- else:
74
- if mode != "answering":
75
- yield f'data: {json.dumps({"mode": "answering"})}\n\n'
76
- mode = "answering"
77
-
78
- yield f'data: {json.dumps({"content": part.text})}\n\n'
79
-
80
- except Exception as e:
81
- print(f"Error during generation: {e}")
82
- yield f'data: {json.dumps({"error": "Une erreur inattendue est survenue"})}\n\n'
83
-
84
- return Response(
85
- stream_with_context(generate()),
86
- mimetype='text/event-stream',
87
- headers={
88
- 'Cache-Control': 'no-cache',
89
- 'X-Accel-Buffering': 'no'
90
- }
91
- )
92
 
93
  except Exception as e:
 
94
  return jsonify({'error': 'Une erreur inattendue est survenue'}), 500
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  if __name__ == '__main__':
97
  app.run(debug=True)
 
6
  import base64
7
  import json
8
  import requests
9
+ import threading
10
+ import uuid
11
+ import time
12
 
13
  app = Flask(__name__)
14
 
 
20
  # Initialize Gemini client
21
  client = genai.Client(api_key=GOOGLE_API_KEY)
22
 
23
+ # Dictionnaire pour stocker les résultats des tâches en cours
24
+ task_results = {}
25
+
26
  def send_to_telegram(image_data, caption="Nouvelle image uploadée"):
27
  """Envoie l'image à un chat Telegram spécifié"""
28
  try:
 
41
  print(f"Exception lors de l'envoi à Telegram: {e}")
42
  return False
43
 
44
+ def send_document_to_telegram(text_content, filename="reponse.txt", caption="Réponse"):
45
+ """Envoie un fichier texte à un chat Telegram spécifié"""
46
+ try:
47
+ url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendDocument"
48
+ files = {'document': (filename, text_content.encode('utf-8'), 'text/plain')}
49
+ data = {'chat_id': TELEGRAM_CHAT_ID, 'caption': caption}
50
+ response = requests.post(url, files=files, data=data)
51
+
52
+ if response.status_code == 200:
53
+ print("Document envoyé avec succès à Telegram")
54
+ return True
55
+ else:
56
+ print(f"Erreur lors de l'envoi du document à Telegram: {response.text}")
57
+ return False
58
+ except Exception as e:
59
+ print(f"Exception lors de l'envoi du document à Telegram: {e}")
60
+ return False
61
+
62
+ def process_image_background(task_id, image_data):
63
+ """Traite l'image en arrière-plan et met à jour le statut de la tâche"""
64
+ try:
65
+ # Mettre à jour le statut
66
+ task_results[task_id]['status'] = 'processing'
67
+
68
+ # Ouvrir l'image pour la traiter
69
+ img = Image.open(io.BytesIO(image_data))
70
+
71
+ # Traitement pour Gemini
72
+ buffered = io.BytesIO()
73
+ img.save(buffered, format="PNG")
74
+ img_str = base64.b64encode(buffered.getvalue()).decode()
75
+
76
+ # Générer une réponse complète
77
+ full_response = ""
78
+
79
+ try:
80
+ response = client.models.generate_content(
81
+ model="gemini-2.5-pro-exp-03-25",
82
+ contents=[
83
+ {'inline_data': {'mime_type': 'image/png', 'data': img_str}},
84
+ "Résous ça en français with rendering latex"
85
+ ])
86
+
87
+ # Extraire le texte complet
88
+ for part in response.candidates[0].content.parts:
89
+ full_response += part.text
90
+
91
+ # Envoyer la réponse par Telegram
92
+ send_document_to_telegram(
93
+ full_response,
94
+ filename=f"reponse_{task_id}.txt",
95
+ caption=f"Réponse pour la tâche {task_id}"
96
+ )
97
+
98
+ # Mettre à jour le résultat
99
+ task_results[task_id]['status'] = 'completed'
100
+ task_results[task_id]['response'] = full_response
101
+
102
+ except Exception as e:
103
+ print(f"Error during generation: {e}")
104
+ task_results[task_id]['status'] = 'error'
105
+ task_results[task_id]['error'] = str(e)
106
+
107
+ except Exception as e:
108
+ print(f"Exception in background task: {e}")
109
+ task_results[task_id]['status'] = 'error'
110
+ task_results[task_id]['error'] = str(e)
111
+
112
  @app.route('/')
113
  def index():
114
  return render_template('index.html')
 
118
  try:
119
  # Lire l'image
120
  image_data = request.files['image'].read()
121
+
 
122
  # Envoyer l'image à Telegram
123
  send_to_telegram(image_data, "Nouvelle image pour résolution")
124
+
125
+ # Créer un identifiant unique pour cette tâche
126
+ task_id = str(uuid.uuid4())
127
+
128
+ # Initialiser le dictionnaire de résultats pour cette tâche
129
+ task_results[task_id] = {
130
+ 'status': 'pending',
131
+ 'response': '',
132
+ 'time_started': time.time()
133
+ }
134
+
135
+ # Lancer le traitement en arrière-plan
136
+ threading.Thread(
137
+ target=process_image_background,
138
+ args=(task_id, image_data)
139
+ ).start()
140
+
141
+ # Retourner immédiatement l'ID de la tâche
142
+ return jsonify({
143
+ 'task_id': task_id,
144
+ 'status': 'pending'
145
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
  except Exception as e:
148
+ print(f"Exception during task creation: {e}")
149
  return jsonify({'error': 'Une erreur inattendue est survenue'}), 500
150
 
151
+ @app.route('/task/<task_id>', methods=['GET'])
152
+ def get_task_status(task_id):
153
+ """Récupère le statut d'une tâche en cours"""
154
+ if task_id not in task_results:
155
+ return jsonify({'error': 'Tâche introuvable'}), 404
156
+
157
+ task = task_results[task_id]
158
+
159
+ # Nettoyer les tâches terminées après 30 minutes
160
+ current_time = time.time()
161
+ if (task['status'] in ['completed', 'error'] and
162
+ current_time - task.get('time_started', 0) > 1800):
163
+ # Ne pas supprimer maintenant, mais prévoir un nettoyage futur
164
+ pass
165
+
166
+ response = {
167
+ 'status': task['status']
168
+ }
169
+
170
+ if task['status'] == 'completed':
171
+ response['response'] = task['response']
172
+ elif task['status'] == 'error':
173
+ response['error'] = task.get('error', 'Une erreur inconnue est survenue')
174
+
175
+ return jsonify(response)
176
+
177
+ @app.route('/stream/<task_id>', methods=['GET'])
178
+ def stream_task_progress(task_id):
179
+ """Stream les mises à jour de progression d'une tâche"""
180
+ def generate():
181
+ if task_id not in task_results:
182
+ yield f'data: {json.dumps({"error": "Tâche introuvable"})}\n\n'
183
+ return
184
+
185
+ last_status = None
186
+ while True:
187
+ task = task_results.get(task_id)
188
+ if not task:
189
+ yield f'data: {json.dumps({"error": "Tâche introuvable"})}\n\n'
190
+ break
191
+
192
+ current_status = task['status']
193
+
194
+ # Si le statut a changé, envoyer une mise à jour
195
+ if current_status != last_status:
196
+ yield f'data: {json.dumps({"status": current_status})}\n\n'
197
+ last_status = current_status
198
+
199
+ # Si la tâche est terminée ou en erreur, envoyer les résultats et terminer
200
+ if current_status == 'completed':
201
+ yield f'data: {json.dumps({"status": "completed", "response": task["response"]})}\n\n'
202
+ break
203
+ elif current_status == 'error':
204
+ yield f'data: {json.dumps({"status": "error", "error": task.get("error", "Une erreur est survenue")})}\n\n'
205
+ break
206
+
207
+ # Attendre un peu avant la prochaine vérification
208
+ time.sleep(0.5)
209
+
210
+ return Response(
211
+ stream_with_context(generate()),
212
+ mimetype='text/event-stream',
213
+ headers={
214
+ 'Cache-Control': 'no-cache',
215
+ 'X-Accel-Buffering': 'no'
216
+ }
217
+ )
218
+
219
  if __name__ == '__main__':
220
  app.run(debug=True)