llauravalente commited on
Commit
8e2eb61
·
verified ·
1 Parent(s): da9e737

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -110
app.py CHANGED
@@ -33,18 +33,6 @@ R_TAB_DIR = ART_DIR / "r" / "tables"
33
 
34
  PAPERMILL_TIMEOUT = int(os.environ.get("PAPERMILL_TIMEOUT", "1800"))
35
  MAX_PREVIEW_ROWS = int(os.environ.get("MAX_FILE_PREVIEW_ROWS", "50"))
36
- MAX_LOG_CHARS = int(os.environ.get("MAX_LOG_CHARS", "8000"))
37
-
38
- HF_API_KEY = os.environ.get("HF_API_KEY", "").strip()
39
- MODEL_NAME = os.environ.get("MODEL_NAME", "deepseek-ai/DeepSeek-R1").strip()
40
- HF_PROVIDER = os.environ.get("HF_PROVIDER", "novita").strip()
41
-
42
- LLM_ENABLED = bool(HF_API_KEY) and InferenceClient is not None
43
- llm_client = (
44
- InferenceClient(provider=HF_PROVIDER, api_key=HF_API_KEY)
45
- if LLM_ENABLED
46
- else None
47
- )
48
 
49
  # =========================================================
50
  # HELPERS
@@ -53,21 +41,11 @@ def ensure_dirs():
53
  for p in [RUNS_DIR, ART_DIR, PY_FIG_DIR, PY_TAB_DIR, R_FIG_DIR, R_TAB_DIR]:
54
  p.mkdir(parents=True, exist_ok=True)
55
 
56
- def stamp():
57
- return time.strftime("%Y%m%d-%H%M%S")
58
-
59
  def _ls(dir_path: Path, exts: Tuple[str, ...]) -> List[str]:
60
  if not dir_path.is_dir():
61
  return []
62
  return sorted(p.name for p in dir_path.iterdir() if p.is_file() and p.suffix.lower() in exts)
63
 
64
- def _read_csv(path: Path) -> pd.DataFrame:
65
- return pd.read_csv(path, nrows=MAX_PREVIEW_ROWS)
66
-
67
- def _read_json(path: Path):
68
- with path.open(encoding="utf-8") as f:
69
- return json.load(f)
70
-
71
  def artifacts_index() -> Dict[str, Any]:
