CedM commited on
Commit
df1cce4
·
verified ·
1 Parent(s): c2d97f9

Déploiement automatique depuis GitLab CI

Browse files
Files changed (5) hide show
  1. .streamlit/config.toml +1 -2
  2. Dockerfile +1 -6
  3. MistralChat.py +45 -75
  4. requirements_docker.txt +1 -1
  5. start.sh +6 -24
.streamlit/config.toml CHANGED
@@ -8,8 +8,7 @@ font = "sans serif"
8
 
9
  [server]
10
  maxUploadSize = 10
11
- enableXsrfProtection = false
12
- enableCORS = false
13
 
14
  [browser]
15
  gatherUsageStats = false
 
8
 
9
  [server]
10
  maxUploadSize = 10
11
+ enableXsrfProtection = true
 
12
 
13
  [browser]
14
  gatherUsageStats = false
Dockerfile CHANGED
@@ -34,7 +34,6 @@ LABEL description="Chatbot NBA hybride RAG + SQL (Streamlit + LangGraph + Mistra
34
  RUN apt-get update && apt-get install -y --no-install-recommends \
35
  postgresql-17 \
36
  postgresql-client-17 \
37
- nginx \
38
  libglib2.0-0 \
39
  libsm6 \
40
  libxext6 \
@@ -78,9 +77,6 @@ COPY --chown=user:user SQL_db/schema_relationnel_sql.sql ./sql/01_schema.sql
78
  COPY --chown=user:user start.sh /home/user/start.sh
79
  RUN chmod +x /home/user/start.sh
80
 
81
- # --- Configuration nginx ---------------------------------------------------
82
- COPY nginx.conf /home/user/nginx.conf
83
-
84
  # --- Variables d'environnement par défaut ----------------------------------
85
  # PG_HOST/PG_PORT pointent vers PostgreSQL local dans le même conteneur
86
  ENV HOME=/home/user \
@@ -89,8 +85,7 @@ ENV HOME=/home/user \
89
  PG_PORT=5432 \
90
  PG_DB=oc_mlops_projet_3 \
91
  PG_ADMIN=admin \
92
- PGDATA=/home/user/pgdata \
93
- PYTHONUNBUFFERED=1
94
 
95
  # --- Port exposé (7860 requis par HF Spaces) -------------------------------
96
  EXPOSE 7860
 
34
  RUN apt-get update && apt-get install -y --no-install-recommends \
35
  postgresql-17 \
36
  postgresql-client-17 \
 
37
  libglib2.0-0 \
38
  libsm6 \
39
  libxext6 \
 
77
  COPY --chown=user:user start.sh /home/user/start.sh
78
  RUN chmod +x /home/user/start.sh
79
 
 
 
 
80
  # --- Variables d'environnement par défaut ----------------------------------
81
  # PG_HOST/PG_PORT pointent vers PostgreSQL local dans le même conteneur
82
  ENV HOME=/home/user \
 
85
  PG_PORT=5432 \
86
  PG_DB=oc_mlops_projet_3 \
87
  PG_ADMIN=admin \
88
+ PGDATA=/home/user/pgdata
 
89
 
90
  # --- Port exposé (7860 requis par HF Spaces) -------------------------------
91
  EXPOSE 7860
MistralChat.py CHANGED
@@ -2,9 +2,7 @@
2
  import streamlit as st
3
  import logfire
4
 
5
- print("=" * 60)
6
- print("[MistralChat] Démarrage — chargement des imports...")
7
- print("=" * 60)
8
 
9
  try:
