高橋慧 commited on
Commit
2670252
·
1 Parent(s): 43ddf11
Files changed (4) hide show
  1. app.py +136 -60
  2. app_stage3.py +173 -0
  3. requirements.txt +1 -2
  4. requirements_stage2.txt +4 -0
app.py CHANGED
@@ -1,5 +1,4 @@
1
  import gradio as gr
2
- import pandas as pd
3
  import os
4
 
5
  # 環境変数チェック
@@ -15,66 +14,108 @@ def check_environment():
15
 
16
  return missing_vars
17
 
18
- # 軽量版データ生成関数
19
- def generate_sample_dataframe(age, sex, tumor_type, GeneMutation, Meseable, Biopsiable):
20
- """サンプルデータを生成(デバッグ用)"""
21
  try:
22
  # 入力検証
23
  if not all([age, sex, tumor_type]):
24
- return pd.DataFrame()
25
 
26
  # サンプルデータの作成
27
- sample_data = {
28
- 'NCTID': ['NCT12345678', 'NCT87654321', 'NCT11111111'],
29
- 'AgentGrade': ['yes', 'no', 'unclear'],
30
- 'Title': [
31
- f'Clinical Trial for {tumor_type} in {sex} patients',
32
- f'Alternative treatment for {tumor_type}',
33
- f'Experimental therapy for {tumor_type} with {GeneMutation}'
34
- ],
35
- 'AgentJudgment': [
36
- f'{age}歳{sex}の{tumor_type}患者は参加可能です',
37
- f'{age}歳{sex}の{tumor_type}患者は参加できません',
38
- f'{age}歳{sex}の{tumor_type}患者の参加は不明確です'
39
- ],
40
- 'Japanese_Locations': ['Tokyo', 'Osaka', 'Kyoto'],
41
- 'Cancer': [tumor_type, tumor_type, tumor_type]
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
- df = pd.DataFrame(sample_data)
45
- return df
46
 
47
  except Exception as e:
48
- print(f"データフレーム生成エラー: {e}")
49
- return pd.DataFrame()
50
 
51
  # フィルタリング関数
52
- def filter_dataframe(df, grade):
53
- """データフレームをフィルタリング"""
54
- if df is None or len(df) == 0:
55
- return df
56
 
57
  try:
58
  if grade == "all":
59
- return df
60
- return df[df['AgentGrade'] == grade]
61
  except Exception as e:
62
  print(f"フィルタリングエラー: {e}")
63
- return df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  # Gradioインターフェースの作成
66
  def create_interface():
67
  missing_vars = check_environment()
68
 
69
  with gr.Blocks(title="臨床試験適格性評価", theme=gr.themes.Soft()) as demo:
70
- gr.Markdown("## 🏥 臨床試験適格性評価インターフェース")
71
 
72
  # 環境変数状態の表示
73
  if not missing_vars:
74
  gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
75
  else:
76
  gr.Markdown(f"⚠️ **注意**: 環境変数が不足しています: {', '.join(missing_vars)}")
77
- gr.Markdown("Settings → Variables and secrets で API キーを設定してください")
78
 
79
  gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Sample Data」をクリックしてください。")
80
 
@@ -90,11 +131,8 @@ def create_interface():
90
  measurable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Measurable Tumor", value="有り")
91
  biopsiable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Biopsiable Tumor", value="有り")
92
 
93
- # データフレーム表示
94
- dataframe_output = gr.DataFrame(
95
- label="Clinical Trials Results",
96
- interactive=False
97
- )
98
 
99
  # フィルタボタン
100
  with gr.Row():
@@ -105,48 +143,86 @@ def create_interface():
105
  unclear_button = gr.Button("Show Unclear", variant="secondary")
106
 
107
  # 状態管理
108
- df_state = gr.State(value=None)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
  # イベントハンドリング
111
- def update_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
112
- df = generate_sample_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
113
- return df, df
 
114
 
115
- def filter_and_show(df, grade):
116
- filtered_df = filter_dataframe(df, grade)
117
- return filtered_df
 
118
 
119
  # ボタンイベント
120
  generate_button.click(
121
- fn=update_dataframe,
122
  inputs=[age_input, sex_input, tumor_type_input, gene_mutation_input, measurable_input, biopsiable_input],
123
- outputs=[dataframe_output, df_state]
124
  )
125
 
126
  all_button.click(
127
- fn=lambda df: filter_and_show(df, "all"),
128
- inputs=[df_state],
129
- outputs=[dataframe_output]
130
  )
131
 
132
  yes_button.click(
133
- fn=lambda df: filter_and_show(df, "yes"),
134
- inputs=[df_state],
135
- outputs=[dataframe_output]
136
  )
137
 
138
  no_button.click(
139
- fn=lambda df: filter_and_show(df, "no"),
140
- inputs=[df_state],
141
- outputs=[dataframe_output]
142
  )
143
 
144
  unclear_button.click(
145
- fn=lambda df: filter_and_show(df, "unclear"),
146
- inputs=[df_state],
147
- outputs=[dataframe_output]
148
  )
149
 
 
 
 
 
150
  return demo
151
 
152
  # アプリケーション起動
 
1
  import gradio as gr
 
2
  import os
3
 
4
  # 環境変数チェック
 
14
 
15
  return missing_vars
16
 
17
+ # サンプルデータ生成(辞書のリスト形式)
18
+ def generate_sample_data(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
19
+ """サンプルデータを生成(pandas無し版)"""
20
  try:
21
  # 入力検証
22
  if not all([age, sex, tumor_type]):
23
+ return []
24
 
25
  # サンプルデータの作成
26
+ sample_data = [
27
+ {
28
+ 'NCTID': 'NCT12345678',
29
+ 'AgentGrade': 'yes',
30
+ 'Title': f'Clinical Trial for {tumor_type} in {sex} patients',
31
+ 'AgentJudgment': f'{age}歳{sex}の{tumor_type}患者は参加可能です',
32
+ 'Japanese_Locations': 'Tokyo',
33
+ 'Cancer': tumor_type,
34
+ 'Gene_Mutation': gene_mutation,
35
+ 'Measurable': measurable,
36
+ 'Biopsiable': biopsiable
37
+ },
38
+ {
39
+ 'NCTID': 'NCT87654321',
40
+ 'AgentGrade': 'no',
41
+ 'Title': f'Alternative treatment for {tumor_type}',
42
+ 'AgentJudgment': f'{age}歳{sex}の{tumor_type}患者は参加できません',
43
+ 'Japanese_Locations': 'Osaka',
44
+ 'Cancer': tumor_type,
45
+ 'Gene_Mutation': gene_mutation,
46
+ 'Measurable': measurable,
47
+ 'Biopsiable': biopsiable
48
+ },
49
+ {
50
+ 'NCTID': 'NCT11111111',
51
+ 'AgentGrade': 'unclear',
52
+ 'Title': f'Experimental therapy for {tumor_type} with {gene_mutation}',
53
+ 'AgentJudgment': f'{age}歳{sex}の{tumor_type}患者の参加は不明確です',
54
+ 'Japanese_Locations': 'Kyoto',
55
+ 'Cancer': tumor_type,
56
+ 'Gene_Mutation': gene_mutation,
57
+ 'Measurable': measurable,
58
+ 'Biopsiable': biopsiable
59
+ }
60
+ ]
61
 
62
+ return sample_data
 
63
 
64
  except Exception as e:
65
+ print(f"データ生成エラー: {e}")
66
+ return []
67
 
68
  # フィルタリング関数
69
+ def filter_data(data, grade):
70
+ """データをフィルタリング"""
71
+ if not data:
72
+ return data
73
 
74
  try:
75
  if grade == "all":
76
+ return data
77
+ return [item for item in data if item.get('AgentGrade') == grade]
78
  except Exception as e:
79
  print(f"フィルタリングエラー: {e}")
80
+ return data
81
+
82
+ # データを表形式に変換
83
+ def data_to_table(data):
84
+ """データを表形式に変換"""
85
+ if not data:
86
+ return []
87
+
88
+ # ヘッダー行
89
+ headers = ['NCTID', 'Grade', 'Title', 'Judgment', 'Location', 'Cancer']
90
+
91
+ # データ行
92
+ rows = []
93
+ for item in data:
94
+ row = [
95
+ item.get('NCTID', ''),
96
+ item.get('AgentGrade', ''),
97
+ item.get('Title', ''),
98
+ item.get('AgentJudgment', ''),
99
+ item.get('Japanese_Locations', ''),
100
+ item.get('Cancer', '')
101
+ ]
102
+ rows.append(row)
103
+
104
+ return [headers] + rows
105
 
106
  # Gradioインターフェースの作成
107
  def create_interface():
108
  missing_vars = check_environment()
109
 
110
  with gr.Blocks(title="臨床試験適格性評価", theme=gr.themes.Soft()) as demo:
111
+ gr.Markdown("## 🏥 臨床試験適格性評価インターフェース(軽量版)")
112
 
113
  # 環境変数状態の表示
114
  if not missing_vars:
115
  gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
116
  else:
117
  gr.Markdown(f"⚠️ **注意**: 環境変数が不足しています: {', '.join(missing_vars)}")
118
+ gr.Markdown("**Settings → Variables and secrets** で API キーを設定してください")
119
 
120
  gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Sample Data」をクリックしてください。")
121
 
 
131
  measurable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Measurable Tumor", value="有り")
132
  biopsiable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Biopsiable Tumor", value="有り")
133
 
134
+ # 結果表示用のHTMLエリア
135
+ results_html = gr.HTML(label="Clinical Trials Results")
 
 
 
136
 
137
  # フィルタボタン
138
  with gr.Row():
 
143
  unclear_button = gr.Button("Show Unclear", variant="secondary")
144
 
145
  # 状態管理
146
+ data_state = gr.State(value=[])
147
+
148
+ # 結果をHTMLテーブルに変換
149
+ def create_html_table(data):
150
+ if not data:
151
+ return "<p>データがありません</p>"
152
+
153
+ html = "<table style='width:100%; border-collapse: collapse;'>"
154
+ html += "<tr style='background-color: #f0f0f0;'>"
155
+ html += "<th style='border: 1px solid #ddd; padding: 8px;'>NCTID</th>"
156
+ html += "<th style='border: 1px solid #ddd; padding: 8px;'>Grade</th>"
157
+ html += "<th style='border: 1px solid #ddd; padding: 8px;'>Title</th>"
158
+ html += "<th style='border: 1px solid #ddd; padding: 8px;'>Judgment</th>"
159
+ html += "<th style='border: 1px solid #ddd; padding: 8px;'>Location</th>"
160
+ html += "</tr>"
161
+
162
+ for item in data:
163
+ grade_color = {
164
+ 'yes': '#d4edda',
165
+ 'no': '#f8d7da',
166
+ 'unclear': '#fff3cd'
167
+ }.get(item.get('AgentGrade', ''), '#ffffff')
168
+
169
+ html += f"<tr style='background-color: {grade_color};'>"
170
+ html += f"<td style='border: 1px solid #ddd; padding: 8px;'>{item.get('NCTID', '')}</td>"
171
+ html += f"<td style='border: 1px solid #ddd; padding: 8px;'>{item.get('AgentGrade', '')}</td>"
172
+ html += f"<td style='border: 1px solid #ddd; padding: 8px;'>{item.get('Title', '')}</td>"
173
+ html += f"<td style='border: 1px solid #ddd; padding: 8px;'>{item.get('AgentJudgment', '')}</td>"
174
+ html += f"<td style='border: 1px solid #ddd; padding: 8px;'>{item.get('Japanese_Locations', '')}</td>"
175
+ html += "</tr>"
176
+
177
+ html += "</table>"
178
+ return html
179
 
180
  # イベントハンドリング
181
+ def update_data(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
182
+ data = generate_sample_data(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
183
+ html_table = create_html_table(data)
184
+ return html_table, data
185
 
186
+ def filter_and_show(data, grade):
187
+ filtered_data = filter_data(data, grade)
188
+ html_table = create_html_table(filtered_data)
189
+ return html_table
190
 
191
  # ボタンイベント
192
  generate_button.click(
193
+ fn=update_data,
194
  inputs=[age_input, sex_input, tumor_type_input, gene_mutation_input, measurable_input, biopsiable_input],
195
+ outputs=[results_html, data_state]
196
  )
197
 
198
  all_button.click(
199
+ fn=lambda data: filter_and_show(data, "all"),
200
+ inputs=[data_state],
201
+ outputs=[results_html]
202
  )
203
 
204
  yes_button.click(
205
+ fn=lambda data: filter_and_show(data, "yes"),
206
+ inputs=[data_state],
207
+ outputs=[results_html]
208
  )
209
 
210
  no_button.click(
211
+ fn=lambda data: filter_and_show(data, "no"),
212
+ inputs=[data_state],
213
+ outputs=[results_html]
214
  )
215
 
216
  unclear_button.click(
217
+ fn=lambda data: filter_and_show(data, "unclear"),
218
+ inputs=[data_state],
219
+ outputs=[results_html]
220
  )
221
 
222
+ # フッター情報
223
+ gr.Markdown("---")
224
+ gr.Markdown("🔬 **技術情報**: これは軽量版です。完全版では実際のClinicalTrials.gov APIから臨床試験データを取得し、AIエージェントが適格性を自動評価します。")
225
+
226
  return demo
227
 
228
  # アプリケーション起動
app_stage3.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import time
4
+ import traceback
5
+ import os
6
+
7
+ # 軽量版のimportエラー対策
8
+ try:
9
+ from OpenAITools.FetchTools import fetch_clinical_trials
10
+ from langchain_openai import ChatOpenAI
11
+ from langchain_groq import ChatGroq
12
+ from OpenAITools.CrinicalTrialTools import SimpleClinicalTrialAgent, GraderAgent, LLMTranslator, generate_ex_question_English
13
+ FULL_VERSION = True
14
+ except ImportError as e:
15
+ print(f"完全版モジュールのインポートに失敗: {e}")
16
+ print("軽量版モードで動作します")
17
+ FULL_VERSION = False
18
+
19
+ # 環境変数チェック
20
+ def check_environment():
21
+ """環境変数をチェックし、不足している場合は警告"""
22
+ missing_vars = []
23
+
24
+ if not os.getenv("GROQ_API_KEY"):
25
+ missing_vars.append("GROQ_API_KEY")
26
+
27
+ if not os.getenv("OPENAI_API_KEY"):
28
+ missing_vars.append("OPENAI_API_KEY")
29
+
30
+ return missing_vars
31
+
32
+ # 軽量版データ生成関数
33
+ def generate_sample_dataframe(age, sex, tumor_type, GeneMutation, Meseable, Biopsiable):
34
+ """サンプルデータを生成(軽量版)"""
35
+ try:
36
+ # 入力検証
37
+ if not all([age, sex, tumor_type]):
38
+ return pd.DataFrame()
39
+
40
+ # サンプルデータの作成
41
+ sample_data = {
42
+ 'NCTID': ['NCT12345678', 'NCT87654321', 'NCT11111111'],
43
+ 'AgentGrade': ['yes', 'no', 'unclear'],
44
+ 'Title': [
45
+ f'Clinical Trial for {tumor_type} in {sex} patients',
46
+ f'Alternative treatment for {tumor_type}',
47
+ f'Experimental therapy for {tumor_type} with {GeneMutation}'
48
+ ],
49
+ 'AgentJudgment': [
50
+ f'{age}歳{sex}の{tumor_type}患者は参加可能です',
51
+ f'{age}歳{sex}の{tumor_type}患者は参加できません',
52
+ f'{age}歳{sex}の{tumor_type}患者の参加は不明確です'
53
+ ],
54
+ 'Japanese_Locations': ['Tokyo', 'Osaka', 'Kyoto'],
55
+ 'Cancer': [tumor_type, tumor_type, tumor_type]
56
+ }
57
+
58
+ df = pd.DataFrame(sample_data)
59
+ return df
60
+
61
+ except Exception as e:
62
+ print(f"データフレーム生成エラー: {e}")
63
+ return pd.DataFrame()
64
+
65
+ # 完全版データ生成関数
66
+ def generate_full_dataframe(age, sex, tumor_type, GeneMutation, Meseable, Biopsiable):
67
+ """完全版のデータ生成(実際のAPI使用)"""
68
+ if not FULL_VERSION:
69
+ return generate_sample_dataframe(age, sex, tumor_type, GeneMutation, Meseable, Biopsiable)
70
+
71
+ # 完全版の実装は元のコードと同じ
72
+ # ... (省略)
73
+
74
+ # Gradioインターフェース
75
+ def create_interface():
76
+ missing_vars = check_environment()
77
+
78
+ with gr.Blocks(title="臨床試験適格性評価", theme=gr.themes.Soft()) as demo:
79
+ gr.Markdown("## 🏥 臨床試験適格性評価インターフェース")
80
+
81
+ # バージョン情報
82
+ if FULL_VERSION:
83
+ gr.Markdown("✅ **モード**: 完全版(API連携)")
84
+ else:
85
+ gr.Markdown("⚠️ **モード**: 軽量版(サンプルデータ)")
86
+
87
+ # 環境変数状態の表示
88
+ if not missing_vars:
89
+ gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
90
+ else:
91
+ gr.Markdown(f"⚠️ **注意**: 環境変数が不足しています: {', '.join(missing_vars)}")
92
+
93
+ # 入力フィールド
94
+ with gr.Row():
95
+ with gr.Column():
96
+ age_input = gr.Textbox(label="Age", placeholder="例: 65", value="65")
97
+ sex_input = gr.Dropdown(choices=["男性", "女性"], label="Sex", value="男性")
98
+ tumor_type_input = gr.Textbox(label="Tumor Type", placeholder="例: gastric cancer", value="gastric cancer")
99
+
100
+ with gr.Column():
101
+ gene_mutation_input = gr.Textbox(label="Gene Mutation", placeholder="例: HER2", value="HER2")
102
+ measurable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Measurable Tumor", value="有り")
103
+ biopsiable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Biopsiable Tumor", value="有り")
104
+
105
+ # データフレーム表示
106
+ dataframe_output = gr.DataFrame(label="Clinical Trials Results", interactive=False)
107
+
108
+ # ボタン群
109
+ with gr.Row():
110
+ if FULL_VERSION:
111
+ generate_button = gr.Button("Generate Clinical Trials Data", variant="primary")
112
+ else:
113
+ generate_button = gr.Button("Generate Sample Data", variant="primary")
114
+
115
+ all_button = gr.Button("Show All", variant="secondary")
116
+ yes_button = gr.Button("Show Eligible", variant="secondary")
117
+ no_button = gr.Button("Show Ineligible", variant="secondary")
118
+ unclear_button = gr.Button("Show Unclear", variant="secondary")
119
+
120
+ # 状態管理
121
+ df_state = gr.State(value=None)
122
+
123
+ # イベントハンドリング
124
+ def update_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
125
+ if FULL_VERSION:
126
+ df = generate_full_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
127
+ else:
128
+ df = generate_sample_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
129
+ return df, df
130
+
131
+ def filter_dataframe(df, grade):
132
+ if df is None or len(df) == 0:
133
+ return df
134
+ if grade == "all":
135
+ return df
136
+ return df[df['AgentGrade'] == grade]
137
+
138
+ # ボタンイベント
139
+ generate_button.click(
140
+ fn=update_dataframe,
141
+ inputs=[age_input, sex_input, tumor_type_input, gene_mutation_input, measurable_input, biopsiable_input],
142
+ outputs=[dataframe_output, df_state]
143
+ )
144
+
145
+ all_button.click(
146
+ fn=lambda df: filter_dataframe(df, "all"),
147
+ inputs=[df_state],
148
+ outputs=[dataframe_output]
149
+ )
150
+
151
+ yes_button.click(
152
+ fn=lambda df: filter_dataframe(df, "yes"),
153
+ inputs=[df_state],
154
+ outputs=[dataframe_output]
155
+ )
156
+
157
+ no_button.click(
158
+ fn=lambda df: filter_dataframe(df, "no"),
159
+ inputs=[df_state],
160
+ outputs=[dataframe_output]
161
+ )
162
+
163
+ unclear_button.click(
164
+ fn=lambda df: filter_dataframe(df, "unclear"),
165
+ inputs=[df_state],
166
+ outputs=[dataframe_output]
167
+ )
168
+
169
+ return demo
170
+
171
+ if __name__ == "__main__":
172
+ demo = create_interface()
173
+ demo.launch()
requirements.txt CHANGED
@@ -1,2 +1 @@
1
- gradio==4.36.1
2
- pandas==1.5.3
 
1
+ gradio==4.36.1
 
requirements_stage2.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # Stage 2: pandas互換版(超軽量版が動作確認できてから使用)
2
+ gradio==4.36.1
3
+ numpy==1.21.6
4
+ pandas==1.3.5