72
  return {
73
  "python": {
@@ -87,9 +65,8 @@ def run_notebook(nb_name: str) -> str:
87
  ensure_dirs()
88
  nb_in = BASE_DIR / nb_name
89
  if not nb_in.exists():
90
- return f"ERROR: {nb_name} not found."
91
-
92
- nb_out = RUNS_DIR / f"run_{stamp()}_{nb_name}"
93
  pm.execute_notebook(
94
  input_path=str(nb_in),
95
  output_path=str(nb_out),
@@ -98,37 +75,19 @@ def run_notebook(nb_name: str) -> str:
98
  progress_bar=False,
99
  execution_timeout=PAPERMILL_TIMEOUT,
100
  )
101
- return f"Executed {nb_name}"
102
-
103
- def run_datacreation():
104
- try:
105
- log = run_notebook(NB1)
106
- return f"OK - {log}"
107
- except Exception as e:
108
- return f"FAILED: {str(e)}"
109
-
110
- def run_pythonanalysis():
111
- try:
112
- log = run_notebook(NB2)
113
- return f"OK - {log}"
114
- except Exception as e:
115
- return f"FAILED: {str(e)}"
116
 
117
- def run_r():
118
  try:
119
- log = run_notebook(NB3)
120
- return f"OK - {log}"
 
 
121
  except Exception as e:
122
- return f"FAILED: {str(e)}"
123
-
124
- def run_full_pipeline():
125
- res1 = run_datacreation()
126
- res2 = run_pythonanalysis()
127
- res3 = run_r()
128
- return f"Step 1: {res1}\nStep 2: {res2}\nStep 3: {res3}"
129
 
130
  # =========================================================
131
- # GALLERY & AI LOGIC
132
  # =========================================================
133
  def refresh_gallery():
134
  idx = artifacts_index()
@@ -138,11 +97,7 @@ def refresh_gallery():
138
  for p in sorted(R_FIG_DIR.glob("*.png")):
139
  figs.append((str(p), f"R | {p.stem}"))
140
 
141
- table_choices = []
142
- for s in ["python", "r"]:
143
- for t in idx[s]["tables"]:
144
- table_choices.append(f"{s}/{t}")
145
-
146
  return figs, gr.update(choices=table_choices), pd.DataFrame()
147
 
148
  def on_table_select(choice):
@@ -150,76 +105,64 @@ def on_table_select(choice):
150
  scope, name = choice.split("/", 1)
151
  path = (PY_TAB_DIR if scope == "python" else R_TAB_DIR) / name
152
  try:
153
- return pd.read_csv(path) if path.suffix == ".csv" else pd.DataFrame([json.load(open(path))])
154
  except:
155
- return pd.DataFrame({"Error": ["File non caricabile"]})
156
 
157
  def ai_chat(user_msg, history):
158
- # Fallback semplice per demo
159
- reply = "Ho ricevuto la tua richiesta."
160
- directive = {"show": "none"}
161
-
162
- msg_l = user_msg.lower()
163
- if "trend" in msg_l:
164
- reply = "Ecco i trend di vendita."
165
- directive = {"show": "figure", "scope": "python", "filename": "sales_trends_sampled_titles.png"}
166
- elif "sentiment" in msg_l:
167
- reply = "Analisi del sentiment completata."
168
- directive = {"show": "figure", "scope": "python", "filename": "sentiment_distribution_sampled_titles.png"}
169
-
170
- fig_out, tab_out = None, None
171
- if directive["show"] == "figure":
172
- base = PY_FIG_DIR if directive["scope"] == "python" else R_FIG_DIR
173
- if (base / directive["filename"]).exists():
174
- fig_out = str(base / directive["filename"])
175
-
176
- # Aggiorna la cronologia nel formato standard (lista di tuple)
177
  history = history or []
178
  history.append((user_msg, reply))
179
-
180
- return history, "", fig_out, tab_out
181
 
182
  # =========================================================
183
- # UI
184
  # =========================================================
185
  ensure_dirs()
186
 
187
- with gr.Blocks() as demo:
188
- gr.Markdown("# RX12 Workshop App")
 
189
 
190
- with gr.Tab("Pipeline Runner"):
191
- log_box = gr.Textbox(label="Log", lines=10)
 
 
 
 
 
 
 
 
 
 
 
 
192
  with gr.Row():
193
- btn1 = gr.Button("Step 1")
194
- btn2 = gr.Button("Step 2a")
195
- btn3 = gr.Button("Step 2b")
196
- btn_all = gr.Button("Run All", variant="primary")
197
-
198
- btn1.click(run_datacreation, outputs=log_box)
199
- btn2.click(run_pythonanalysis, outputs=log_box)
200
- btn3.click(run_r, outputs=log_box)
201
- btn_all.click(run_full_pipeline, outputs=log_box)
202
-
203
- with gr.Tab("Gallery"):
204
- refresh_btn = gr.Button("Refresh")
205
- gallery = gr.Gallery(label="Output")
206
- drop = gr.Dropdown(label="Tables", choices=[])
207
- df_out = gr.Dataframe()
208
 
209
- refresh_btn.click(refresh_gallery, outputs=[gallery, drop, df_out])
210
- drop.change(on_table_select, inputs=drop, outputs=df_out)
211
 
212
- with gr.Tab("AI Dashboard"):
213
  with gr.Row():
214
- with gr.Column():
215
- # Rimosso type="messages" per compatibilità
216
- chatbot = gr.Chatbot(label="Chat")
217
- txt = gr.Textbox(show_label=False, placeholder="Chiedi ai tuoi dati...")
218
- with gr.Column():
219
- ai_fig = gr.Image()
220
- ai_tab = gr.Dataframe()
221
 
222
- txt.submit(ai_chat, [txt, chatbot], [chatbot, txt, ai_fig, ai_tab])
 
 
 
223
 
224
  if __name__ == "__main__":
225
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
33
 
34
  PAPERMILL_TIMEOUT = int(os.environ.get("PAPERMILL_TIMEOUT", "1800"))
35
  MAX_PREVIEW_ROWS = int(os.environ.get("MAX_FILE_PREVIEW_ROWS", "50"))
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  # =========================================================
38
  # HELPERS
 
41
  for p in [RUNS_DIR, ART_DIR, PY_FIG_DIR, PY_TAB_DIR, R_FIG_DIR, R_TAB_DIR]:
42
  p.mkdir(parents=True, exist_ok=True)
43
 
 
 
 
44
  def _ls(dir_path: Path, exts: Tuple[str, ...]) -> List[str]:
45
  if not dir_path.is_dir():
46
  return []
47
  return sorted(p.name for p in dir_path.iterdir() if p.is_file() and p.suffix.lower() in exts)
48
 
 
 
 
 
 
 
 
49
  def artifacts_index() -> Dict[str, Any]:
50
  return {
51
  "python": {
 
65
  ensure_dirs()
66
  nb_in = BASE_DIR / nb_name
67
  if not nb_in.exists():
68
+ return f"ERROR: {nb_name} non trovato."
69
+ nb_out = RUNS_DIR / f"run_{time.strftime('%Y%m%d-%H%M%S')}_{nb_name}"
 
70
  pm.execute_notebook(
71
  input_path=str(nb_in),
72
  output_path=str(nb_out),
 
75
  progress_bar=False,
76
  execution_timeout=PAPERMILL_TIMEOUT,
77
  )
78
+ return f"Eseguito {nb_name}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ def run_full_pipeline():
81
  try:
82
+ r1 = run_notebook(NB1)
83
+ r2 = run_notebook(NB2)
84
+ r3 = run_notebook(NB3)
85
+ return f"Pipeline Completata!\n1. {r1}\n2. {r2}\n3. {r3}"
86
  except Exception as e:
87
+ return f"ERRORE: {str(e)}"
 
 
 
 
 
 
88
 
89
  # =========================================================
90
+ # UI LOGIC
91
  # =========================================================
92
  def refresh_gallery():
93
  idx = artifacts_index()
 
97
  for p in sorted(R_FIG_DIR.glob("*.png")):
98
  figs.append((str(p), f"R | {p.stem}"))
99
 
100
+ table_choices = [f"python/{t}" for t in idx["python"]["tables"]] + [f"r/{t}" for t in idx["r"]["tables"]]
 
 
 
 
101
  return figs, gr.update(choices=table_choices), pd.DataFrame()
102
 
103
  def on_table_select(choice):
 
105
  scope, name = choice.split("/", 1)
106
  path = (PY_TAB_DIR if scope == "python" else R_TAB_DIR) / name
107
  try:
108
+ return pd.read_csv(path).head(MAX_PREVIEW_ROWS) if path.suffix == ".csv" else pd.DataFrame([json.load(open(path))])
109
  except:
110
+ return pd.DataFrame({"Stato": ["Dati non ancora disponibili"]})
111
 
112
  def ai_chat(user_msg, history):
113
+ # Logica di risposta semplificata per compatibilità
114
+ reply = "Ho analizzato la tua richiesta sui dati."
115
+ fig_out = None
116
+ if "trend" in user_msg.lower():
117
+ target = PY_FIG_DIR / "sales_trends_sampled_titles.png"
118
+ if target.exists(): fig_out = str(target)
119
+
 
 
 
 
 
 
 
 
 
 
 
 
120
  history = history or []
121
  history.append((user_msg, reply))
122
+ return history, "", fig_out
 
123
 
124
  # =========================================================
125
+ # GRADIO INTERFACE
126
  # =========================================================
127
  ensure_dirs()
128
 
129
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
130
+ # BANNER SUPERIORE
131
+ gr.Image("background_top.png", show_label=False, container=False, interactive=False)
132
 
133
+ gr.Markdown("# 🚀 RX12 - Dashboard Integrata Python & R")
134
+
135
+ with gr.Tab("1. Esecuzione Analisi"):
136
+ gr.Markdown("Avvia la pipeline per generare report e grafici.")
137
+ log_box = gr.Textbox(label="Log di Sistema", lines=8)
138
+ run_btn = gr.Button("Lancia Pipeline Completa", variant="primary")
139
+ run_btn.click(run_full_pipeline, outputs=log_box)
140
+
141
+ # BANNER CENTRALE
142
+ gr.Image("background_mid.png", show_label=False, container=False, interactive=False)
143
+
144
+ with gr.Tab("2. Galleria Risultati"):
145
+ refresh_btn = gr.Button("🔄 Aggiorna Visualizzazioni")
146
+ gallery = gr.Gallery(label="Grafici Analitici", columns=2)
147
  with gr.Row():
148
+ table_drop = gr.Dropdown(label="Seleziona Tabella", choices=[])
149
+ table_out = gr.Dataframe(label="Anteprima Dati")
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
151
+ refresh_btn.click(refresh_gallery, outputs=[gallery, table_drop, table_out])
152
+ table_drop.change(on_table_select, inputs=table_drop, outputs=table_out)
153
 
154
+ with gr.Tab("3. AI Dashboard"):
155
  with gr.Row():
156
+ with gr.Column(scale=1):
157
+ chatbot = gr.Chatbot(label="Assistente Virtuale") # type="messages" RIMOSSO
158
+ msg = gr.Textbox(label="Chiedi all'AI", placeholder="Es: Mostrami i trend...")
159
+ with gr.Column(scale=1):
160
+ ai_img = gr.Image(label="Grafico Suggerito")
 
 
161
 
162
+ msg.submit(ai_chat, [msg, chatbot], [chatbot, msg, ai_img])
163
+
164
+ # BANNER INFERIORE
165
+ gr.Image("background_bottom.png", show_label=False, container=False, interactive=False)
166
 
167
  if __name__ == "__main__":
168
  demo.launch(server_name="0.0.0.0", server_port=7860)