datacipen commited on
Commit
539249f
·
verified ·
1 Parent(s): 7be48a1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +165 -201
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import os
2
  import dash
3
  import json
@@ -25,11 +26,13 @@ from langgraph.checkpoint.memory import MemorySaver
25
  from langchain_openai import ChatOpenAI
26
  from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
27
 
 
28
  import dash
29
  from dash.dependencies import Input, Output, State
30
  from dash import Dash, html, dcc, callback, callback_context, ctx, Output, Input, dash_table, State, no_update, _dash_renderer, clientside_callback
31
  from dash import html
32
 
 
33
  import dash_bootstrap_components as dbc
34
  from dash.exceptions import PreventUpdate
35
  import dash_mantine_components as dmc
@@ -37,6 +40,7 @@ from dash_iconify import DashIconify
37
  _dash_renderer._set_react_version("18.2.0")
38
  import flask
39
  from flask_login import LoginManager, UserMixin, login_user, current_user, login_required, logout_user
 
40
  from datetime import timedelta
41
 
42
  from IPython.display import display, HTML
@@ -621,48 +625,37 @@ def init_agent_state(current_url, num, pathname) -> AgentState:
621
  if task == "load_and_preprocess":
622
  if key == "current_file":
623
  result += f"Traitement du fichier {taskInfo['current_file']} en cours...\n"
624
-
625
  if task == "classify_teachings":
626
  if key == "status":
627
  for key, value in taskInfo['classified_teachings'].items():
628
  result += f"\n\n-**Enseignement classé dans la catégorie '{key}'** : "
629
  for enseignement in value:
630
  result += f"{enseignement}, "
631
-
632
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
633
-
634
  if task == "create_categories":
635
  if key == "status":
636
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
637
-
638
  if task == "create_learning_situations":
639
  if key == "status":
640
  if taskInfo['learning_situations'].items():
641
  for key, value in taskInfo['learning_situations'].items():
642
  result += f"\n\n-**Situation d'apprentissage créée pour la catégorie '{key}'** : {value}\n"
643
-
644
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
645
-
646
  else:
647
  result += f"\n\nTraitement de la tâche : pas de situations d'apprentissage créées\n"
648
-
649
  if task == "create_academic_competencies":
650
  if key == "dataframe":
651
  df = taskInfo['dataframe']
652
  if key == "status":
653
  if taskInfo['academic_competencies'].items():
654
  for key, value in taskInfo['academic_competencies'].items():
655
- result += f"\n\n-**Compétence académique créée pour la catégorie '{key}'** : {value}\n"
656
-
657
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
658
-
659
  else:
660
  result += f"\n\nTraitement de la tâche : pas de BCC créés\n"
661
-
662
  if task == "export_to_excel_2":
663
  if key == "status":
664
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
665
-
666
 
667
  except Exception as e:
668
  print(f"Erreur lors de l'exécution du workflow: {e}")
@@ -690,6 +683,40 @@ def getGitFilesFromRepo(DIRECTORY):
690
  })
691
  return all_files
692
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
693
  # Fonction pour extraire les catégories et enseignements
694
  def extract_categories_enseignements(data: Dict) -> pd.DataFrame:
695
  """Extraire les catégories et enseignements associés dans un DataFrame."""
@@ -745,11 +772,12 @@ def extract_situations_apprentissage(data: Dict) -> pd.DataFrame:
745
  # the exception.
746
  server = flask.Flask(__name__)
747
 
748
- app = dash.Dash(__name__, server=server, external_stylesheets=dmc.styles.ALL,
749
  title='BCC Agent',
750
  update_title='Chargement...',
751
  suppress_callback_exceptions=True)
752
 
 
753
  # Updating the Flask Server configuration with Secret Key to encrypt the user session cookie
754
  server.config['REMEMBER_COOKIE_DURATION'] = timedelta(seconds=3600)
755
 
@@ -775,39 +803,26 @@ def load_user(username):
775
  return User(username)
776
 
777
  # User status management views
778
- index_page = html.Div([
779
- dbc.Col([dcc.Location(id='url_login', refresh=True),
780
- html.H2('''Please log in to continue:''', id='h1'),
781
- dcc.Input(placeholder='Enter your username',
782
- type='text', id='uname-box'),
783
- dcc.Input(placeholder='Enter your password',
784
- type='password', id='pwd-box'),
785
- html.Button(children='Login', n_clicks=0,
786
- type='submit', id='login-button'),
787
- html.Div(children='', id='output-state'),]
788
- , sm=4,style={'textAlign': 'center', 'marginTop': 'calc(50vh - 120px)','border':'1px solid #495057','border-radius':'10px'}),
789
- ])
790
-
791
- #index_page = dmc.MantineProvider(
792
- # [
793
- # dmc.Container(
794
- # children=[
795
- # dmc.Grid(
796
- # children=[
797
- # dmc.GridCol(
798
- # html.Div([dcc.Location(id='url_login', refresh=True),
799
- # dmc.Text("BCC Agent", id='h1',style={"fontSize": 48}, fw=900),
800
- # dmc.TextInput(placeholder="login",w=250, ml="calc(50% - 125px)", id='uname-box'),
801
- # dmc.PasswordInput(id='pwd-box',placeholder="Mot de passe",w=250, ml="calc(50% - 125px)", mt=10),
802
- # dmc.Button("Continuer", w=250,variant="gradient", n_clicks=0, id='login-button', mt=20, mb=20),
803
- # html.Div(children='', id='output-state')
804
- # ]), span=4, offset=4, style={'textAlign': 'center', 'marginTop': 'calc(50vh - 120px)','border':'1px solid #495057','border-radius':'10px'}, c='white'
805
- # )
806
- # ]
807
- # )
808
- # ]
809
- #)]
810
- # )
811
 
