Ken-INOUE commited on
Commit
610a84c
·
1 Parent(s): 71ff920

Update app.py to support MCP functionality and enhance Gradio UI; improve error handling and streamline data processing

Browse files
Files changed (1) hide show
  1. app.py +9 -16
app.py CHANGED
@@ -1,9 +1,10 @@
1
- # 閾値診断アプリ Gradio版
2
 
3
  import gradio as gr
4
  import pandas as pd
5
  import numpy as np
6
  import json
 
7
 
8
  # --- ユーティリティ ---
9
  def judge_status(value, ll, l, h, hh):
@@ -19,7 +20,6 @@ def judge_status(value, ll, l, h, hh):
19
  return "OK"
20
 
21
  def convert_value(v):
22
- """numpy型をPython標準型に変換"""
23
  if hasattr(v, "item"):
24
  return v.item()
25
  return float(v) if isinstance(v, (np.floating, float)) else int(v) if isinstance(v, (np.integer, int)) else v
@@ -27,24 +27,20 @@ def convert_value(v):
27
  # --- 診断関数 ---
28
  def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, window_minutes):
29
  try:
30
- # CSV読み込み(3行ヘッダー)
31
  df = pd.read_csv(csv_file.name, header=[0, 1, 2])
32
  timestamp_col = df.iloc[:, 0]
33
  df = df.drop(df.columns[0], axis=1)
34
  df.insert(0, "timestamp", timestamp_col)
35
  df["timestamp"] = pd.to_datetime(df["timestamp"], errors="coerce")
36
 
37
- # 閾値テーブル
38
  thresholds_df = pd.read_excel(excel_file.name)
39
  thresholds_df["Important"] = thresholds_df["Important"].astype(str).str.upper().map({"TRUE": True, "FALSE": False})
40
  for col in ["LL", "L", "H", "HH"]:
41
  if col in thresholds_df.columns:
42
  thresholds_df[col] = pd.to_numeric(thresholds_df[col], errors="coerce")
43
-
44
  except Exception as e:
45
  return None, None, None, f"❌ 入力ファイルの読み込みに失敗しました: {e}", None
46
 
47
- # 対象期間抽出
48
  try:
49
  target_time = pd.to_datetime(datetime_str)
50
  except Exception:
@@ -60,7 +56,6 @@ def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, win
60
  if proc_thresholds.empty:
61
  return None, None, None, f"⚠ プロセス {process_name} の閾値が設定されていません。", None
62
 
63
- # --- 判定結果 ---
64
  all_results = []
65
  for _, row in df_window.iterrows():
66
  for _, thr in proc_thresholds.iterrows():
@@ -77,7 +72,6 @@ def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, win
77
  "時刻": str(row["timestamp"])
78
  })
79
 
80
- # --- 集計(全項目) ---
81
  total = len(all_results)
82
  status_counts = pd.Series([r["判定"] for r in all_results]).value_counts().reindex(
83
  ["LOW-LOW", "LOW", "OK", "HIGH", "HIGH-HIGH"], fill_value=0
@@ -89,7 +83,6 @@ def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, win
89
  "割合(%)": status_ratio.values
90
  })
91
 
92
- # --- 集計(重要項目全体) ---
93
  important_results = [r for r in all_results if r["重要項目"]]
94
  if important_results:
95
  total_imp = len(important_results)
@@ -106,7 +99,6 @@ def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, win
106
  result_df_imp = pd.DataFrame(columns=["状態", "件数", "割合(%)"])
107
  status_ratio_imp = pd.Series(dtype=float)
108
 
109
- # --- 集計(重要項目ごと) ---
110
  result_per_item = []
111
  for item in [r["ItemName"] for r in important_results]:
112
  item_results = [r for r in important_results if r["ItemName"] == item]
@@ -121,7 +113,6 @@ def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, win
121
  result_per_item.append({"ItemName": item, "状態": s, "件数": c, "割合(%)": r})
122
  result_df_imp_items = pd.DataFrame(result_per_item)
123
 
124
- # --- サマリー ---
125
  summary = (
126
  f"✅ {process_name} の診断完了({start_time} ~ {end_time})\n"
127
  + "[全項目] " + " / ".join([f"{s}:{r:.1f}%" for s, r in status_ratio.items()]) + "\n"
@@ -131,7 +122,6 @@ def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, win
131
  )
132
  )
133
 
