Docfile commited on
Commit
4979ae3
·
verified ·
1 Parent(s): 7ddeafc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -94
app.py CHANGED
@@ -8,15 +8,22 @@ from werkzeug.utils import secure_filename
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,26 +31,38 @@ safety_settings = [
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,134 +71,192 @@ def perform_web_search(query):
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()
 
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
  {"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
  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
  @app.route('/send_message', methods=['POST'])
150
  def send_message():
151
+ """Traite l'envoi d'un message"""
152
  try:
153
  data = request.json
154
  message = data.get('message')
155
+ conversation_id = data.get('conversation_id')
156
+ web_search = data.get('web_search', False)
157
+
158
  if not message:
159
+ return jsonify({'error': 'Message manquant'}), 400
160
+
161
+ # Crée une nouvelle conversation si nécessaire
162
+ if not conversation_id or conversation_id not in conversations:
163
+ conversation_id = create_new_conversation()
164
+
165
+ # Effectue une recherche web si activée
166
+ search_results = ""
167
+ if web_search:
168
+ results = perform_web_search(message)
169
+ if results:
170
+ search_results = format_search_results(results)
171
+ message = f"{message}\n\nContexte de recherche web:\n{search_results}"
172
+
173
+ # Envoie le message au modèle
174
+ response = chat_sessions[conversation_id].send_message(message)
175
+
176
+ # Enregistre les messages
177
+ conversations[conversation_id]['messages'].append({
 
 
 
 
 
 
 
 
 
 
178
  'role': 'user',
179
+ 'content': message,
180
+ 'timestamp': datetime.now().isoformat()
181
  })
182
+ conversations[conversation_id]['messages'].append({
183
  'role': 'assistant',
184
+ 'content': response.text,
185
+ 'timestamp': datetime.now().isoformat()
186
  })
187
+
 
188
  return jsonify({
189
+ 'conversation_id': conversation_id,
190
  'response': response.text
191
  })
192
 
193
  except Exception as e:
194
+ print(f"Erreur lors de l'envoi du message: {e}")
195
  return jsonify({'error': str(e)}), 500
196
 
197
  @app.route('/upload', methods=['POST'])
198
  def upload_file():
199
+ """Gère l'upload de fichiers"""
200
  if 'file' not in request.files:
201
+ return jsonify({'error': 'Aucun fichier fourni'}), 400
202
+
203
  file = request.files['file']
204
  if file.filename == '':
205
+ return jsonify({'error': 'Nom de fichier vide'}), 400
206
+
207
  if file and allowed_file(file.filename):
 
 
 
 
208
  try:
209
+ # Sécurise le nom du fichier
210
+ filename = secure_filename(file.filename)
211
+ timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
212
+ safe_filename = f"{timestamp}_{filename}"
213
+
214
+ # Sauvegarde le fichier
215
+ filepath = UPLOAD_FOLDER / safe_filename
216
+ file.save(filepath)
217
+
218
+ return jsonify({
219
+ 'success': True,
220
+ 'filename': safe_filename,
221
+ 'message': 'Fichier uploadé avec succès'
222
+ })
223
+
224
  except Exception as e:
225
+ return jsonify({'error': f'Erreur lors de l\'upload: {str(e)}'}), 500
226
+
227
+ return jsonify({'error': 'Type de fichier non autorisé'}), 400
228
 
229
  @app.route('/clear_chat', methods=['POST'])
230
  def clear_chat():
231
+ """Efface une conversation"""
232
+ data = request.json
233
+ conversation_id = data.get('conversation_id')
234
+
235
+ if conversation_id:
236
+ if conversation_id in conversations:
237
+ del conversations[conversation_id]
238
+ if conversation_id in chat_sessions:
239
+ del chat_sessions[conversation_id]
240
+
241
  return jsonify({'success': True})
242
 
243
+ @app.route('/download/<filename>')
244
+ def download_file(filename):
245
+ """Télécharge un fichier"""
246
+ try:
247
+ return send_from_directory(UPLOAD_FOLDER, filename, as_attachment=True)
248
+ except Exception as e:
249
+ return jsonify({'error': f'Erreur lors du téléchargement: {str(e)}'}), 500
250
+
251
+ @app.errorhandler(404)
252
+ def not_found_error(error):
253
+ """Gère les erreurs 404"""
254
+ return jsonify({'error': 'Page non trouvée'}), 404
255
+
256
+ @app.errorhandler(500)
257
+ def internal_error(error):
258
+ """Gère les erreurs 500"""
259
+ return jsonify({'error': 'Erreur interne du serveur'}), 500
260
+
261
  if __name__ == '__main__':
262
+ app.run(debug=True)