10
  from utils.config import (
@@ -15,10 +13,8 @@ try:
15
  from utils.vector_store import VectorStoreManager
16
  from utils.langgraph_app import build_graph, AppState # Graphe partagé RAG + SQL
17
  from load_excel_to_db import main as load_excel_main
18
- print("[MistralChat] Imports réussis.")
19
- except Exception as e:
20
- print(f"[MistralChat] ❌ ERREUR import : {type(e).__name__}: {e}")
21
- st.error(f"Erreur d'importation ({type(e).__name__}): {e}. Vérifiez la structure de vos dossiers et les fichiers dans 'utils'.")
22
  st.stop()
23
 
24
 
@@ -87,24 +83,8 @@ def get_vector_store_manager():
87
  return None, messages
88
 
89
 
90
- logfire.info("🚀 [MistralChat] Démarrage du script Streamlit...")
91
-
92
- sql_messages = []
93
- vector_store_manager = None
94
- vs_messages = []
95
- graph = None
96
-
97
- try:
98
- sql_messages = init_sql_db()
99
- except Exception as _e:
100
- st.error(f"❌ Erreur initialisation SQL : {_e}")
101
- logfire.error("[MistralChat] Erreur init_sql_db", erreur=str(_e))
102
-
103
- try:
104
- vector_store_manager, vs_messages = get_vector_store_manager()
105
- except Exception as _e:
106
- st.error(f"❌ Erreur chargement VectorStore : {_e}")
107
- logfire.error("[MistralChat] Erreur get_vector_store_manager", erreur=str(_e))
108
 
109
 
110
  # --- Compilation du graphe LangGraph hybride (RAG + SQL) ---
@@ -117,13 +97,7 @@ def get_langgraph(_vector_store_manager):
117
  return graph
118
 
119
 
120
- try:
121
- graph = get_langgraph(vector_store_manager)
122
- except Exception as _e:
123
- st.error(f"❌ Erreur construction graphe LangGraph : {_e}")
124
- logfire.error("[MistralChat] Erreur get_langgraph", erreur=str(_e))
125
-
126
-
127
  # ==============================
128
  # CSS Global — Design professionnel & responsive
129
  # ==============================
@@ -490,46 +464,42 @@ if user_input:
490
  with st.chat_message("user"):
491
  st.markdown(prompt)
492
 
493
- if graph is None:
494
- with st.chat_message("assistant"):
495
- st.error("⚠️ Le graphe LangGraph n'a pas pu être initialisé. Vérifiez les logs de démarrage.")
496
- else:
497
- # 2. Invoquer le graphe LangGraph (routage automatique RAG ou SQL)
498
- with st.chat_message("assistant"):
499
- message_placeholder = st.empty()
500
- message_placeholder.markdown("""
501
- <div class="thinking-bar">
502
- <div class="dot-flashing"></div>
503
- &nbsp;&nbsp;Analyse en cours…
504
- </div>
505
- """, unsafe_allow_html=True)
506
- try:
507
- logfire.info(f"[Graph] Invocation pour : '{prompt}'")
508
- # Exclure le message de bienvenue (index 0) et la question en cours (dernier)
509
- chat_history = st.session_state.messages[1:-1]
510
- result = graph.invoke({
511
- "user_question": prompt,
512
- "chat_history": chat_history,
513
- })
514
- response_content = result.get("final_answer", "Je n'ai pas pu générer de réponse.")
515
- response_route = result.get("route", "unknown")
516
- # Préfixe visuel de la route
517
- route_badge = {"rag": "🔎 `[RAG]`", "sql": "🔢 `[SQL]`"}.get(response_route, "🤖 `[?]`")
518
- response_display = f"{route_badge} {response_content}"
519
- logfire.info(f"[Graph] Réponse finale obtenue (route={response_route}).")
520
- except Exception as e:
521
- response_content = "Je suis désolé, une erreur technique m'empêche de répondre. Veuillez réessayer."
522
- response_display = response_content
523
- response_route = "unknown"
524
- st.error(f"Erreur lors de l'appel au graphe : {e}")
525
- logfire.exception("Erreur lors de graph.invoke")
526
-
527
- message_placeholder.markdown(response_display)
528
-
529
- # 3. Ajouter la réponse à l'historique (avec route pour filtrage contextuel)
530
- st.session_state.messages.append({
531
- "role": "assistant",
532
- "content": response_content, # contenu brut sans badge pour le contexte LLM
533
- "route": response_route,
534
- "display": response_display, # version affichée avec badge
535
- })
 
2
  import streamlit as st
3
  import logfire
4
 
5
+
 
 
6
 
7
  try:
8
  from utils.config import (
 
13
  from utils.vector_store import VectorStoreManager
14
  from utils.langgraph_app import build_graph, AppState # Graphe partagé RAG + SQL
15
  from load_excel_to_db import main as load_excel_main
16
+ except ImportError as e:
17
+ st.error(f"Erreur d'importation: {e}. Vérifiez la structure de vos dossiers et les fichiers dans 'utils'.")
 
 
18
  st.stop()
19
 
20
 
 
83
  return None, messages
84
 
85
 
86
+ sql_messages = init_sql_db()
87
+ vector_store_manager, vs_messages = get_vector_store_manager()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
 
90
  # --- Compilation du graphe LangGraph hybride (RAG + SQL) ---
 
97
  return graph
98
 
99
 
100
+ graph = get_langgraph(vector_store_manager)
 
 
 
 
 
 
101
  # ==============================
102
  # CSS Global — Design professionnel & responsive
103
  # ==============================
 
464
  with st.chat_message("user"):
465
  st.markdown(prompt)
466
 
467
+ # 2. Invoquer le graphe LangGraph (routage automatique RAG ou SQL)
468
+ with st.chat_message("assistant"):
469
+ message_placeholder = st.empty()
470
+ message_placeholder.markdown("""
471
+ <div class="thinking-bar">
472
+ <div class="dot-flashing"></div>
473
+ &nbsp;&nbsp;Analyse en cours…
474
+ </div>
475
+ """, unsafe_allow_html=True)
476
+ try:
477
+ logfire.info(f"[Graph] Invocation pour : '{prompt}'")
478
+ # Exclure le message de bienvenue (index 0) et la question en cours (dernier)
479
+ chat_history = st.session_state.messages[1:-1]
480
+ result = graph.invoke({
481
+ "user_question": prompt,
482
+ "chat_history": chat_history,
483
+ })
484
+ response_content = result.get("final_answer", "Je n'ai pas pu générer de réponse.")
485
+ response_route = result.get("route", "unknown")
486
+ # Préfixe visuel de la route
487
+ route_badge = {"rag": "🔎 `[RAG]`", "sql": "🔢 `[SQL]`"}.get(response_route, "🤖 `[?]`")
488
+ response_display = f"{route_badge} {response_content}"
489
+ logfire.info(f"[Graph] Réponse finale obtenue (route={response_route}).")
490
+ except Exception as e:
491
+ response_content = "Je suis désolé, une erreur technique m'empêche de répondre. Veuillez réessayer."
492
+ response_display = response_content
493
+ response_route = "unknown"
494
+ st.error(f"Erreur lors de l'appel au graphe : {e}")
495
+ logfire.exception("Erreur lors de graph.invoke")
496
+
497
+ message_placeholder.markdown(response_display)
498
+
499
+ # 3. Ajouter la réponse à l'historique (avec route pour filtrage contextuel)
500
+ st.session_state.messages.append({
501
+ "role": "assistant",
502
+ "content": response_content, # contenu brut sans badge pour le contexte LLM
503
+ "route": response_route,
504
+ "display": response_display, # version affichée avec badge
505
+ })
 
 
 
 
requirements_docker.txt CHANGED
@@ -1,5 +1,5 @@
1
  mistralai==1.12.4
2
- streamlit>=1.44.1,<1.45
3
  langchain>=1.2.10
4
  langchain-community>=0.4.1
5
  langchain-core>=1.2.17
 
1
  mistralai==1.12.4
2
+ streamlit>=1.44.1
3
  langchain>=1.2.10
4
  langchain-community>=0.4.1
5
  langchain-core>=1.2.17
start.sh CHANGED
@@ -87,30 +87,12 @@ echo "🚀 [PG] Démarrage de PostgreSQL (port $PG_PORT) ..."
87
  pg_ctl -D "$PGDATA" -l "$PG_LOG" start -w -t 60 || { echo "❌ [PG] Échec du démarrage. Log :"; cat "$PG_LOG"; exit 1; }
88
  echo "✅ [PG] PostgreSQL démarré."
89
  # ---------------------------------------------------------------------------
90
- # Étape 3 — Démarrage de Streamlit en tâche de fond (port 7861, interne)
91
  # ---------------------------------------------------------------------------
92
- echo "🚀 [Streamlit] Démarrage sur le port 7861 (interne) ..."
93
  cd "$APP_DIR"
94
- streamlit run MistralChat.py \
95
- --server.port=7861 \
96
- --server.address=127.0.0.1 \
97
  --server.headless=true \
98
- --server.enableXsrfProtection=false \
99
- --server.enableCORS=false \
100
- --browser.gatherUsageStats=false &
101
-
102
- # Attendre que Streamlit soit prêt avant de démarrer nginx
103
- echo "⏳ [Streamlit] Attente du démarrage (port 7861) ..."
104
- for i in $(seq 1 30); do
105
- if curl -sf http://127.0.0.1:7861/_stcore/health > /dev/null 2>&1; then
106
- echo "✅ [Streamlit] Prêt."
107
- break
108
- fi
109
- sleep 2
110
- done
111
-
112
- # ---------------------------------------------------------------------------
113
- # Étape 4 — Démarrage de nginx en premier plan (port 7860, public HF Spaces)
114
- # ---------------------------------------------------------------------------
115
- echo "🚀 [nginx] Démarrage sur le port 7860 (public) ..."
116
- exec nginx -c /home/user/nginx.conf
 
87
  pg_ctl -D "$PGDATA" -l "$PG_LOG" start -w -t 60 || { echo "❌ [PG] Échec du démarrage. Log :"; cat "$PG_LOG"; exit 1; }
88
  echo "✅ [PG] PostgreSQL démarré."
89
  # ---------------------------------------------------------------------------
90
+ # Étape 3 — Démarrage de Streamlit en premier plan (port 7860, HF Spaces)
91
  # ---------------------------------------------------------------------------
92
+ echo "🚀 [Streamlit] Démarrage sur le port 7860 ..."
93
  cd "$APP_DIR"
94
+ exec streamlit run MistralChat.py \
95
+ --server.port=7860 \
96
+ --server.address=0.0.0.0 \
97
  --server.headless=true \
98
+ --browser.gatherUsageStats=false