812
  # Successful login
813
  success = html.Div([html.Div([html.H2('Login successful.'),
@@ -868,19 +883,19 @@ app.layout = dmc.MantineProvider(
868
  html.Div(id='user-status-div'),
869
  html.Div(id='page-content')
870
  ])])
871
- #def layout(**kwargs):
872
- # return dmc.MantineProvider(
873
- # [
874
- # html.Div([
875
- # dcc.Location(id='url', refresh=False),
876
- # dcc.Location(id='redirect', refresh=True),
877
- # dcc.Store(id='login-status', storage_type='session'),
878
- # dcc.Store(id="history-store", storage_type="session", data=[]),
879
- # dcc.Store(id="model-params-store", storage_type="session", data={"model": "mistralai/Mistral-Small-3.1-24B-Instruct-2503","temperature": 0.7,"max_tokens": 1024,"top_p": 0.9}),
880
- # html.Div(id='user-status-div'),
881
- # html.Div(id='page-content')
882
- # ]),
883
- # ],forceColorScheme="dark", span=12, offset=0, c='white')
884
 
885
  app_page = dmc.MantineProvider(
886
  [
@@ -1095,7 +1110,7 @@ app_page = dmc.MantineProvider(
1095
  className="g-0"
1096
  ),
1097
  html.H4(id="text-enseignement-dropdown", className="mb-3 text-success", style={"font-size": "0.7rem"}),
1098
- dcc.Loading(dbc.Textarea(id="enseignement-dropdown", className="mb-3", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"})),
1099
  ], md=6),
1100
  dbc.Col([
1101
  dbc.Row(
@@ -1109,7 +1124,7 @@ app_page = dmc.MantineProvider(
1109
  className="g-0"
1110
  ),
1111
  html.H4("Choisir d'abord une maquette de formation avec propositions BCC", className="mb-3", style={"font-size": "0.7rem"}),
1112
- dcc.Loading(dbc.Textarea(id="classification-dropdown", className="mb-3", placeholder="Choisir d'abord une maquette avec propositions BCC", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"})),
1113
  ], md=6)
1114
  ]),
1115
  dbc.Row([
@@ -1125,7 +1140,7 @@ app_page = dmc.MantineProvider(
1125
  className="g-0"
1126
  ),
1127
  html.H4("Choisir d'abord une maquette de formation avec propositions BCC", className="mb-3", style={"font-size": "0.7rem"}),
1128
- dcc.Loading(dbc.Textarea(id="situation-dropdown", className="mb-3", placeholder="Choisir d'abord une maquette avec propositions BCC", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"})),
1129
  ], md=6),
1130
  dbc.Col([
1131
  dbc.Row(
@@ -1183,7 +1198,7 @@ app_page = dmc.MantineProvider(
1183
  className="g-0"
1184
  ),
1185
  html.Div(id="generation-status", className="mb-3"),
1186
- dcc.Loading(
1187
  html.Div(id="competence-output", className="p-3 border rounded", style={"color":"rgb(90, 242, 156)","border-color":"rgb(90, 242, 156)!important","background-color":"rgba(90, 242, 156, 0.2)"}),
1188
  ),
1189
  ], md=12),
@@ -1253,7 +1268,7 @@ app_page = dmc.MantineProvider(
1253
  align="left",
1254
  className="g-0"
1255
  ),
1256
- dcc.Loading(html.Div(id='output-response', style={"color":"rgb(90, 242, 156)","border-radius":"3px","border":"1px solid rgb(255,255,255)!important","background-color":"rgba(90, 242, 156, 0.2)","padding":"5px"})),
1257
  html.Div(id="notification_wrapper", style={"margin-top":"1rem"}),
1258
  ], width=12)
1259
  ])
@@ -1483,7 +1498,7 @@ app_avid_page = dmc.MantineProvider(
1483
  className="g-0"
1484
  ),
1485
  html.H4(id="text-enseignement-dropdown", className="mb-3 text-success", style={"font-size": "0.7rem"}),
1486
- dcc.Loading(dbc.Textarea(id="enseignement-dropdown", className="mb-3", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"})),
1487
  ], md=6),
1488
  dbc.Col([
1489
  dbc.Row(
@@ -1497,7 +1512,7 @@ app_avid_page = dmc.MantineProvider(
1497
  className="g-0"
1498
  ),
1499
  html.H4("Choisir d'abord une maquette de formation avec propositions BCC AVID", className="mb-3", style={"font-size": "0.7rem"}),
1500
- dcc.Loading(dbc.Textarea(id="classification-dropdown", className="mb-3", placeholder="Choisir d'abord une maquette avec propositions BCC AVID", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"})),
1501
  ], md=6)
1502
  ]),
1503
  dbc.Row([
@@ -1513,7 +1528,7 @@ app_avid_page = dmc.MantineProvider(
1513
  className="g-0"
1514
  ),
1515
  html.H4("Choisir d'abord une maquette de formation avec propositions BCC AVID", className="mb-3", style={"font-size": "0.7rem"}),
1516
- dcc.Loading(dbc.Textarea(id="situation-dropdown", className="mb-3", placeholder="Choisir d'abord une maquette avec propositions BCC AVID", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"})),
1517
  ], md=6),
1518
  dbc.Col([
1519
  dbc.Row(
@@ -1565,7 +1580,7 @@ app_avid_page = dmc.MantineProvider(
1565
  className="g-0"
1566
  ),
1567
  html.Div(id="generation-status", className="mb-3"),
1568
- dcc.Loading(
1569
  html.Div(id="competence-output", className="p-3 border rounded", style={"color":"rgb(90, 242, 156)","border-color":"rgb(90, 242, 156)!important","background-color":"rgba(90, 242, 156, 0.2)"}),
1570
  ),
1571
  ], md=12),
@@ -1635,7 +1650,7 @@ app_avid_page = dmc.MantineProvider(
1635
  align="left",
1636
  className="g-0"
1637
  ),
1638
- dcc.Loading(html.Div(id='output-response-avid', style={"color":"rgb(156, 242, 242)","border-radius":"3px","border":"1px solid rgb(255,255,255)!important","background-color":"rgba(156, 242, 242, 0.2)","padding":"5px"})),
1639
  html.Div(id="notification_wrapper-avid", style={"margin-top":"1rem"}),
1640
  ], width=12)
1641
  ])
@@ -1764,31 +1779,28 @@ def update_skills_dropdown(categorie_selected, pathname):
1764
  )
1765
  def update_enseignements_dropdown(categorie_selected, pathname):
1766
  """Mettre à jour les options du dropdown d'enseignements en fonction de la catégorie sélectionnée."""
1767
- try:
1768
- if not categorie_selected:
1769
- default_text = "par défaut : "
1770
- if pathname == "/bcc":
1771
- categorie_selected = 'JSON/L1-Anglais.json'
1772
- elif pathname == "/bcc-avid":
1773
- categorie_selected = 'VD/JSON/L1-Lettres-Modernes.json'
1774
- else:
1775
- default_text = "formation sélectionnée : "
1776
 
1777
- url = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{categorie_selected}"
1778
- res = requests.get(url, headers=headers, params=params)
1779
- if res.status_code == 200:
1780
- jsonData = json.loads(base64.b64decode(res.json()['content']))
1781
- modal_text = "**Description des catégories d'enseignements : **\n\n"
1782
- for item in jsonData.get("categories", []):
1783
- modal_text += f"- **{item['nom']}**:\n\n{item['description']}\n\n"
1784
- if pathname == "/bcc":
1785
- return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(jsonData.get("categories", []), indent = 6, separators =(",", ":"),
1786
  sort_keys = True, ensure_ascii=False), "Choisir d'abord une maquette de formation avec propositions BCC : " + default_text + jsonData.get("niveau", ""), modal_text
1787
- elif pathname == "/bcc-avid":
1788
- return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(jsonData.get("categories", []), indent = 6, separators =(",", ":"),
1789
- sort_keys = True, ensure_ascii=False), "Choisir d'abord une maquette de formation avec propositions BCC : " + default_text + jsonData.get("niveau_etude", ""), modal_text
1790
- except:
1791
- print("Aucun fichier chargé")
1792
 
1793
  @app.callback(
1794
  Output("classification-dropdown", "placeholder"),
@@ -1799,44 +1811,41 @@ def update_enseignements_dropdown(categorie_selected, pathname):
1799
  )
1800
  def update_classification_dropdown(categorie_selected, pathname):
1801
  """Mettre à jour les options du dropdown d'enseignements en fonction de la catégorie sélectionnée."""
1802
- try:
1803
- if not categorie_selected:
1804
- default_text = "par défaut : "
1805
- if pathname == "/bcc":
1806
- categorie_selected = 'JSON/L1-Anglais.json'
1807
- elif pathname == "/bcc-avid":
1808
- categorie_selected = 'VD/JSON/L1-Lettres-Modernes.json'
1809
- else:
1810
- default_text = ""
1811
 
1812
- url = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{categorie_selected}"
1813
- res = requests.get(url, headers=headers, params=params)
1814
- if res.status_code == 200:
1815
- jsonData = json.loads(base64.b64decode(res.json()['content']))
1816
- modal_text = "**Classification des enseignements :**"
1817
- if pathname == "/bcc":
1818
- textarea_value = jsonData.get("classified_teachings", [])
1819
- for key, value in textarea_value.items():
1820
- modal_text += f"\n\n- **{key}**: "
1821
- for i in range(0,len(value)):
1822
- modal_text += f"{value[i]}\t"
1823
- elif pathname == "/bcc-avid":
1824
- textarea_value = jsonData.get("dataframe", [])
1825
- test = " "
1826
- for item in sorted(textarea_value, key=lambda x: x['categorie'] if x['categorie'] else ""):
1827
- if test != item['categorie']:
1828
- modal_text += f"\n\n- **{item['categorie']}**: "
1829
- modal_text += f"{item['enseignements']}\t"
1830
- test = item['categorie']
1831
 
1832
- if pathname == "/bcc":
1833
- return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(textarea_value, indent = 6, separators =(",", ":"),
1834
  sort_keys = True, ensure_ascii=False),modal_text
1835
- elif pathname == "/bcc-avid":
1836
- return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(textarea_value, indent = 6, separators =(",", ":"),
1837
  sort_keys = True, ensure_ascii=False),modal_text
1838
- except:
1839
- print("Aucun fichier chargé")
1840
 
1841
  @app.callback(
1842
  Output("situation-dropdown", "placeholder"),
@@ -1847,46 +1856,43 @@ def update_classification_dropdown(categorie_selected, pathname):
1847
  )
1848
  def update_situations_dropdown(categorie_selected, pathname):
1849
  """Mettre à jour les options du dropdown d'enseignements en fonction de la catégorie sélectionnée."""
 
 
 
 
 
 
 
 
 
 
 
1850
  try:
1851
- if not categorie_selected:
1852
- default_text = "par défaut : "
 
1853
  if pathname == "/bcc":
1854
- categorie_selected = 'JSON/L1-Anglais.json'
 
 
1855
  elif pathname == "/bcc-avid":
1856
- categorie_selected = 'VD/JSON/L1-Lettres-Modernes.json'
1857
- else:
1858
- default_text = ""
1859
-
1860
- url = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{categorie_selected}"
1861
- res = requests.get(url, headers=headers, params=params)
1862
- try:
1863
- if res.status_code == 200:
1864
- jsonData = json.loads(base64.b64decode(res.json()['content']))
1865
- modal_text = "**Description des situations d'apprentissage :**"
1866
- if pathname == "/bcc":
1867
- textarea_value = jsonData.get("learning_situations", [])
1868
- for key, value in textarea_value.items():
1869
- modal_text += f"\n\n- **{key}**: {value}"
1870
- elif pathname == "/bcc-avid":
1871
- textarea_value = jsonData.get("situations_apprentissage", [])
1872
- for item in textarea_value:
1873
- modal_text += f"\n\n- **Situation d'apprentissage**: {item['situation']}"
1874
- if item['objectifs']:
1875
- modal_text += f"\n\nObjectifs : "
1876
- for objectif in item['objectifs']:
1877
- modal_text += f"\n-{objectif}"
1878
- modal_text += f"\n\nLien avec les thématiques ODD11 : {item['lien_odd11']}"
1879
 
1880
- if pathname == "/bcc":
1881
- return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(textarea_value, indent = 6, separators =(",", ":"),
1882
  sort_keys = True, ensure_ascii=False), modal_text
1883
- elif pathname == "/bcc-avid":
1884
- return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(textarea_value, indent = 6, separators =(",", ":"),
1885
  sort_keys = True, ensure_ascii=False), modal_text
1886
- except:
1887
- return "Choisir d'abord une maquette de formation avec proposition BCC", "", "**Aucune situation d'apprentissage définie pour cette maquette de formation.**"
1888
  except:
1889
- print("aucun fichier chargé")
1890
 
1891
  @app.callback(
1892
  Output("selection-display", "children"),
@@ -2248,47 +2254,5 @@ def display_status(num, current, n_clicks, pathname):
2248
  except:
2249
  return html.Div(dcc.Markdown(f"""{agent}""", style={"color":"white","font-size":"0.75rem"})), []
2250
 
2251
- clientside_callback(
2252
- """connected => !connected""",
2253
- Output("submit-button", "disabled"),
2254
- )
2255
-
2256
- clientside_callback(
2257
- """(notification) => {
2258
- if (!notification) return dash_clientside.no_update
2259
- return notification
2260
- }""",
2261
- Output("notification_wrapper", "children", allow_duplicate=True),
2262
- prevent_initial_call=True,
2263
- )
2264
-
2265
- clientside_callback(
2266
- """(word, text) => text + word""",
2267
- Output("output-response", "children", allow_duplicate=True),
2268
- State("output-response", "children"),
2269
- prevent_initial_call=True,
2270
- )
2271
-
2272
- clientside_callback(
2273
- """connected => !connected""",
2274
- Output("submit-button-avid", "disabled"),
2275
- )
2276
-
2277
- clientside_callback(
2278
- """(notification) => {
2279
- if (!notification) return dash_clientside.no_update
2280
- return notification
2281
- }""",
2282
- Output("notification_wrapper-avid", "children", allow_duplicate=True),
2283
- prevent_initial_call=True,
2284
- )
2285
-
2286
- clientside_callback(
2287
- """(word, text) => text + word""",
2288
- Output("output-response-avid", "children", allow_duplicate=True),
2289
- State("output-response-avid", "children"),
2290
- prevent_initial_call=True,
2291
- )
2292
-
2293
  if __name__ == '__main__':
2294
  app.run_server(debug=True)
 
1
+
2
  import os
3
  import dash
4
  import json
 
26
  from langchain_openai import ChatOpenAI
27
  from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
28
 
29
+ from dash_socketio import DashSocketIO
30
  import dash
31
  from dash.dependencies import Input, Output, State
32
  from dash import Dash, html, dcc, callback, callback_context, ctx, Output, Input, dash_table, State, no_update, _dash_renderer, clientside_callback
33
  from dash import html
34
 
35
+ import dash_bootstrap_components as dbc
36
  import dash_bootstrap_components as dbc
37
  from dash.exceptions import PreventUpdate
38
  import dash_mantine_components as dmc
 
40
  _dash_renderer._set_react_version("18.2.0")
41
  import flask
42
  from flask_login import LoginManager, UserMixin, login_user, current_user, login_required, logout_user
43
+ from flask_socketio import SocketIO, emit
44
  from datetime import timedelta
45
 
46
  from IPython.display import display, HTML
 
625
  if task == "load_and_preprocess":
626
  if key == "current_file":
627
  result += f"Traitement du fichier {taskInfo['current_file']} en cours...\n"
 
628
  if task == "classify_teachings":
629
  if key == "status":
630
  for key, value in taskInfo['classified_teachings'].items():
631
  result += f"\n\n-**Enseignement classé dans la catégorie '{key}'** : "
632
  for enseignement in value:
633
  result += f"{enseignement}, "
 
634
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
 
635
  if task == "create_categories":
636
  if key == "status":
637
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
 
638
  if task == "create_learning_situations":
639
  if key == "status":
640
  if taskInfo['learning_situations'].items():
641
  for key, value in taskInfo['learning_situations'].items():
642
  result += f"\n\n-**Situation d'apprentissage créée pour la catégorie '{key}'** : {value}\n"
 
643
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
 
644
  else:
645
  result += f"\n\nTraitement de la tâche : pas de situations d'apprentissage créées\n"
 
646
  if task == "create_academic_competencies":
647
  if key == "dataframe":
648
  df = taskInfo['dataframe']
649
  if key == "status":
650
  if taskInfo['academic_competencies'].items():
651
  for key, value in taskInfo['academic_competencies'].items():
652
+ result += f"\n\n-**Compétence académique créée pour la catégorie '{key}'** : {value}\n"
 
653
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
 
654
  else:
655
  result += f"\n\nTraitement de la tâche : pas de BCC créés\n"
 
656
  if task == "export_to_excel_2":
657
  if key == "status":
658
  result += f"\n\nTraitement de la tâche : {taskInfo['status']}...\n"
 
659
 
660
  except Exception as e:
661
  print(f"Erreur lors de l'exécution du workflow: {e}")
 
683
  })
684
  return all_files
685
 
686
+ def load_json_files(directory_path: str = "./BCC-Application/JSON"):
687
+ if not os.path.exists(directory_path):
688
+ print(f"Erreur: Le répertoire {directory_path} n'existe pas.")
689
+ return
690
+
691
+ # Récupérer la liste des fichiers CSV dans le répertoire
692
+ json_files = glob.glob(os.path.join(directory_path, "*.json"))
693
+
694
+ if not json_files:
695
+ print(f"Aucun fichier JSON trouvé dans le répertoire {directory_path}.")
696
+ return
697
+
698
+ print(f"Fichiers JSON trouvés: {len(json_files)}")
699
+ #for file in json_files:
700
+ # print(f"- {file}")
701
+ return json_files
702
+
703
+ def load_json_AVID_files(directory_path: str = "./VD-Agent/JSON"):
704
+ if not os.path.exists(directory_path):
705
+ print(f"Erreur: Le répertoire {directory_path} n'existe pas.")
706
+ return
707
+
708
+ # Récupérer la liste des fichiers CSV dans le répertoire
709
+ json_files = glob.glob(os.path.join(directory_path, "*.json"))
710
+
711
+ if not json_files:
712
+ print(f"Aucun fichier JSON trouvé dans le répertoire {directory_path}.")
713
+ return
714
+
715
+ print(f"Fichiers JSON trouvés: {len(json_files)}")
716
+ #for file in json_files:
717
+ # print(f"- {file}")
718
+ return json_files
719
+
720
  # Fonction pour extraire les catégories et enseignements
721
  def extract_categories_enseignements(data: Dict) -> pd.DataFrame:
722
  """Extraire les catégories et enseignements associés dans un DataFrame."""
 
772
  # the exception.
773
  server = flask.Flask(__name__)
774
 
775
+ app = dash.Dash(__name__, server=server, external_stylesheets=[dmc.styles.ALL, dbc.themes.DARKLY],
776
  title='BCC Agent',
777
  update_title='Chargement...',
778
  suppress_callback_exceptions=True)
779
 
780
+ #socketio = SocketIO(app.server)
781
  # Updating the Flask Server configuration with Secret Key to encrypt the user session cookie
782
  server.config['REMEMBER_COOKIE_DURATION'] = timedelta(seconds=3600)
783
 
 
803
  return User(username)
804
 
805
  # User status management views
806
+ index_page = dmc.MantineProvider(
807
+ [
808
+ dmc.Container(
809
+ children=[
810
+ dmc.Grid(
811
+ children=[
812
+ dmc.GridCol(
813
+ html.Div([dcc.Location(id='url_login', refresh=True),
814
+ dmc.Text("BCC Agent", id='h1',style={"fontSize": 48}, fw=900),
815
+ dmc.TextInput(placeholder="login",w=250, ml="calc(50% - 125px)", id='uname-box'),
816
+ dmc.PasswordInput(id='pwd-box',placeholder="Mot de passe",w=250, ml="calc(50% - 125px)", mt=10),
817
+ dmc.Button("Continuer", w=250,variant="gradient", n_clicks=0, id='login-button', mt=20, mb=20),
818
+ html.Div(children='', id='output-state')
819
+ ]), span=4, offset=4, style={'textAlign': 'center', 'marginTop': 'calc(50vh - 120px)','border':'1px solid #495057','border-radius':'10px'}, c='white'
820
+ )
821
+ ]
822
+ )
823
+ ]
824
+ )],forceColorScheme="dark"
825
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
826
 
827
  # Successful login
828
  success = html.Div([html.Div([html.H2('Login successful.'),
 
883
  html.Div(id='user-status-div'),
884
  html.Div(id='page-content')
885
  ])])
886
+ def layout(**kwargs):
887
+ return dmc.MantineProvider(
888
+ [
889
+ html.Div([
890
+ dcc.Location(id='url', refresh=False),
891
+ dcc.Location(id='redirect', refresh=True),
892
+ dcc.Store(id='login-status', storage_type='session'),
893
+ dcc.Store(id="history-store", storage_type="session", data=[]),
894
+ dcc.Store(id="model-params-store", storage_type="session", data={"model": "mistralai/Mistral-Small-3.1-24B-Instruct-2503","temperature": 0.7,"max_tokens": 1024,"top_p": 0.9}),
895
+ html.Div(id='user-status-div'),
896
+ html.Div(id='page-content')
897
+ ]),
898
+ ],forceColorScheme="dark", span=12, offset=0, c='white')
899
 
900
  app_page = dmc.MantineProvider(
901
  [
 
1110
  className="g-0"
1111
  ),
1112
  html.H4(id="text-enseignement-dropdown", className="mb-3 text-success", style={"font-size": "0.7rem"}),
1113
+ dbc.Textarea(id="enseignement-dropdown", className="mb-3", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"}),
1114
  ], md=6),
1115
  dbc.Col([
1116
  dbc.Row(
 
1124
  className="g-0"
1125
  ),
1126
  html.H4("Choisir d'abord une maquette de formation avec propositions BCC", className="mb-3", style={"font-size": "0.7rem"}),
1127
+ dbc.Textarea(id="classification-dropdown", className="mb-3", placeholder="Choisir d'abord une maquette avec propositions BCC", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"}),
1128
  ], md=6)
1129
  ]),
1130
  dbc.Row([
 
1140
  className="g-0"
1141
  ),
1142
  html.H4("Choisir d'abord une maquette de formation avec propositions BCC", className="mb-3", style={"font-size": "0.7rem"}),
1143
+ dbc.Textarea(id="situation-dropdown", className="mb-3", placeholder="Choisir d'abord une maquette avec propositions BCC", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"}),
1144
  ], md=6),
1145
  dbc.Col([
1146
  dbc.Row(
 
1198
  className="g-0"
1199
  ),
1200
  html.Div(id="generation-status", className="mb-3"),
1201
+ dbc.Spinner(
1202
  html.Div(id="competence-output", className="p-3 border rounded", style={"color":"rgb(90, 242, 156)","border-color":"rgb(90, 242, 156)!important","background-color":"rgba(90, 242, 156, 0.2)"}),
1203
  ),
1204
  ], md=12),
 
1268
  align="left",
1269
  className="g-0"
1270
  ),
