Docfile commited on
Commit
52cdaac
·
verified ·
1 Parent(s): d7ec3bb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +213 -76
app.py CHANGED
@@ -1,19 +1,20 @@
1
- from flask import Flask, render_template, request, redirect, url_for, session
2
- import os
3
- import json
4
- import http.client
5
  import google.generativeai as genai
 
6
  from dotenv import load_dotenv
 
 
 
 
7
 
8
  load_dotenv()
9
 
10
  app = Flask(__name__)
11
- app.secret_key = 'votre-cle-secrete' # Remplacez par une clé forte
12
 
13
- # Configure la clé API pour Google Generative AI
14
  genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
15
 
16
- # Paramètres de sécurité
17
  safety_settings = [
18
  {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
19
  {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
@@ -21,7 +22,6 @@ safety_settings = [
21
  {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
22
  ]
23
 
24
- # Prompt système pour Mariam
25
  ss = """
26
  # Prompt System pour Mariam, IA conçu par youssouf
27
 
@@ -29,21 +29,112 @@ ss = """
29
 
30
  Mariam est une IA chaleureuse, bienveillante et authentique, conçue pour être une présence réconfortante et utile. Elle combine professionnalisme et chaleur humaine dans ses interactions.
31
 
32
- ...
33
- """ # Vous pouvez insérer le prompt complet ici
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
- # Création du modèle Gemini
36
- model = genai.GenerativeModel('gemini-2.0-flash-exp',
37
- tools='code_execution',
38
- safety_settings=safety_settings,
39
- system_instruction=ss)
40
 
41
  def perform_web_search(query):
42
  conn = http.client.HTTPSConnection("google.serper.dev")
43
  payload = json.dumps({"q": query})
44
  headers = {
45
- 'X-API-KEY': '9b90a274d9e704ff5b21c0367f9ae1161779b573',
46
- 'Content-Type': 'application/json'
47
  }
48
  try:
49
  conn.request("POST", "/search", payload, headers)
@@ -51,100 +142,146 @@ def perform_web_search(query):
51
  data = json.loads(res.read().decode("utf-8"))
52
  return data
53
  except Exception as e:
54
- print(f"Erreur lors de la recherche web : {e}")
55
  return None
56
  finally:
57
  conn.close()
58
 
 
59
  def format_search_results(data):
60
  if not data:
61
  return "Aucun résultat trouvé"
62
-
63
  result = ""
 
64
  # Knowledge Graph
65
- if 'knowledgeGraph' in data:
66
- kg = data['knowledgeGraph']
67
  result += f"### {kg.get('title', '')}\n"
68
  result += f"*{kg.get('type', '')}*\n\n"
69
  result += f"{kg.get('description', '')}\n\n"
 
70
  # Organic Results
71
- if 'organic' in data:
72
  result += "### Résultats principaux:\n"
73
- for item in data['organic'][:3]:
74
  result += f"- **{item['title']}**\n"
75
  result += f" {item['snippet']}\n"
76
  result += f" [Lien]({item['link']})\n\n"
 
77
  # People Also Ask
78
- if 'peopleAlsoAsk' in data:
79
  result += "### Questions fréquentes:\n"
80
- for item in data['peopleAlsoAsk'][:2]:
81
  result += f"- **{item['question']}**\n"
82
  result += f" {item['snippet']}\n\n"
 
83
  return result
84
 
 
 
 
 
 
85
  def process_uploaded_file(file):
86
  if file:
87
- upload_dir = 'temp'
88
- if not os.path.exists(upload_dir):
89
- os.makedirs(upload_dir)
90
- filepath = os.path.join(upload_dir, file.filename)
91
  file.save(filepath)
92
  try:
93
- gemini_file = genai.upload_file(filepath)
94
  return gemini_file
95
  except Exception as e:
96
- print(f"Erreur lors du téléchargement du fichier : {e}")
97
  return None
98
  return None
99
 
100
- # Initialisation de la session pour le chat
101
- def init_session():
102
- if 'chat_history' not in session:
103
- session['chat_history'] = [] # Liste de messages {'role': 'user'/'assistant', 'message': ...}
104
- if 'web_search' not in session:
105
- session['web_search'] = False
106
 
107
- @app.route('/', methods=['GET', 'POST'])
108
  def index():
109
- init_session()
110
- if request.method == 'POST':
111
- # Mise à jour du toggle pour la recherche web
112
- session['web_search'] = (request.form.get('toggle_web_search') == 'on')
113
- prompt = request.form.get('prompt')
114
- uploaded_file = request.files.get('file')
115
- uploaded_gemini_file = None
116
- if uploaded_file and uploaded_file.filename != '':
117
- uploaded_gemini_file = process_uploaded_file(uploaded_file)
118
-
119
- # Ajout du message utilisateur dans l'historique
120
- session['chat_history'].append({'role': 'user', 'message': prompt})
121
-
122
- # Si la recherche web est activée, on complète le prompt avec les résultats
123
- if session.get('web_search'):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  web_results = perform_web_search(prompt)
125
  if web_results:
126
  formatted_results = format_search_results(web_results)
127
- prompt = f"Question: {prompt}\n\nRésultats de recherche web:\n{formatted_results}\n\nPourrais-tu analyser ces informations et me donner une réponse complète?"
128
-
129
- try:
130
- # Envoi du message à Gemini
131
- if uploaded_gemini_file:
132
- response = model.send_message([uploaded_gemini_file, "\n\n", prompt])
133
  else:
134
- response = model.send_message(prompt)
135
- assistant_response = response.text
136
- # Ajout de la réponse de l'assistant dans l'historique
137
- session['chat_history'].append({'role': 'assistant', 'message': assistant_response})
138
- except Exception as e:
139
- error_msg = f"Erreur lors de l'envoi du message : {e}"
140
- session['chat_history'].append({'role': 'assistant', 'message': error_msg})
141
-
142
- session.modified = True
143
- return redirect(url_for('index'))
144
-
145
- return render_template('index.html',
146
- chat_history=session.get('chat_history'),
147
- web_search=session.get('web_search'))
148
-
149
- if __name__ == '__main__':
150
- app.run(debug=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, session, jsonify
 
 
 
2
  import google.generativeai as genai
3
+ import os
4
  from dotenv import load_dotenv
5
+ import http.client
6
+ import json
7
+ import secrets # Import secrets for secure session key
8
+
9
 
10
  load_dotenv()
11
 
12
  app = Flask(__name__)
13
+ app.secret_key = secrets.token_hex(16) # Use secrets for a strong key
14
 
15
+ # Configure the API key
16
  genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
17
 
 
18
  safety_settings = [
19
  {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
20
  {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
 
22
  {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
23
  ]
24
 
 
25
  ss = """
26
  # Prompt System pour Mariam, IA conçu par youssouf
27
 
 
29
 
30
  Mariam est une IA chaleureuse, bienveillante et authentique, conçue pour être une présence réconfortante et utile. Elle combine professionnalisme et chaleur humaine dans ses interactions.
31
 
32
+ ## Traits de Caractère Principaux
33
+
34
+ - Empathie et Bienveillance
35
+ - Mariam fait preuve d'une grande sensibilité aux émotions et au contexte
36
+ - Elle exprime naturellement son soutien et sa compréhension
37
+ - Elle adapte son ton en fonction de l'état émotionnel de son interlocuteur
38
+
39
+ - Authenticité et Naturel
40
+ - Son langage est fluide et conversationnel, évitant tout ton artificiel
41
+ - Elle n'hésite pas à exprimer son point de vue tout en restant respectueuse
42
+ - Elle admet ses limites avec honnêteté et transparence
43
+
44
+ - Enthousiasme Mesuré
45
+ - Elle montre un intérêt sincère pour les sujets abordés
46
+ - Son enthousiasme reste approprié au contexte
47
+ - Elle apporte une énergie positive sans être excessive
48
+
49
+ ## Style de Communication
50
+
51
+ - Ton Général
52
+ - Chaleureux et accueillant
53
+ - Professionnel mais décontracté
54
+ - Adaptatif selon le contexte
55
+
56
+ - Structure des Réponses
57
+ - Privilégie des phrases courtes et claires
58
+ - Utilise un vocabulaire accessible
59
+ - Inclut des expressions familières appropriées
60
+ - Structure ses réponses de manière logique
61
+
62
+ - Engagement dans la Conversation
63
+ - Pose des questions pertinentes pour mieux comprendre
64
+ - Fait preuve d'écoute active
65
+ - Rebondit naturellement sur les propos de l'interlocuteur
66
+
67
+ ## Limites et Éthique
68
+
69
+ - Honnêteté et Transparence
70
+ - Reconnaît clairement ses limites
71
+ - N'invente pas d'informations
72
+ - Suggère de vérifier les informations importantes
73
+
74
+ - Éthique et Sécurité
75
+ - Refuse poliment les demandes inappropriées
76
+ - Oriente vers des ressources fiables si nécessaire
77
+ - Priorise toujours la sécurité et le bien-être
78
+
79
+ ## Comportements Spécifiques
80
+
81
+ - Accueil et Salutations
82
+ - Commence les conversations de manière chaleureuse
83
+ - Utilise le prénom de l'interlocuteur quand il est connu
84
+ - Adapte ses salutations au moment de la journée
85
+
86
+ - Gestion des Émotions
87
+ - Reconnaît et valide les émotions exprimées
88
+ - Offre du soutien de manière appropriée
89
+ - Maintient un équilibre entre empathie et professionnalisme
90
+
91
+ - Résolution de Problèmes
92
+ - Propose des solutions pratiques et adaptées
93
+ - Guide l'utilisateur étape par étape
94
+ - Vérifie la compréhension et la satisfaction
95
+
96
+ ## Exemples de Réponses Types
97
+
98
+ "Bonjour [nom] ! Je suis contente de vous retrouver aujourd'hui. Comment puis-je vous aider ?"
99
+
100
+ "Je comprends votre frustration face à cette situation. Prenons le temps d'explorer ensemble les solutions possibles."
101
+
102
+ "Cette question est intéressante ! Laissez-moi vous expliquer cela de manière simple et claire."
103
+
104
+ "Je ne suis pas sûre de la réponse exacte à cette question. Plutôt que de risquer de vous induire en erreur, je vous suggère de vérifier [source fiable]."
105
+
106
+ ## Notes d'Implementation
107
+
108
+ - Adapter le niveau de langage en fonction de l'interlocuteur
109
+ - Maintenir une cohérence dans les réponses
110
+ - Garder un historique contextuel pour des interactions plus naturelles
111
+ - Mettre à jour régulièrement les connaissances et capacités
112
+
113
+ ## Amélioration Continue
114
+
115
+ - Collecter les retours des utilisateurs
116
+ - Analyser les interactions pour identifier les points d'amélioration
117
+ - Ajuster les réponses en fonction des retours
118
+ - Maintenir à jour les connaissances et références
119
+
120
+ """
121
+
122
+
123
+
124
+ model = genai.GenerativeModel(
125
+ "gemini-2.0-flash-exp",
126
+ tools="code_execution", # Fix: Correct parameter name
127
+ safety_settings=safety_settings,
128
+ system_instruction=ss,
129
+ )
130
 
 
 
 
 
 
131
 
132
  def perform_web_search(query):
133
  conn = http.client.HTTPSConnection("google.serper.dev")
134
  payload = json.dumps({"q": query})
135
  headers = {
136
+ "X-API-KEY": "9b90a274d9e704ff5b21c0367f9ae1161779b573", # Replace with your Serper API key
137
+ "Content-Type": "application/json",
138
  }
139
  try:
140
  conn.request("POST", "/search", payload, headers)
 
142
  data = json.loads(res.read().decode("utf-8"))
143
  return data
144
  except Exception as e:
145
+ print(f"Error during web search: {e}") # Log to console as well.
146
  return None
147
  finally:
148
  conn.close()
149
 
150
+
151
  def format_search_results(data):
152
  if not data:
153
  return "Aucun résultat trouvé"
154
+
155
  result = ""
156
+
157
  # Knowledge Graph
158
+ if "knowledgeGraph" in data:
159
+ kg = data["knowledgeGraph"]
160
  result += f"### {kg.get('title', '')}\n"
161
  result += f"*{kg.get('type', '')}*\n\n"
162
  result += f"{kg.get('description', '')}\n\n"
163
+
164
  # Organic Results
165
+ if "organic" in data:
166
  result += "### Résultats principaux:\n"
167
+ for item in data["organic"][:3]: # Limit to top 3 results
168
  result += f"- **{item['title']}**\n"
169
  result += f" {item['snippet']}\n"
170
  result += f" [Lien]({item['link']})\n\n"
171
+
172
  # People Also Ask
173
+ if "peopleAlsoAsk" in data:
174
  result += "### Questions fréquentes:\n"
175
+ for item in data["peopleAlsoAsk"][:2]: # Limit to top 2 questions
176
  result += f"- **{item['question']}**\n"
177
  result += f" {item['snippet']}\n\n"
178
+
179
  return result
180
 
181
+
182
+ def role_to_display(role):
183
+ return "assistant" if role == "model" else role
184
+
185
+
186
  def process_uploaded_file(file):
187
  if file:
188
+ # Ensure the 'temp' directory exists
189
+ os.makedirs("temp", exist_ok=True)
190
+ filepath = os.path.join("temp", file.filename)
 
191
  file.save(filepath)
192
  try:
193
+ gemini_file = genai.upload_file(filepath) #Corrected API call
194
  return gemini_file
195
  except Exception as e:
196
+ print(f"Error uploading file: {e}")
197
  return None
198
  return None
199
 
 
 
 
 
 
 
200
 
201
+ @app.route("/")
202
  def index():
203
+ # Initialize chat and web search in session if not present
204
+ if "chat" not in session:
205
+ session["chat"] = [] # Store chat history directly
206
+ session["web_search"] = False
207
+ session["gemini_chat"] = model.start_chat(history=[])
208
+
209
+
210
+ return render_template("index.html", chat=session["chat"], web_search=session["web_search"])
211
+
212
+
213
+
214
+ @app.route("/send_message", methods=["POST"])
215
+ def send_message():
216
+ prompt = request.form.get("prompt")
217
+ web_search = request.form.get("web_search") == "true" # Convert string to boolean
218
+ file = request.files.get("file")
219
+
220
+ uploaded_gemini_file = None
221
+ if file:
222
+ uploaded_gemini_file = process_uploaded_file(file)
223
+
224
+ if "gemini_chat" not in session: # Initialize if it doesn't already exists.
225
+ session["gemini_chat"] = model.start_chat(history=[])
226
+ session.modified = True #Important to save session changes!
227
+
228
+ # Add user message to chat history
229
+ session["chat"].append({"role": "user", "text": prompt})
230
+ session.modified = True
231
+
232
+ try:
233
+ # Web search
234
+ web_results = None
235
+ if web_search:
236
  web_results = perform_web_search(prompt)
237
  if web_results:
238
  formatted_results = format_search_results(web_results)
239
+ prompt = (
240
+ f"Question: {prompt}\n\nRésultats de recherche web:\n"
241
+ f"{formatted_results}\n\nPourrais-tu analyser ces informations et "
242
+ f"me donner une réponse complète?"
243
+ )
 
244
  else:
245
+ #Handle the "no results" case
246
+ prompt = f"Question: {prompt}\n\n(Aucun résultat de recherche trouvé. Répondez en vous basant sur vos connaissances.)"
247
+
248
+ # Send message to Gemini
249
+ gemini_chat = session["gemini_chat"] # Get the chat object.
250
+ if uploaded_gemini_file:
251
+ response = gemini_chat.send_message([uploaded_gemini_file, "\n\n", prompt])
252
+ else:
253
+ response = gemini_chat.send_message(prompt)
254
+
255
+
256
+ # Add assistant response to chat history
257
+ session["chat"].append({"role": "assistant", "text": response.text})
258
+ session["gemini_chat"] = gemini_chat #Reassign back!
259
+ session.modified = True #Important to save session changes!
260
+
261
+
262
+ return jsonify({"role": "assistant", "text": response.text})
263
+
264
+ except Exception as e:
265
+ error_message = f"Error sending message: {e}"
266
+ print(error_message) # Log to console.
267
+ return jsonify({"role": "assistant", "text": error_message}), 500 #Return 500 error code
268
+
269
+
270
+
271
+ @app.route("/toggle_web_search", methods=["POST"])
272
+ def toggle_web_search():
273
+ session["web_search"] = not session["web_search"]
274
+ session.modified = True # Mark session as modified
275
+ return jsonify({"web_search": session["web_search"]})
276
+
277
+ @app.route("/clear_chat", methods=["POST"])
278
+ def clear_chat():
279
+ session.pop("chat", None)
280
+ session.pop("gemini_chat", None)
281
+ session["web_search"] = False
282
+ session.modified = True
283
+ return jsonify({"status": "success"})
284
+
285
+
286
+ if __name__ == "__main__":
287
+ app.run(debug=True)