Bambo TRAORE [SNT DRPS/PEX/SDN] commited on
Commit
5088582
·
1 Parent(s): fa649ad

Add application file

Browse files
Files changed (1) hide show
  1. app.py +93 -0
app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ from utils import summarize_dataframe, validate_columns
4
+ from llm_adapter import llm_generate
5
+ from planner import plan_from_llm
6
+ from viz import plot_bar, plot_line, plot_scatter, plot_hist
7
+
8
+ def load_file(file):
9
+ if file is None:
10
+ return None, "Aucun fichier.", "", None, None
11
+ df = pd.read_csv(file.name)
12
+ preview = df.head(10)
13
+ summary = summarize_dataframe(df)
14
+ cols = list(df.columns)
15
+ return df, "✅ Dataset chargé", summary, preview, gr.update(choices=cols)
16
+
17
+ def ask_llm(summary, question):
18
+ if not summary or not question:
19
+ return "Charge un dataset et pose une question."
20
+ prompt = f"""Voici un résumé de données suivi d'une question.
21
+ Réponds en puces (6-10) + mini conclusion actionnable.
22
+
23
+ [DATA SUMMARY]
24
+ {summary}
25
+
26
+ [QUESTION]
27
+ {question}
28
+ """
29
+ return llm_generate(prompt)
30
+
31
+ def ask_to_chart(df, summary, question, bins):
32
+ if df is None:
33
+ return None, "Charge un dataset."
34
+ plan = plan_from_llm(summary, question, list(df.columns))
35
+ # Validation & défauts
36
+ x = plan.get("x"); y = plan.get("y"); chart = plan.get("chart", "bar"); agg = plan.get("agg", "count")
37
+ valid = validate_columns(df, [x, y])
38
+ x_ok = valid[0] if len(valid) > 0 else None
39
+ y_ok = valid[1] if len(valid) > 1 else None
40
+ if x_ok is None:
41
+ return None, f"Colonne X invalide. Colonnes disponibles: {list(df.columns)}"
42
+ # Routing
43
+ fig = None
44
+ if chart == "bar":
45
+ fig = plot_bar(df, x_ok, y_ok, agg)
46
+ elif chart == "line":
47
+ if y_ok is None: return None, "Pour une courbe, X et Y sont requis."
48
+ fig = plot_line(df, x_ok, y_ok, agg)
49
+ elif chart == "scatter":
50
+ if y_ok is None: return None, "Pour un scatter, X et Y sont requis."
51
+ fig = plot_scatter(df, x_ok, y_ok)
52
+ elif chart == "hist":
53
+ fig = plot_hist(df, x_ok, bins or 20)
54
+ else:
55
+ return None, f"Type de graphique non supporté: {chart}"
56
+ return fig, f"OK → plan: {plan}"
57
+
58
+ with gr.Blocks(title="Assistant analytique LLM + Gradio") as demo:
59
+ gr.Markdown("## De la donnée brute aux insights visuels — LLM + Gradio")
60
+
61
+ with gr.Row():
62
+ file = gr.File(label="Uploader un CSV")
63
+ load_btn = gr.Button("Charger")
64
+
65
+ df_state = gr.State(None)
66
+ status = gr.Markdown()
67
+ summary_box = gr.Textbox(label="Résumé (schéma + stats)", lines=12)
68
+ preview = gr.Dataframe(label="Aperçu (10 premières lignes)", interactive=False)
69
+ cols_dropdown = gr.Dropdown(choices=[], visible=False) # juste pour transporter les colonnes
70
+
71
+ def _load(file):
72
+ df, stat, summary, prev, cols = load_file(file)
73
+ return df, stat, summary, prev, cols
74
+
75
+ load_btn.click(_load, [file], [df_state, status, summary_box, preview, cols_dropdown])
76
+
77
+ gr.Markdown("---")
78
+ gr.Markdown("### 🧠 Questions à l'IA")
79
+ question = gr.Textbox(label="Pose une question (FR/EN)")
80
+ answer = gr.Markdown()
81
+ ask_btn = gr.Button("Demander à l'IA")
82
+ ask_btn.click(ask_llm, [summary_box, question], [answer])
83
+
84
+ gr.Markdown("---")
85
+ gr.Markdown("### 📊 Ask → Chart (par LLM)")
86
+ bins = gr.Slider(5, 100, value=20, step=1, label="Bins (hist)")
87
+ plot = gr.Plot(label="Graphique")
88
+ plot_msg = gr.Markdown()
89
+ chart_btn = gr.Button("Proposer et tracer le graphique")
90
+ chart_btn.click(ask_to_chart, [df_state, summary_box, question, bins], [plot, plot_msg])
91
+
92
+ if __name__ == "__main__":
93
+ demo.launch()