1271
+ html.Div(id='output-response', style={"color":"rgb(90, 242, 156)","border-radius":"3px","border":"1px solid rgb(255,255,255)!important","background-color":"rgba(90, 242, 156, 0.2)","padding":"5px"}),
1272
  html.Div(id="notification_wrapper", style={"margin-top":"1rem"}),
1273
  ], width=12)
1274
  ])
 
1498
  className="g-0"
1499
  ),
1500
  html.H4(id="text-enseignement-dropdown", className="mb-3 text-success", style={"font-size": "0.7rem"}),
1501
+ dbc.Textarea(id="enseignement-dropdown", className="mb-3", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"}),
1502
  ], md=6),
1503
  dbc.Col([
1504
  dbc.Row(
 
1512
  className="g-0"
1513
  ),
1514
  html.H4("Choisir d'abord une maquette de formation avec propositions BCC AVID", className="mb-3", style={"font-size": "0.7rem"}),
1515
+ dbc.Textarea(id="classification-dropdown", className="mb-3", placeholder="Choisir d'abord une maquette avec propositions BCC AVID", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"}),
1516
  ], md=6)
1517
  ]),
1518
  dbc.Row([
 
1528
  className="g-0"
1529
  ),
1530
  html.H4("Choisir d'abord une maquette de formation avec propositions BCC AVID", className="mb-3", style={"font-size": "0.7rem"}),
1531
+ dbc.Textarea(id="situation-dropdown", className="mb-3", placeholder="Choisir d'abord une maquette avec propositions BCC AVID", style={"height":"200px", "max-height":"250px", "font-size": "0.75rem","color":"white","border":"border 1px solid rgb(67,167,255)!important", "background-color":"transparent"}),
1532
  ], md=6),