134
- # --- JSON(集計結果のみ、UIと一致) ---
135
  json_data = {
136
  "集計結果": {
137
  "全項目割合": {k: convert_value(v) for k, v in status_ratio.to_dict().items()},
@@ -145,17 +135,16 @@ def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, win
145
 
146
  return result_df_all, result_df_imp, result_df_imp_items, summary, result_json
147
 
148
-
149
  # --- Gradio UI ---
150
  with gr.Blocks() as demo:
151
- gr.Markdown("## 閾値診断アプリ")
152
 
153
  with gr.Row():
154
  csv_input = gr.File(label="CSVファイルをアップロード", file_types=[".csv"], type="filepath")
155
  excel_input = gr.File(label="Excel閾値ファイルをアップロード", file_types=[".xlsx"], type="filepath")
156
 
157
  process_name = gr.Textbox(label="プロセス名", value="E018-A012_除害RO")
158
- datetime_str = gr.Textbox(label="診断基準日時 (例: 2025/8/1 1:05)", value="2025/8/1 1:05")
159
  window_minutes = gr.Number(label="さかのぼる時間幅(分)", value=60)
160
 
161
  run_btn = gr.Button("診断を実行")
@@ -173,4 +162,8 @@ with gr.Blocks() as demo:
173
  )
174
 
175
  if __name__ == "__main__":
176
- demo.launch(server_name="0.0.0.0", share=False)
 
 
 
 
 
1
+ # 閾値診断アプリ Gradio + MCP対応
2
 
3
  import gradio as gr
4
  import pandas as pd
5
  import numpy as np
6
  import json
7
+ import os
8
 
9
  # --- ユーティリティ ---
10
  def judge_status(value, ll, l, h, hh):
 
20
  return "OK"
21
 
22
  def convert_value(v):
 
23
  if hasattr(v, "item"):
24
  return v.item()
25
  return float(v) if isinstance(v, (np.floating, float)) else int(v) if isinstance(v, (np.integer, int)) else v
 
27
  # --- 診断関数 ---
28
  def diagnose_process_range(csv_file, excel_file, process_name, datetime_str, window_minutes):
29
  try:
 
30
  df = pd.read_csv(csv_file.name, header=[0, 1, 2])
31
  timestamp_col = df.iloc[:, 0]
32
  df = df.drop(df.columns[0], axis=1)
33
  df.insert(0, "timestamp", timestamp_col)
34
  df["timestamp"] = pd.to_datetime(df["timestamp"], errors="coerce")
35
 
 
36
  thresholds_df = pd.read_excel(excel_file.name)
37
  thresholds_df["Important"] = thresholds_df["Important"].astype(str).str.upper().map({"TRUE": True, "FALSE": False})
38
  for col in ["LL", "L", "H", "HH"]:
39
  if col in thresholds_df.columns:
40
  thresholds_df[col] = pd.to_numeric(thresholds_df[col], errors="coerce")
 
41
  except Exception as e:
42
  return None, None, None, f"❌ 入力ファイルの読み込みに失敗しました: {e}", None
43
 
 
44
  try:
45
  target_time = pd.to_datetime(datetime_str)
46
  except Exception:
 
56
  if proc_thresholds.empty:
57
  return None, None, None, f"⚠ プロセス {process_name} の閾値が設定されていません。", None
58
 
 
59
  all_results = []
60
  for _, row in df_window.iterrows():
61
  for _, thr in proc_thresholds.iterrows():
 
72
  "時刻": str(row["timestamp"])
73
  })
74
 
 
75
  total = len(all_results)
76
  status_counts = pd.Series([r["判定"] for r in all_results]).value_counts().reindex(
77
  ["LOW-LOW", "LOW", "OK", "HIGH", "HIGH-HIGH"], fill_value=0
 
83
  "割合(%)": status_ratio.values
84
  })
85
 
 
86
  important_results = [r for r in all_results if r["重要項目"]]
87
  if important_results:
88
  total_imp = len(important_results)
 
99
  result_df_imp = pd.DataFrame(columns=["状態", "件数", "割合(%)"])
100
  status_ratio_imp = pd.Series(dtype=float)
101
 
 
102
  result_per_item = []
103
  for item in [r["ItemName"] for r in important_results]:
104
  item_results = [r for r in important_results if r["ItemName"] == item]
 
113
  result_per_item.append({"ItemName": item, "状態": s, "件数": c, "割合(%)": r})
114
  result_df_imp_items = pd.DataFrame(result_per_item)
115
 
 
116
  summary = (
117
  f"✅ {process_name} の診断完了({start_time} ~ {end_time})\n"
118
  + "[全項目] " + " / ".join([f"{s}:{r:.1f}%" for s, r in status_ratio.items()]) + "\n"
 
122
  )
123
  )
124
 
 
125
  json_data = {
126
  "集計結果": {
127
  "全項目割合": {k: convert_value(v) for k, v in status_ratio.to_dict().items()},
 
135
 
136
  return result_df_all, result_df_imp, result_df_imp_items, summary, result_json
137
 
 
138
  # --- Gradio UI ---
139
  with gr.Blocks() as demo:
140
+ gr.Markdown("## 閾値診断アプリ (MCP対応)")
141
 
142
  with gr.Row():
143
  csv_input = gr.File(label="CSVファイルをアップロード", file_types=[".csv"], type="filepath")
144
  excel_input = gr.File(label="Excel閾値ファイルをアップロード", file_types=[".xlsx"], type="filepath")
145
 
146
  process_name = gr.Textbox(label="プロセス名", value="E018-A012_除害RO")
147
+ datetime_str = gr.Textbox(label="診断基準日時", value="2025/8/1 1:05")
148
  window_minutes = gr.Number(label="さかのぼる時間幅(分)", value=60)
149
 
150
  run_btn = gr.Button("診断を実行")
 
162
  )
163
 
164
  if __name__ == "__main__":
165
+ use_mcp = os.getenv("USE_MCP", "0") == "1"
166
+ if use_mcp:
167
+ demo.launch(mcp_server=True)
168
+ else:
169
+ demo.launch(server_name="0.0.0.0", share=False)