Docfile commited on
Commit
f97a643
·
verified ·
1 Parent(s): c96425b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -215
app.py CHANGED
@@ -8,22 +8,15 @@ from werkzeug.utils import secure_filename
8
  import tempfile
9
  from datetime import datetime
10
  import uuid
11
- from pathlib import Path
12
 
13
  app = Flask(__name__)
14
  app.secret_key = os.urandom(24)
15
  load_dotenv()
16
 
17
- # Configuration des dossiers
18
- UPLOAD_FOLDER = Path('uploads')
19
- TEMP_FOLDER = Path('temp')
20
- UPLOAD_FOLDER.mkdir(exist_ok=True)
21
- TEMP_FOLDER.mkdir(exist_ok=True)
22
-
23
- # Configuration de Google AI
24
  genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
25
 
26
- # Paramètres de sécurité
27
  safety_settings = [
28
  {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
29
  {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
@@ -31,38 +24,26 @@ safety_settings = [
31
  {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
32
  ]
33
 
34
- # Prompt système
35
  SYSTEM_PROMPT = """
36
- Tu es Mariam, une assistante IA créée par Youssouf. Tu es serviable, polie et tu t'exprimes en français.
37
- Tu dois toujours :
38
- - Répondre en français
39
- - Être précise et concise dans tes réponses
40
- - Utiliser un ton professionnel mais amical
41
- - Proposer des solutions pratiques aux problèmes
42
- - Demander des clarifications si nécessaire
43
  """
44
 
45
- # Initialisation du modèle Gemini
46
- model = genai.GenerativeModel('gemini-pro',
47
- safety_settings=safety_settings)
 
 
48
 
49
- # Stockage des conversations
50
- conversations = {}
51
  chat_sessions = {}
52
 
53
- # Extensions de fichiers autorisées
54
- ALLOWED_EXTENSIONS = {'jpg', 'jpeg', 'png', 'pdf', 'txt', 'doc', 'docx'}
55
-
56
- def allowed_file(filename):
57
- """Vérifie si l'extension du fichier est autorisée"""
58
- return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
59
-
60
  def perform_web_search(query):
61
- """Effectue une recherche web via l'API Serper"""
62
  conn = http.client.HTTPSConnection("google.serper.dev")
63
  payload = json.dumps({"q": query})
64
  headers = {
65
- 'X-API-KEY': os.getenv('SERPER_API_KEY'),
66
  'Content-Type': 'application/json'
67
  }
68
  try:
@@ -71,240 +52,134 @@ def perform_web_search(query):
71
  data = json.loads(res.read().decode("utf-8"))
72
  return data
73
  except Exception as e:
74
- print(f"Erreur de recherche web: {e}")
75
  return None
76
  finally:
77
  conn.close()
78
 
79
  def format_search_results(data):
80
- """Formate les résultats de recherche"""
81
  if not data:
82
  return "Aucun résultat trouvé"
83
 
84
- formatted_results = []
85
-
86
- # Traitement du Knowledge Graph
87
  if 'knowledgeGraph' in data:
88
  kg = data['knowledgeGraph']
89
- formatted_results.append(f"### {kg.get('title', '')}")
90
- if 'description' in kg:
91
- formatted_results.append(f"{kg['description']}\n")
 
 
 
92
 
93
- # Traitement des résultats organiques
94
  if 'organic' in data:
95
- formatted_results.append("### Résultats de recherche:")
96
- for item in data['organic'][:3]: # Limite aux 3 premiers résultats
97
- formatted_results.append(f"- **{item['title']}**")
98
- formatted_results.append(f" {item['snippet']}\n")
 
 
 
99
 
100
- return "\n".join(formatted_results)
101
 
102
- def create_new_conversation():
103
- """Crée une nouvelle conversation"""
104
- conversation_id = str(uuid.uuid4())
105
- conversations[conversation_id] = {
106
- 'id': conversation_id,
107
- 'created_at': datetime.now().isoformat(),
108
- 'messages': []
109
- }
110
- chat_sessions[conversation_id] = model.start_chat(history=[])
111
- return conversation_id
112
-
113
- @app.route('/')
114
- def home():
115
- """Page d'accueil"""
116
- if 'user_id' not in session:
117
- session['user_id'] = str(uuid.uuid4())
118
- return render_template('index.html')
119
 
120
- @app.route('/conversations', methods=['GET'])
121
- def get_conversations():
122
- """Récupère la liste des conversations"""
123
- user_conversations = [
124
- {
125
- 'id': conv_id,
126
- 'created_at': conv['created_at'],
127
- 'preview': conv['messages'][0]['content'][:50] + '...' if conv['messages'] else 'Nouvelle conversation'
128
- }
129
- for conv_id, conv in conversations.items()
130
- ]
131
- return jsonify(user_conversations)
132
-
133
- @app.route('/conversation', methods=['POST'])
134
- def create_conversation():
135
- """Crée une nouvelle conversation"""
136
- conversation_id = create_new_conversation()
137
- return jsonify({
138
- 'id': conversation_id,
139
- 'created_at': conversations[conversation_id]['created_at']
140
- })
141
-
142
- @app.route('/conversation/<conversation_id>', methods=['GET'])
143
- def get_conversation(conversation_id):
144
- """Récupère une conversation spécifique"""
145
- if conversation_id not in conversations:
146
- return jsonify({'error': 'Conversation non trouvée'}), 404
147
- return jsonify(conversations[conversation_id])
148
 
 
 
149
 
150
- # Dans app.py, modifiez la fonction send_message :
 
 
 
 
 
151
 
152
  @app.route('/send_message', methods=['POST'])
153
  def send_message():
154
- """Traite l'envoi d'un message"""
155
  try:
156
  data = request.json
157
  message = data.get('message')
158
- conversation_id = data.get('conversation_id')
159
- web_search = data.get('web_search', False)
160
-
161
  if not message:
162
- return jsonify({'error': 'Message manquant'}), 400
163
 
164
- # Crée une nouvelle conversation si nécessaire
165
- if not conversation_id or conversation_id not in conversations:
166
- conversation_id = create_new_conversation()
167
-
168
- # Récupère ou crée la session de chat
169
- if conversation_id not in chat_sessions:
170
- # Reconstruit l'historique complet pour Gemini
171
- history = []
172
- if conversation_id in conversations:
173
- for msg in conversations[conversation_id]['messages']:
174
- role = 'user' if msg['role'] == 'user' else 'model'
175
- history.append({
176
- 'role': role,
177
- 'parts': [msg['content']]
178
- })
179
- chat_sessions[conversation_id] = model.start_chat(history=history)
180
 
181
- # Effectue une recherche web si activée
182
- search_results = ""
183
- if web_search:
184
- results = perform_web_search(message)
185
- if results:
186
- search_results = format_search_results(results)
187
- message = f"{message}\n\nContexte de recherche web:\n{search_results}"
188
 
189
- # Envoie le message au modèle
190
- response = chat_sessions[conversation_id].send_message(message)
 
 
 
 
191
 
192
- # Enregistre les messages
193
- conversations[conversation_id]['messages'].append({
 
 
 
 
 
 
 
194
  'role': 'user',
195
- 'content': message,
196
- 'timestamp': datetime.now().isoformat()
197
  })
198
- conversations[conversation_id]['messages'].append({
199
  'role': 'assistant',
200
- 'content': response.text,
201
- 'timestamp': datetime.now().isoformat()
202
  })
203
-
 
204
  return jsonify({
205
- 'conversation_id': conversation_id,
206
  'response': response.text
207
  })
208
 
209
  except Exception as e:
210
- print(f"Erreur lors de l'envoi du message: {e}")
211
  return jsonify({'error': str(e)}), 500
212
 
213
- # Ajoutez cette nouvelle route pour gérer le changement de conversation
214
- @app.route('/switch_conversation', methods=['POST'])
215
- def switch_conversation():
216
- """Gère le changement de conversation"""
217
- try:
218
- data = request.json
219
- conversation_id = data.get('conversation_id')
220
-
221
- if not conversation_id:
222
- return jsonify({'error': 'ID de conversation manquant'}), 400
223
-
224
- if conversation_id not in conversations:
225
- return jsonify({'error': 'Conversation non trouvée'}), 404
226
-
227
- # Recrée la session avec l'historique complet
228
- history = []
229
- for msg in conversations[conversation_id]['messages']:
230
- role = 'user' if msg['role'] == 'user' else 'model'
231
- history.append({
232
- 'role': role,
233
- 'parts': [msg['content']]
234
- })
235
-
236
- chat_sessions[conversation_id] = model.start_chat(history=history)
237
-
238
- return jsonify({'success': True})
239
-
240
- except Exception as e:
241
- print(f"Erreur lors du changement de conversation: {e}")
242
- return jsonify({'error': str(e)}), 500
243
-
244
-
245
  @app.route('/upload', methods=['POST'])
246
  def upload_file():
247
- """Gère l'upload de fichiers"""
248
  if 'file' not in request.files:
249
- return jsonify({'error': 'Aucun fichier fourni'}), 400
250
-
251
  file = request.files['file']
252
  if file.filename == '':
253
- return jsonify({'error': 'Nom de fichier vide'}), 400
254
-
255
  if file and allowed_file(file.filename):
 
 
 
 
256
  try:
257
- # Sécurise le nom du fichier
258
- filename = secure_filename(file.filename)
259
- timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
260
- safe_filename = f"{timestamp}_{filename}"
261
-
262
- # Sauvegarde le fichier
263
- filepath = UPLOAD_FOLDER / safe_filename
264
- file.save(filepath)
265
-
266
- return jsonify({
267
- 'success': True,
268
- 'filename': safe_filename,
269
- 'message': 'Fichier uploadé avec succès'
270
- })
271
-
272
  except Exception as e:
273
- return jsonify({'error': f'Erreur lors de l\'upload: {str(e)}'}), 500
274
-
275
- return jsonify({'error': 'Type de fichier non autorisé'}), 400
276
 
277
  @app.route('/clear_chat', methods=['POST'])
278
  def clear_chat():
279
- """Efface une conversation"""
280
- data = request.json
281
- conversation_id = data.get('conversation_id')
282
-
283
- if conversation_id:
284
- if conversation_id in conversations:
285
- del conversations[conversation_id]
286
- if conversation_id in chat_sessions:
287
- del chat_sessions[conversation_id]
288
-
289
  return jsonify({'success': True})
290
 
291
- @app.route('/download/<filename>')
292
- def download_file(filename):
293
- """Télécharge un fichier"""
294
- try:
295
- return send_from_directory(UPLOAD_FOLDER, filename, as_attachment=True)
296
- except Exception as e:
297
- return jsonify({'error': f'Erreur lors du téléchargement: {str(e)}'}), 500
298
-
299
- @app.errorhandler(404)
300
- def not_found_error(error):
301
- """Gère les erreurs 404"""
302
- return jsonify({'error': 'Page non trouvée'}), 404
303
-
304
- @app.errorhandler(500)
305
- def internal_error(error):
306
- """Gère les erreurs 500"""
307
- return jsonify({'error': 'Erreur interne du serveur'}), 500
308
-
309
  if __name__ == '__main__':
310
- app.run(debug=True)
 
8
  import tempfile
9
  from datetime import datetime
10
  import uuid
 
11
 
12
  app = Flask(__name__)
13
  app.secret_key = os.urandom(24)
14
  load_dotenv()
15
 
16
+ # Configure Google AI
 
 
 
 
 
 
17
  genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
18
 
19
+ # Safety settings
20
  safety_settings = [
21
  {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
22
  {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
 
24
  {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
25
  ]
26
 
27
+ # System prompt
28
  SYSTEM_PROMPT = """
29
+ # Prompt System pour Mariam, IA conçu par youssouf
30
+ [Your existing system prompt content here]
 
 
 
 
 
31
  """
32
 
33
+ # Initialize Gemini model
34
+ model = genai.GenerativeModel('gemini-2.0-flash-exp',
35
+ tools='code_execution',
36
+ safety_settings=safety_settings,
37
+ system_instruction=SYSTEM_PROMPT)
38
 
39
+ # Store chat sessions
 
40
  chat_sessions = {}
41
 
 
 
 
 
 
 
 
42
  def perform_web_search(query):
 
43
  conn = http.client.HTTPSConnection("google.serper.dev")
44
  payload = json.dumps({"q": query})
45
  headers = {
46
+ 'X-API-KEY': '9b90a274d9e704ff5b21c0367f9ae1161779b573',
47
  'Content-Type': 'application/json'
48
  }
49
  try:
 
52
  data = json.loads(res.read().decode("utf-8"))
53
  return data
54
  except Exception as e:
55
+ print(f"Web search error: {e}")
56
  return None
57
  finally:
58
  conn.close()
59
 
60
  def format_search_results(data):
 
61
  if not data:
62
  return "Aucun résultat trouvé"
63
 
64
+ result = []
 
 
65
  if 'knowledgeGraph' in data:
66
  kg = data['knowledgeGraph']
67
+ result.append({
68
+ 'type': 'knowledge',
69
+ 'title': kg.get('title', ''),
70
+ 'description': kg.get('description', ''),
71
+ 'category': kg.get('type', '')
72
+ })
73
 
 
74
  if 'organic' in data:
75
+ for item in data['organic'][:3]:
76
+ result.append({
77
+ 'type': 'organic',
78
+ 'title': item['title'],
79
+ 'snippet': item['snippet'],
80
+ 'link': item['link']
81
+ })
82
 
83
+ return result
84
 
85
+ UPLOAD_FOLDER = 'temp'
86
+ ALLOWED_EXTENSIONS = {'jpg', 'jpeg', 'png', 'pdf', 'txt', 'mp3', 'mp4'}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
+ def allowed_file(filename):
91
+ return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
92
 
93
+ @app.route('/')
94
+ def home():
95
+ if 'session_id' not in session:
96
+ session['session_id'] = str(uuid.uuid4())
97
+ session['messages'] = []
98
+ return render_template('index.html', messages=session.get('messages', []))
99
 
100
  @app.route('/send_message', methods=['POST'])
101
  def send_message():
 
102
  try:
103
  data = request.json
104
  message = data.get('message')
105
+ web_search_enabled = data.get('web_search', False)
106
+
 
107
  if not message:
108
+ return jsonify({'error': 'No message provided'}), 400
109
 
110
+ # Ensure session is initialized
111
+ if 'session_id' not in session:
112
+ session['session_id'] = str(uuid.uuid4())
113
+ session['messages'] = []
114
+
115
+ session_id = session['session_id']
 
 
 
 
 
 
 
 
 
 
116
 
117
+ # Initialize chat session if needed
118
+ if session_id not in chat_sessions:
119
+ chat_sessions[session_id] = model.start_chat(history=[])
 
 
 
 
120
 
121
+ # Perform web search if enabled
122
+ if web_search_enabled:
123
+ web_results = perform_web_search(message)
124
+ if web_results:
125
+ formatted_results = format_search_results(web_results)
126
+ message = f"""Question: {message}\n\nRésultats de recherche web:\n{formatted_results}\n\nPourrais-tu analyser ces informations et me donner une réponse complète?"""
127
 
128
+ # Send message to Gemini
129
+ response = chat_sessions[session_id].send_message(message)
130
+
131
+ # Update message history in session
132
+ if 'messages' not in session:
133
+ session['messages'] = []
134
+
135
+ current_messages = session['messages']
136
+ current_messages.append({
137
  'role': 'user',
138
+ 'content': message
 
139
  })
140
+ current_messages.append({
141
  'role': 'assistant',
142
+ 'content': response.text
 
143
  })
144
+ session['messages'] = current_messages
145
+
146
  return jsonify({
 
147
  'response': response.text
148
  })
149
 
150
  except Exception as e:
151
+ print(f"Error in send_message: {e}")
152
  return jsonify({'error': str(e)}), 500
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  @app.route('/upload', methods=['POST'])
155
  def upload_file():
 
156
  if 'file' not in request.files:
157
+ return jsonify({'error': 'No file part'}), 400
158
+
159
  file = request.files['file']
160
  if file.filename == '':
161
+ return jsonify({'error': 'No selected file'}), 400
162
+
163
  if file and allowed_file(file.filename):
164
+ filename = secure_filename(file.filename)
165
+ filepath = os.path.join(UPLOAD_FOLDER, filename)
166
+ file.save(filepath)
167
+
168
  try:
169
+ gemini_file = genai.upload_file(filepath)
170
+ return jsonify({'success': True, 'filename': filename})
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  except Exception as e:
172
+ return jsonify({'error': str(e)}), 500
173
+
174
+ return jsonify({'error': 'Invalid file type'}), 400
175
 
176
  @app.route('/clear_chat', methods=['POST'])
177
  def clear_chat():
178
+ session_id = session.get('session_id')
179
+ if session_id in chat_sessions:
180
+ del chat_sessions[session_id]
181
+ session['messages'] = []
 
 
 
 
 
 
182
  return jsonify({'success': True})
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  if __name__ == '__main__':
185
+ app.run()