1533
  dbc.Col([
1534
  dbc.Row(
 
1580
  className="g-0"
1581
  ),
1582
  html.Div(id="generation-status", className="mb-3"),
1583
+ dbc.Spinner(
1584
  html.Div(id="competence-output", className="p-3 border rounded", style={"color":"rgb(90, 242, 156)","border-color":"rgb(90, 242, 156)!important","background-color":"rgba(90, 242, 156, 0.2)"}),
1585
  ),
1586
  ], md=12),
 
1650
  align="left",
1651
  className="g-0"
1652
  ),
1653
+ html.Div(id='output-response-avid', style={"color":"rgb(156, 242, 242)","border-radius":"3px","border":"1px solid rgb(255,255,255)!important","background-color":"rgba(156, 242, 242, 0.2)","padding":"5px"}),
1654
  html.Div(id="notification_wrapper-avid", style={"margin-top":"1rem"}),
1655
  ], width=12)
1656
  ])
 
1779
  )
1780
  def update_enseignements_dropdown(categorie_selected, pathname):
1781
  """Mettre à jour les options du dropdown d'enseignements en fonction de la catégorie sélectionnée."""
1782
+ if not categorie_selected:
1783
+ default_text = "par défaut : "
1784
+ if pathname == "/bcc":
1785
+ categorie_selected = 'JSON/L1-Anglais.json'
1786
+ elif pathname == "/bcc-avid":
1787
+ categorie_selected = 'VD/JSON/L1-Lettres-Modernes.json'
1788
+ else:
1789
+ default_text = "formation sélectionnée : "
 
