app.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import streamlit as st
  2. import os
  3. from dotenv import load_dotenv
  4. import uuid
  5. # --- CONFIGURATION INITIALE ---
  6. st.set_page_config(page_title="Actuariat GPT", page_icon="📊")
  7. load_dotenv()
  8. # Infos utilisateur
  9. user_infos = {
  10. "username": "user123",
  11. "mdps": "pass123"
  12. }
  13. def login_page():
  14. # --- INJECTION CSS (GRENAT & GRIS) ---
  15. st.markdown("""
  16. <style>
  17. .stApp {
  18. background-color: #F2F2F2;
  19. }
  20. .login-box {
  21. background-color: white;
  22. padding: 40px;
  23. border-radius: 15px;
  24. box-shadow: 0 4px 20px rgba(0,0,0,0.08);
  25. border-top: 5px solid #6B0D0D;
  26. margin-bottom: 20px;
  27. }
  28. .main-title {
  29. color: #6B0D0D;
  30. font-family: 'Helvetica Neue', sans-serif;
  31. font-weight: 700;
  32. text-align: center;
  33. margin-bottom: 30px;
  34. }
  35. .stat-card {
  36. background: white;
  37. padding: 20px;
  38. border-radius: 12px;
  39. box-shadow: 0 2px 8px rgba(0,0,0,0.05);
  40. text-align: center;
  41. border-bottom: 4px solid #4A4A4A;
  42. }
  43. .stat-val {
  44. font-size: 26px;
  45. font-weight: bold;
  46. color: #6B0D0D;
  47. }
  48. .stat-label {
  49. font-size: 14px;
  50. color: #4A4A4A;
  51. font-weight: 500;
  52. }
  53. /* Style des boutons de navigation du Header */
  54. /* Style des boutons de navigation du Header */
  55. .nav-button {
  56. background-color: #6B0D0D; /* Fond Grenat par défaut */
  57. color: white !important; /* Texte blanc */
  58. border: none;
  59. padding: 8px 18px;
  60. border-radius: 20px;
  61. text-decoration: none !important; /* SUPPRIME LE SOULIGNÉ */
  62. font-size: 14px;
  63. font-weight: 500;
  64. transition: 0.3s;
  65. margin-left: 10px;
  66. display: inline-block;
  67. box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  68. }
  69. .nav-button:hover {
  70. background-color: #4A0808; /* Grenat plus foncé au survol */
  71. color: white !important;
  72. text-decoration: none !important;
  73. transform: translateY(-1px); /* Petit effet de levier */
  74. }
  75. /* Bouton Connexion */
  76. div.stButton > button:first-child {
  77. background-color: #6B0D0D !important;
  78. color: white !important;
  79. border: none;
  80. padding: 10px 20px;
  81. border-radius: 8px;
  82. transition: 0.3s;
  83. }
  84. div.stButton > button:first-child:hover {
  85. background-color: #4A0808 !important;
  86. }
  87. </style>
  88. """, unsafe_allow_html=True)
  89. # --- HEADER / LOGO & NAV ---
  90. header_col1, header_col2 = st.columns([2, 8])
  91. with header_col1:
  92. try:
  93. st.image("logo Dataltist.png", width=130)
  94. except:
  95. st.markdown("<h3 style='color:#6B0D0D; margin:0;'>DATALTIST</h3>", unsafe_allow_html=True)
  96. st.markdown("<br>", unsafe_allow_html=True)
  97. # --- SECTION CENTRALE : LOGIN ---
  98. left_co, cent_co, last_co = st.columns([1, 5, 1])
  99. with cent_co:
  100. st.markdown('<h2 class="main-title"> Login </h2>', unsafe_allow_html=True)
  101. st.markdown("<br>", unsafe_allow_html=True)
  102. st.markdown("<br>", unsafe_allow_html=True)
  103. username = st.text_input("👤 Nom d'utilisateur", placeholder="votre email")
  104. password = st.text_input("🔑 Mot de passe", type="password", placeholder="••••••••")
  105. st.markdown("<br>", unsafe_allow_html=True)
  106. if st.button("Se Connecter", use_container_width=True):
  107. if username == user_infos["username"] and password == user_infos["mdps"]:
  108. st.session_state["is_logged_in"] = True
  109. st.rerun()
  110. else :
  111. st.error("Identifiants incorrects")
  112. st.markdown('</div>', unsafe_allow_html=True)
  113. st.markdown("<br><br>", unsafe_allow_html=True)
  114. # --- INITIALISATION SESSION ---
  115. if "is_logged_in" not in st.session_state:
  116. st.session_state["is_logged_in"] = False
  117. if not st.session_state["is_logged_in"]:
  118. login_page()
  119. else:
  120. # --- INTERFACE CHATBOT ---
  121. st.markdown("""<style>.stApp { background-color: #F2F2F2; }</style>""", unsafe_allow_html=True)
  122. h_col1, h_col2 = st.columns([3, 1])
  123. with h_col1:
  124. try: st.image("logo Dataltist.png", width=100)
  125. except: st.markdown("<h3 style='color:#6B0D0D; margin:0;'>DATALTIST GPT</h3>", unsafe_allow_html=True)
  126. with h_col2:
  127. if st.button("🚪 Déconnexion"):
  128. st.session_state["is_logged_in"] = False
  129. st.rerun()
  130. st.markdown("<h2 style='color:#4A4A4A; text-align:center;'> Assistant Expert en Actuariat</h2>", unsafe_allow_html=True)
  131. # Logique Agent
  132. @st.cache_resource
  133. def get_agent():
  134. from tools import create_agent
  135. return create_agent()
  136. agent_executor = get_agent()
  137. if "messages" not in st.session_state:
  138. st.session_state.messages = []
  139. for message in st.session_state.messages:
  140. with st.chat_message(message["role"]):
  141. st.markdown(message["content"])
  142. if prompt := st.chat_input("Posez votre question actuarielle..."):
  143. st.session_state.messages.append({"role": "user", "content": prompt})
  144. with st.chat_message("user"):
  145. st.markdown(prompt)
  146. with st.chat_message("assistant"):
  147. with st.spinner("Analyse des mémoires..."):
  148. config = {"configurable": {"thread_id": st.session_state.get("thread_id", str(uuid.uuid4()))}}
  149. result = agent_executor.invoke({"messages": [("user", prompt)]}, config)
  150. response = result["messages"][-1].content
  151. st.markdown(response)
  152. st.session_state.messages.append({"role": "assistant", "content": response})