1790
 
1791
+ url = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{categorie_selected}"
1792
+ res = requests.get(url, headers=headers, params=params)
1793
+ if res.status_code == 200:
1794
+ jsonData = json.loads(base64.b64decode(res.json()['content']))
1795
+ modal_text = "**Description des catégories d'enseignements : **\n\n"
1796
+ for item in jsonData.get("categories", []):
1797
+ modal_text += f"- **{item['nom']}**:\n\n{item['description']}\n\n"
1798
+ if pathname == "/bcc":
1799
+ return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(jsonData.get("categories", []), indent = 6, separators =(",", ":"),
1800
  sort_keys = True, ensure_ascii=False), "Choisir d'abord une maquette de formation avec propositions BCC : " + default_text + jsonData.get("niveau", ""), modal_text
1801
+ elif pathname == "/bcc-avid":
1802
+ return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(jsonData.get("categories", []), indent = 6, separators =(",", ":"),
1803
+ sort_keys = True, ensure_ascii=False), "Choisir d'abord une maquette de formation avec propositions BCC : " + default_text + jsonData.get("niveau_etude", ""), modal_text
 
 
1804
 
1805
  @app.callback(
1806
  Output("classification-dropdown", "placeholder"),
 
1811
  )
1812
  def update_classification_dropdown(categorie_selected, pathname):
1813
  """Mettre à jour les options du dropdown d'enseignements en fonction de la catégorie sélectionnée."""
1814
+ if not categorie_selected:
1815
+ default_text = "par défaut : "
1816
+ if pathname == "/bcc":
1817
+ categorie_selected = 'JSON/L1-Anglais.json'
1818
+ elif pathname == "/bcc-avid":
1819
+ categorie_selected = 'VD/JSON/L1-Lettres-Modernes.json'
1820
+ else:
1821
+ default_text = ""
 
1822
 
1823
+ url = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{categorie_selected}"
1824
+ res = requests.get(url, headers=headers, params=params)
1825
+ if res.status_code == 200:
1826
+ jsonData = json.loads(base64.b64decode(res.json()['content']))
1827
+ modal_text = "**Classification des enseignements :**"
1828
+ if pathname == "/bcc":
1829
+ textarea_value = jsonData.get("classified_teachings", [])
1830
+ for key, value in textarea_value.items():
1831
+ modal_text += f"\n\n- **{key}**: "
1832
+ for i in range(0,len(value)):
1833
+ modal_text += f"{value[i]}\t"
1834
+ elif pathname == "/bcc-avid":
1835
+ textarea_value = jsonData.get("dataframe", [])
1836
+ test = " "
1837
+ for item in sorted(textarea_value, key=lambda x: x['categorie'] if x['categorie'] else ""):
1838
+ if test != item['categorie']:
1839
+ modal_text += f"\n\n- **{item['categorie']}**: "
1840
+ modal_text += f"{item['enseignements']}\t"
1841
+ test = item['categorie']
1842
 
1843
+ if pathname == "/bcc":
1844
+ return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(textarea_value, indent = 6, separators =(",", ":"),
1845
  sort_keys = True, ensure_ascii=False),modal_text
1846
+ elif pathname == "/bcc-avid":
1847
+ return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(textarea_value, indent = 6, separators =(",", ":"),
1848
  sort_keys = True, ensure_ascii=False),modal_text
 
 
1849
 
1850
  @app.callback(
1851
  Output("situation-dropdown", "placeholder"),
 
1856
  )
1857
  def update_situations_dropdown(categorie_selected, pathname):
1858
  """Mettre à jour les options du dropdown d'enseignements en fonction de la catégorie sélectionnée."""
1859
+ if not categorie_selected:
1860
+ default_text = "par défaut : "
1861
+ if pathname == "/bcc":
1862
+ categorie_selected = 'JSON/L1-Anglais.json'
1863
+ elif pathname == "/bcc-avid":
1864
+ categorie_selected = 'VD/JSON/L1-Lettres-Modernes.json'
1865
+ else:
1866
+ default_text = ""
1867
+
1868
+ url = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{categorie_selected}"
1869
+ res = requests.get(url, headers=headers, params=params)
1870
  try:
1871
+ if res.status_code == 200:
1872
+ jsonData = json.loads(base64.b64decode(res.json()['content']))
1873
+ modal_text = "**Description des situations d'apprentissage :**"
1874
  if pathname == "/bcc":
1875
+ textarea_value = jsonData.get("learning_situations", [])
1876
+ for key, value in textarea_value.items():
1877
+ modal_text += f"\n\n- **{key}**: {value}"
1878
  elif pathname == "/bcc-avid":
1879
+ textarea_value = jsonData.get("situations_apprentissage", [])
1880
+ for item in textarea_value:
1881
+ modal_text += f"\n\n- **Situation d'apprentissage**: {item['situation']}"
1882
+ if item['objectifs']:
1883
+ modal_text += f"\n\nObjectifs : "
1884
+ for objectif in item['objectifs']:
1885
+ modal_text += f"\n-{objectif}"
1886
+ modal_text += f"\n\nLien avec les thématiques ODD11 : {item['lien_odd11']}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1887
 
1888
+ if pathname == "/bcc":
1889
+ return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(textarea_value, indent = 6, separators =(",", ":"),
1890
  sort_keys = True, ensure_ascii=False), modal_text
1891
+ elif pathname == "/bcc-avid":
1892
+ return "Choisir d'abord une maquette de formation avec proposition BCC", json.dumps(textarea_value, indent = 6, separators =(",", ":"),
1893
  sort_keys = True, ensure_ascii=False), modal_text
 
 
1894
  except:
1895
+ return "Choisir d'abord une maquette de formation avec proposition BCC", "", "**Aucune situation d'apprentissage définie pour cette maquette de formation.**"
1896
 
1897
  @app.callback(
1898
  Output("selection-display", "children"),
 
2254
  except:
2255
  return html.Div(dcc.Markdown(f"""{agent}""", style={"color":"white","font-size":"0.75rem"})), []
2256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2257
  if __name__ == '__main__':
2258
  app.run_server(debug=True)