高橋慧 commited on
Commit
c33e580
·
1 Parent(s): 636cfae

light editon

Browse files
Files changed (7) hide show
  1. README.md +23 -6
  2. app.py +122 -283
  3. appOld3.py +321 -0
  4. app_fixed.py +321 -0
  5. requirements.txt +5 -13
  6. requirements_old3.txt +50 -0
  7. requirements_spaces.txt +26 -0
README.md CHANGED
@@ -1,12 +1,29 @@
1
  ---
2
  title: ClinicalTrialV2
3
- emoji: 💻
4
- colorFrom: yellow
5
- colorTo: yellow
6
  sdk: gradio
7
- sdk_version: 5.4.0
8
- app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: ClinicalTrialV2
3
+ emoji: 🏥
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: gradio
7
+ sdk_version: 4.36.1
8
+ app_file: app_fixed.py
9
  pinned: false
10
+ license: mit
11
  ---
12
 
13
+ # 臨床試験適格性評価システム
14
+
15
+ このアプリケーションは患者情報に基づいて適切な臨床試験を見つけ、AIエージェントが適格性を自動評価するシステムです。
16
+
17
+ ## 必要な環境変数
18
+
19
+ Spacesの設定で以下の環境変数を設定してください:
20
+
21
+ - `GROQ_API_KEY`: GroqのAPIキー
22
+ - `OPENAI_API_KEY`: OpenAIのAPIキー(オプション)
23
+
24
+ ## 使用方法
25
+
26
+ 1. 患者の基本情報(年齢、性別、腫瘍タイプ)を入力
27
+ 2. 遺伝子変異情報、測定可能腫瘍の有無を入力
28
+ 3. 「Generate Clinical Trials Data」をクリック
29
+ 4. 結果をフィルタリング・ダウンロード
app.py CHANGED
@@ -1,12 +1,6 @@
1
  import gradio as gr
2
  import pandas as pd
3
- import time
4
- import traceback
5
  import os
6
- from OpenAITools.FetchTools import fetch_clinical_trials
7
- from langchain_openai import ChatOpenAI
8
- from langchain_groq import ChatGroq
9
- from OpenAITools.CrinicalTrialTools import SimpleClinicalTrialAgent, GraderAgent, LLMTranslator, generate_ex_question_English
10
 
11
  # 環境変数チェック
12
  def check_environment():
@@ -19,303 +13,148 @@ def check_environment():
19
  if not os.getenv("OPENAI_API_KEY"):
20
  missing_vars.append("OPENAI_API_KEY")
21
 
22
- if missing_vars:
23
- print(f"⚠️ 環境変数が設定されていません: {', '.join(missing_vars)}")
24
- print("一部の機能が制限される可能性があります。")
25
-
26
- return len(missing_vars) == 0
27
-
28
- # 環境変数チェック実行
29
- env_ok = check_environment()
30
-
31
- # モデルとエージェントの安全な初期化
32
- def safe_init_agents():
33
- """エージェントを安全に初期化"""
34
- try:
35
- groq = ChatGroq(model_name="llama3-70b-8192", temperature=0)
36
- translator = LLMTranslator(groq)
37
- criteria_agent = SimpleClinicalTrialAgent(groq)
38
- grader_agent = GraderAgent(groq)
39
- return translator, criteria_agent, grader_agent
40
- except Exception as e:
41
- print(f"エージェント初期化エラー: {e}")
42
- return None, None, None
43
-
44
- # エージェント初期化
45
- translator, CriteriaCheckAgent, grader_agent = safe_init_agents()
46
-
47
- # エラーハンドリング付きでエージェント評価を実行する関数
48
- def evaluate_with_retry(agent, criteria, question, max_retries=3):
49
- """エラーハンドリング付きでエージェント評価を実行"""
50
- if agent is None:
51
- return "評価エラー: エージェントが初期化されていません。API keyを確認してください。"
52
-
53
- for attempt in range(max_retries):
54
- try:
55
- return agent.evaluate_eligibility(criteria, question)
56
- except Exception as e:
57
- if "missing variables" in str(e):
58
- # プロンプトテンプレートの変数エラーの場合
59
- print(f"プロンプトテンプレートエラー (試行 {attempt + 1}/{max_retries}): {e}")
60
- return "評価エラー: プロンプトテンプレートの設定に問題があります"
61
- elif "no healthy upstream" in str(e) or "InternalServerError" in str(e):
62
- # Groqサーバーエラーの場合
63
- print(f"Groqサーバーエラー (試行 {attempt + 1}/{max_retries}): {e}")
64
- if attempt < max_retries - 1:
65
- time.sleep(2) # 2秒待機してリトライ
66
- continue
67
- else:
68
- return "評価エラー: サーバーに接続できませんでした"
69
- elif "API key" in str(e) or "authentication" in str(e).lower():
70
- return "評価エラー: API keyが無効または設定されていません"
71
- else:
72
- print(f"予期しないエラー (試行 {attempt + 1}/{max_retries}): {e}")
73
- if attempt < max_retries - 1:
74
- time.sleep(1)
75
- continue
76
- else:
77
- return f"評価エラー: {str(e)}"
78
- return "評価エラー: 最大リトライ回数に達しました"
79
-
80
- def evaluate_grade_with_retry(agent, judgment, max_retries=3):
81
- """エラーハンドリング付きでグレード評価を実行"""
82
- if agent is None:
83
- return "unclear"
84
-
85
- for attempt in range(max_retries):
86
- try:
87
- return agent.evaluate_eligibility(judgment)
88
- except Exception as e:
89
- if "no healthy upstream" in str(e) or "InternalServerError" in str(e):
90
- print(f"Groqサーバーエラー (グレード評価 - 試行 {attempt + 1}/{max_retries}): {e}")
91
- if attempt < max_retries - 1:
92
- time.sleep(2)
93
- continue
94
- else:
95
- return "unclear"
96
- elif "API key" in str(e) or "authentication" in str(e).lower():
97
- return "unclear"
98
- else:
99
- print(f"予期しないエラー (グレード評価 - 試行 {attempt + 1}/{max_retries}): {e}")
100
- if attempt < max_retries - 1:
101
- time.sleep(1)
102
- continue
103
- else:
104
- return "unclear"
105
- return "unclear"
106
 
107
- # データフレームを生成する関数
108
- def generate_dataframe(age, sex, tumor_type, GeneMutation, Meseable, Biopsiable):
 
109
  try:
110
  # 入力検証
111
  if not all([age, sex, tumor_type]):
112
- return pd.DataFrame(), pd.DataFrame()
113
 
114
- # 日本語の腫瘍タイプを英語に翻訳
115
- try:
116
- if translator is not None:
117
- TumorName = translator.translate(tumor_type)
118
- else:
119
- print("翻訳エージェントが利用できません。元の値を使用します。")
120
- TumorName = tumor_type
121
- except Exception as e:
122
- print(f"翻訳エラー: {e}")
123
- TumorName = tumor_type # 翻訳に失敗した場合は元の値を使用
124
-
125
- # 質問文を生成
126
- try:
127
- ex_question = generate_ex_question_English(age, sex, TumorName, GeneMutation, Meseable, Biopsiable)
128
- except Exception as e:
129
- print(f"質問生成エラー: {e}")
130
- return pd.DataFrame(), pd.DataFrame()
131
 
132
- # 臨床試験データの取得
133
- try:
134
- df = fetch_clinical_trials(TumorName)
135
- if df.empty:
136
- print("臨床試験データが見つかりませんでした")
137
- return pd.DataFrame(), pd.DataFrame()
138
- except Exception as e:
139
- print(f"臨床試験データ取得エラー: {e}")
140
- return pd.DataFrame(), pd.DataFrame()
141
 
142
- df['AgentJudgment'] = None
143
- df['AgentGrade'] = None
144
-
145
- # 臨床試験の適格性の評価
146
- NCTIDs = list(df['NCTID'])
147
- progress = gr.Progress(track_tqdm=True)
148
-
149
- for i, nct_id in enumerate(NCTIDs):
150
- try:
151
- target_criteria = df.loc[df['NCTID'] == nct_id, 'Eligibility Criteria'].values[0]
152
-
153
- # エラーハンドリング付きで評価実行
154
- agent_judgment = evaluate_with_retry(CriteriaCheckAgent, target_criteria, ex_question)
155
- agent_grade = evaluate_grade_with_retry(grader_agent, agent_judgment)
156
-
157
- # データフレームの更新
158
- df.loc[df['NCTID'] == nct_id, 'AgentJudgment'] = agent_judgment
159
- df.loc[df['NCTID'] == nct_id, 'AgentGrade'] = agent_grade
160
-
161
- except Exception as e:
162
- print(f"NCTID {nct_id} の評価中にエラー: {e}")
163
- df.loc[df['NCTID'] == nct_id, 'AgentJudgment'] = f"エラー: {str(e)}"
164
- df.loc[df['NCTID'] == nct_id, 'AgentGrade'] = "unclear"
165
-
166
- progress((i + 1) / len(NCTIDs))
167
-
168
- # 列を指定した順に並び替え
169
- columns_order = ['NCTID', 'AgentGrade', 'Title', 'AgentJudgment', 'Japanes Locations',
170
- 'Primary Completion Date', 'Cancer', 'Summary', 'Eligibility Criteria']
171
-
172
- # 存在する列のみを選択
173
- available_columns = [col for col in columns_order if col in df.columns]
174
- df = df[available_columns]
175
-
176
- return df, df # フィルタ用と表示用にデータフレームを返す
177
-
178
- except Exception as e:
179
- print(f"データフレーム生成中に予期しないエラー: {e}")
180
- traceback.print_exc()
181
- return pd.DataFrame(), pd.DataFrame()
182
-
183
- # CSVとして保存しダウンロードする関数
184
- def download_filtered_csv(df):
185
- try:
186
- if df is None or len(df) == 0:
187
- return None
188
- file_path = "filtered_data.csv"
189
- df.to_csv(file_path, index=False)
190
- return file_path
191
  except Exception as e:
192
- print(f"CSV保存エラー: {e}")
193
- return None
194
 
195
- # 全体結果をCSVとして保存しダウンロードする関数
196
- def download_full_csv(df):
 
 
 
 
197
  try:
198
- if df is None or len(df) == 0:
199
- return None
200
- file_path = "full_data.csv"
201
- df.to_csv(file_path, index=False)
202
- return file_path
203
  except Exception as e:
204
- print(f"CSV保存エラー: {e}")
205
- return None
206
 
207
  # Gradioインターフェースの作成
208
- with gr.Blocks(title="臨床試験適格性評価", theme=gr.themes.Soft()) as demo:
209
- gr.Markdown("## 臨床試験適格性評価インターフェース")
210
-
211
- # 環境変数状態の表示
212
- if env_ok:
213
- gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
214
- else:
215
- gr.Markdown("⚠️ **注意**: 一部の環境変数が設定されていません。機能が制限される可能性があります。")
216
 
217
- gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Clinical Trials Data」をクリックしてください。")
218
-
219
- # 各種入力フィールド
220
- with gr.Row():
221
- with gr.Column():
222
- age_input = gr.Textbox(label="Age", placeholder="例: 65", value="")
223
- sex_input = gr.Dropdown(choices=["男性", "女性"], label="Sex", value=None)
224
- tumor_type_input = gr.Textbox(label="Tumor Type", placeholder="例: gastric cancer", value="")
225
 
226
- with gr.Column():
227
- gene_mutation_input = gr.Textbox(label="Gene Mutation", placeholder="例: HER2", value="")
228
- measurable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Measurable Tumor", value=None)
229
- biopsiable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Biopsiable Tumor", value=None)
230
-
231
- # データフレーム表示エリア
232
- dataframe_output = gr.DataFrame(
233
- headers=["NCTID", "AgentGrade", "Title", "AgentJudgment", "Status"],
234
- datatype=["str", "str", "str", "str", "str"],
235
- value=None
236
- )
237
-
238
- # 内部状態用の非表示コンポーネント
239
- original_df_state = gr.State(value=None)
240
- filtered_df_state = gr.State(value=None)
241
-
242
- # ボタン類
243
- with gr.Row():
244
- generate_button = gr.Button("Generate Clinical Trials Data", variant="primary")
245
-
246
- with gr.Row():
247
- yes_button = gr.Button("Show Eligible Trials", variant="secondary")
248
- no_button = gr.Button("Show Ineligible Trials", variant="secondary")
249
- unclear_button = gr.Button("Show Unclear Trials", variant="secondary")
250
-
251
- with gr.Row():
252
- download_filtered_button = gr.Button("Download Filtered Data")
253
- download_full_button = gr.Button("Download Full Data")
254
-
255
- # ダウンロードファイル
256
- download_filtered_output = gr.File(label="Download Filtered Data", visible=False)
257
- download_full_output = gr.File(label="Download Full Data", visible=False)
258
-
259
- # イベントハンドリング
260
- def update_dataframe_and_state(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
261
- """データフレーム生成と状態更新"""
262
- df, _ = generate_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
263
- return df, df, df
264
-
265
- def filter_and_update(original_df, grade):
266
- """フィルタリングと表示更新"""
267
- if original_df is None or len(original_df) == 0:
268
- return original_df, original_df
269
 
270
- try:
271
- df_filtered = original_df[original_df['AgentGrade'] == grade]
272
- return df_filtered, df_filtered
273
- except Exception as e:
274
- print(f"フィルタリングエラー: {e}")
275
- return original_df, original_df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
 
277
- # ボタン動作の設定
278
- generate_button.click(
279
- fn=update_dataframe_and_state,
280
- inputs=[age_input, sex_input, tumor_type_input, gene_mutation_input, measurable_input, biopsiable_input],
281
- outputs=[dataframe_output, original_df_state, filtered_df_state]
282
- )
283
-
284
- yes_button.click(
285
- fn=lambda df: filter_and_update(df, "yes"),
286
- inputs=[original_df_state],
287
- outputs=[dataframe_output, filtered_df_state]
288
- )
289
-
290
- no_button.click(
291
- fn=lambda df: filter_and_update(df, "no"),
292
- inputs=[original_df_state],
293
- outputs=[dataframe_output, filtered_df_state]
294
- )
295
-
296
- unclear_button.click(
297
- fn=lambda df: filter_and_update(df, "unclear"),
298
- inputs=[original_df_state],
299
- outputs=[dataframe_output, filtered_df_state]
300
- )
301
-
302
- download_filtered_button.click(
303
- fn=download_filtered_csv,
304
- inputs=[filtered_df_state],
305
- outputs=[download_filtered_output]
306
- )
307
-
308
- download_full_button.click(
309
- fn=download_full_csv,
310
- inputs=[original_df_state],
311
- outputs=[download_full_output]
312
- )
313
-
314
  if __name__ == "__main__":
 
315
  demo.launch(
316
  server_name="0.0.0.0",
317
  server_port=7860,
318
  share=False,
319
- debug=False,
320
  show_error=True
321
- )
 
1
  import gradio as gr
2
  import pandas as pd
 
 
3
  import os
 
 
 
 
4
 
5
  # 環境変数チェック
6
  def check_environment():
 
13
  if not os.getenv("OPENAI_API_KEY"):
14
  missing_vars.append("OPENAI_API_KEY")
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
 
78
+ gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Sample Data」をクリックしてください。")
79
+
80
+ # 入力フィールド
81
+ with gr.Row():
82
+ with gr.Column():
83
+ age_input = gr.Textbox(label="Age", placeholder="例: 65", value="65")
84
+ sex_input = gr.Dropdown(choices=["男性", "女性"], label="Sex", value="男性")
85
+ tumor_type_input = gr.Textbox(label="Tumor Type", placeholder="例: gastric cancer", value="gastric cancer")
86
+
87
+ with gr.Column():
88
+ gene_mutation_input = gr.Textbox(label="Gene Mutation", placeholder="例: HER2", value="HER2")
89
+ measurable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Measurable Tumor", value="有り")
90
+ biopsiable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Biopsiable Tumor", value="有り")
91
+
92
+ # データフレーム表示
93
+ dataframe_output = gr.DataFrame(
94
+ label="Clinical Trials Results",
95
+ interactive=False
96
+ )
97
+
98
+ # フィルタボタン
99
+ with gr.Row():
100
+ generate_button = gr.Button("Generate Sample Data", variant="primary")
101
+ all_button = gr.Button("Show All", variant="secondary")
102
+ yes_button = gr.Button("Show Eligible", variant="secondary")
103
+ no_button = gr.Button("Show Ineligible", variant="secondary")
104
+ unclear_button = gr.Button("Show Unclear", variant="secondary")
105
+
106
+ # 状態管理
107
+ df_state = gr.State(value=None)
108
+
109
+ # イベントハンドリング
110
+ def update_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
111
+ df = generate_sample_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
112
+ return df, df
113
+
114
+ def filter_and_show(df, grade):
115
+ filtered_df = filter_dataframe(df, grade)
116
+ return filtered_df
117
+
118
+ # ボタンイベント
119
+ generate_button.click(
120
+ fn=update_dataframe,
121
+ inputs=[age_input, sex_input, tumor_type_input, gene_mutation_input, measurable_input, biopsiable_input],
122
+ outputs=[dataframe_output, df_state]
123
+ )
124
+
125
+ all_button.click(
126
+ fn=lambda df: filter_and_show(df, "all"),
127
+ inputs=[df_state],
128
+ outputs=[dataframe_output]
129
+ )
130
+
131
+ yes_button.click(
132
+ fn=lambda df: filter_and_show(df, "yes"),
133
+ inputs=[df_state],
134
+ outputs=[dataframe_output]
135
+ )
136
+
137
+ no_button.click(
138
+ fn=lambda df: filter_and_show(df, "no"),
139
+ inputs=[df_state],
140
+ outputs=[dataframe_output]
141
+ )
142
+
143
+ unclear_button.click(
144
+ fn=lambda df: filter_and_show(df, "unclear"),
145
+ inputs=[df_state],
146
+ outputs=[dataframe_output]
147
+ )
148
 
149
+ return demo
150
+
151
+ # アプリケーション起動
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  if __name__ == "__main__":
153
+ demo = create_interface()
154
  demo.launch(
155
  server_name="0.0.0.0",
156
  server_port=7860,
157
  share=False,
158
+ debug=True,
159
  show_error=True
160
+ )
appOld3.py ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import time
4
+ import traceback
5
+ import os
6
+ from OpenAITools.FetchTools import fetch_clinical_trials
7
+ from langchain_openai import ChatOpenAI
8
+ from langchain_groq import ChatGroq
9
+ from OpenAITools.CrinicalTrialTools import SimpleClinicalTrialAgent, GraderAgent, LLMTranslator, generate_ex_question_English
10
+
11
+ # 環境変数チェック
12
+ def check_environment():
13
+ """環境変数をチェックし、不足している場合は警告"""
14
+ missing_vars = []
15
+
16
+ if not os.getenv("GROQ_API_KEY"):
17
+ missing_vars.append("GROQ_API_KEY")
18
+
19
+ if not os.getenv("OPENAI_API_KEY"):
20
+ missing_vars.append("OPENAI_API_KEY")
21
+
22
+ if missing_vars:
23
+ print(f"⚠️ 環境変数が設定されていません: {', '.join(missing_vars)}")
24
+ print("一部の機能が制限される可能性があります。")
25
+
26
+ return len(missing_vars) == 0
27
+
28
+ # 環境変数チェック実行
29
+ env_ok = check_environment()
30
+
31
+ # モデルとエージェントの安全な初期化
32
+ def safe_init_agents():
33
+ """エージェントを安全に初期化"""
34
+ try:
35
+ groq = ChatGroq(model_name="llama3-70b-8192", temperature=0)
36
+ translator = LLMTranslator(groq)
37
+ criteria_agent = SimpleClinicalTrialAgent(groq)
38
+ grader_agent = GraderAgent(groq)
39
+ return translator, criteria_agent, grader_agent
40
+ except Exception as e:
41
+ print(f"エージェント初期化エラー: {e}")
42
+ return None, None, None
43
+
44
+ # エージェント初期化
45
+ translator, CriteriaCheckAgent, grader_agent = safe_init_agents()
46
+
47
+ # エラーハンドリング付きでエージェント評価を実行する関数
48
+ def evaluate_with_retry(agent, criteria, question, max_retries=3):
49
+ """エラーハンドリング付きでエージェント評価を実行"""
50
+ if agent is None:
51
+ return "評価エラー: エージェントが初期化されていません。API keyを確認してください。"
52
+
53
+ for attempt in range(max_retries):
54
+ try:
55
+ return agent.evaluate_eligibility(criteria, question)
56
+ except Exception as e:
57
+ if "missing variables" in str(e):
58
+ # プロンプトテンプレートの変数エラーの場合
59
+ print(f"プロンプトテンプレートエラー (試行 {attempt + 1}/{max_retries}): {e}")
60
+ return "評価エラー: プロンプトテンプレートの設定に問題があります"
61
+ elif "no healthy upstream" in str(e) or "InternalServerError" in str(e):
62
+ # Groqサーバーエラーの場合
63
+ print(f"Groqサーバーエラー (試行 {attempt + 1}/{max_retries}): {e}")
64
+ if attempt < max_retries - 1:
65
+ time.sleep(2) # 2秒待機してリトライ
66
+ continue
67
+ else:
68
+ return "評価エラー: サーバーに接続できませんでした"
69
+ elif "API key" in str(e) or "authentication" in str(e).lower():
70
+ return "評価エラー: API keyが無効または設定されていません"
71
+ else:
72
+ print(f"予期しないエラー (試行 {attempt + 1}/{max_retries}): {e}")
73
+ if attempt < max_retries - 1:
74
+ time.sleep(1)
75
+ continue
76
+ else:
77
+ return f"評価エラー: {str(e)}"
78
+ return "評価エラー: 最大リトライ回数に達しました"
79
+
80
+ def evaluate_grade_with_retry(agent, judgment, max_retries=3):
81
+ """エラーハンドリング付きでグレード評価を実行"""
82
+ if agent is None:
83
+ return "unclear"
84
+
85
+ for attempt in range(max_retries):
86
+ try:
87
+ return agent.evaluate_eligibility(judgment)
88
+ except Exception as e:
89
+ if "no healthy upstream" in str(e) or "InternalServerError" in str(e):
90
+ print(f"Groqサーバーエラー (グレード評価 - 試行 {attempt + 1}/{max_retries}): {e}")
91
+ if attempt < max_retries - 1:
92
+ time.sleep(2)
93
+ continue
94
+ else:
95
+ return "unclear"
96
+ elif "API key" in str(e) or "authentication" in str(e).lower():
97
+ return "unclear"
98
+ else:
99
+ print(f"予期しないエラー (グレード評価 - 試行 {attempt + 1}/{max_retries}): {e}")
100
+ if attempt < max_retries - 1:
101
+ time.sleep(1)
102
+ continue
103
+ else:
104
+ return "unclear"
105
+ return "unclear"
106
+
107
+ # データフレームを生成する関数
108
+ def generate_dataframe(age, sex, tumor_type, GeneMutation, Meseable, Biopsiable):
109
+ try:
110
+ # 入力検証
111
+ if not all([age, sex, tumor_type]):
112
+ return pd.DataFrame(), pd.DataFrame()
113
+
114
+ # 日本語の腫瘍タイプを英語に翻訳
115
+ try:
116
+ if translator is not None:
117
+ TumorName = translator.translate(tumor_type)
118
+ else:
119
+ print("翻訳エージェントが利用できません。元の値を使用します。")
120
+ TumorName = tumor_type
121
+ except Exception as e:
122
+ print(f"翻訳エラー: {e}")
123
+ TumorName = tumor_type # 翻訳に失敗した場合は元の値を使用
124
+
125
+ # 質問文を生成
126
+ try:
127
+ ex_question = generate_ex_question_English(age, sex, TumorName, GeneMutation, Meseable, Biopsiable)
128
+ except Exception as e:
129
+ print(f"質問生成エラー: {e}")
130
+ return pd.DataFrame(), pd.DataFrame()
131
+
132
+ # 臨床試験データの取得
133
+ try:
134
+ df = fetch_clinical_trials(TumorName)
135
+ if df.empty:
136
+ print("臨床試験データが見つかりませんでした")
137
+ return pd.DataFrame(), pd.DataFrame()
138
+ except Exception as e:
139
+ print(f"臨床試験データ取得エラー: {e}")
140
+ return pd.DataFrame(), pd.DataFrame()
141
+
142
+ df['AgentJudgment'] = None
143
+ df['AgentGrade'] = None
144
+
145
+ # 臨床試験の適格性の評価
146
+ NCTIDs = list(df['NCTID'])
147
+ progress = gr.Progress(track_tqdm=True)
148
+
149
+ for i, nct_id in enumerate(NCTIDs):
150
+ try:
151
+ target_criteria = df.loc[df['NCTID'] == nct_id, 'Eligibility Criteria'].values[0]
152
+
153
+ # エラーハンドリング付きで評価実行
154
+ agent_judgment = evaluate_with_retry(CriteriaCheckAgent, target_criteria, ex_question)
155
+ agent_grade = evaluate_grade_with_retry(grader_agent, agent_judgment)
156
+
157
+ # データフレームの更新
158
+ df.loc[df['NCTID'] == nct_id, 'AgentJudgment'] = agent_judgment
159
+ df.loc[df['NCTID'] == nct_id, 'AgentGrade'] = agent_grade
160
+
161
+ except Exception as e:
162
+ print(f"NCTID {nct_id} の評価中にエラー: {e}")
163
+ df.loc[df['NCTID'] == nct_id, 'AgentJudgment'] = f"エラー: {str(e)}"
164
+ df.loc[df['NCTID'] == nct_id, 'AgentGrade'] = "unclear"
165
+
166
+ progress((i + 1) / len(NCTIDs))
167
+
168
+ # 列を指定した順に並び替え
169
+ columns_order = ['NCTID', 'AgentGrade', 'Title', 'AgentJudgment', 'Japanes Locations',
170
+ 'Primary Completion Date', 'Cancer', 'Summary', 'Eligibility Criteria']
171
+
172
+ # 存在する列のみを選択
173
+ available_columns = [col for col in columns_order if col in df.columns]
174
+ df = df[available_columns]
175
+
176
+ return df, df # フィルタ用と表示用にデータフレームを返す
177
+
178
+ except Exception as e:
179
+ print(f"データフレーム生成中に予期しないエラー: {e}")
180
+ traceback.print_exc()
181
+ return pd.DataFrame(), pd.DataFrame()
182
+
183
+ # CSVとして保存しダウンロードする関数
184
+ def download_filtered_csv(df):
185
+ try:
186
+ if df is None or len(df) == 0:
187
+ return None
188
+ file_path = "filtered_data.csv"
189
+ df.to_csv(file_path, index=False)
190
+ return file_path
191
+ except Exception as e:
192
+ print(f"CSV保存エラー: {e}")
193
+ return None
194
+
195
+ # 全体結果をCSVとして保存しダウンロードする関数
196
+ def download_full_csv(df):
197
+ try:
198
+ if df is None or len(df) == 0:
199
+ return None
200
+ file_path = "full_data.csv"
201
+ df.to_csv(file_path, index=False)
202
+ return file_path
203
+ except Exception as e:
204
+ print(f"CSV保存エラー: {e}")
205
+ return None
206
+
207
+ # Gradioインターフェースの作成
208
+ with gr.Blocks(title="臨床試験適格性評価", theme=gr.themes.Soft()) as demo:
209
+ gr.Markdown("## 臨床試験適格性評価インターフェース")
210
+
211
+ # 環境変数状態の表示
212
+ if env_ok:
213
+ gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
214
+ else:
215
+ gr.Markdown("⚠️ **注意**: 一部の環境変数が設定されていません。機能が制限される可能性があります。")
216
+
217
+ gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Clinical Trials Data」をクリックしてください。")
218
+
219
+ # 各種入力フィールド
220
+ with gr.Row():
221
+ with gr.Column():
222
+ age_input = gr.Textbox(label="Age", placeholder="例: 65", value="")
223
+ sex_input = gr.Dropdown(choices=["男性", "女性"], label="Sex", value=None)
224
+ tumor_type_input = gr.Textbox(label="Tumor Type", placeholder="例: gastric cancer", value="")
225
+
226
+ with gr.Column():
227
+ gene_mutation_input = gr.Textbox(label="Gene Mutation", placeholder="例: HER2", value="")
228
+ measurable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Measurable Tumor", value=None)
229
+ biopsiable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Biopsiable Tumor", value=None)
230
+
231
+ # データフレーム表示エリア
232
+ dataframe_output = gr.DataFrame(
233
+ headers=["NCTID", "AgentGrade", "Title", "AgentJudgment", "Status"],
234
+ datatype=["str", "str", "str", "str", "str"],
235
+ value=None
236
+ )
237
+
238
+ # 内部状態用の非表示コンポーネント
239
+ original_df_state = gr.State(value=None)
240
+ filtered_df_state = gr.State(value=None)
241
+
242
+ # ボタン類
243
+ with gr.Row():
244
+ generate_button = gr.Button("Generate Clinical Trials Data", variant="primary")
245
+
246
+ with gr.Row():
247
+ yes_button = gr.Button("Show Eligible Trials", variant="secondary")
248
+ no_button = gr.Button("Show Ineligible Trials", variant="secondary")
249
+ unclear_button = gr.Button("Show Unclear Trials", variant="secondary")
250
+
251
+ with gr.Row():
252
+ download_filtered_button = gr.Button("Download Filtered Data")
253
+ download_full_button = gr.Button("Download Full Data")
254
+
255
+ # ダウンロードファイル
256
+ download_filtered_output = gr.File(label="Download Filtered Data", visible=False)
257
+ download_full_output = gr.File(label="Download Full Data", visible=False)
258
+
259
+ # イベントハンドリング
260
+ def update_dataframe_and_state(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
261
+ """データフレーム生成と状態更新"""
262
+ df, _ = generate_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
263
+ return df, df, df
264
+
265
+ def filter_and_update(original_df, grade):
266
+ """フィルタリングと表示更新"""
267
+ if original_df is None or len(original_df) == 0:
268
+ return original_df, original_df
269
+
270
+ try:
271
+ df_filtered = original_df[original_df['AgentGrade'] == grade]
272
+ return df_filtered, df_filtered
273
+ except Exception as e:
274
+ print(f"フィルタリングエラー: {e}")
275
+ return original_df, original_df
276
+
277
+ # ボタン動作の設定
278
+ generate_button.click(
279
+ fn=update_dataframe_and_state,
280
+ inputs=[age_input, sex_input, tumor_type_input, gene_mutation_input, measurable_input, biopsiable_input],
281
+ outputs=[dataframe_output, original_df_state, filtered_df_state]
282
+ )
283
+
284
+ yes_button.click(
285
+ fn=lambda df: filter_and_update(df, "yes"),
286
+ inputs=[original_df_state],
287
+ outputs=[dataframe_output, filtered_df_state]
288
+ )
289
+
290
+ no_button.click(
291
+ fn=lambda df: filter_and_update(df, "no"),
292
+ inputs=[original_df_state],
293
+ outputs=[dataframe_output, filtered_df_state]
294
+ )
295
+
296
+ unclear_button.click(
297
+ fn=lambda df: filter_and_update(df, "unclear"),
298
+ inputs=[original_df_state],
299
+ outputs=[dataframe_output, filtered_df_state]
300
+ )
301
+
302
+ download_filtered_button.click(
303
+ fn=download_filtered_csv,
304
+ inputs=[filtered_df_state],
305
+ outputs=[download_filtered_output]
306
+ )
307
+
308
+ download_full_button.click(
309
+ fn=download_full_csv,
310
+ inputs=[original_df_state],
311
+ outputs=[download_full_output]
312
+ )
313
+
314
+ if __name__ == "__main__":
315
+ demo.launch(
316
+ server_name="0.0.0.0",
317
+ server_port=7860,
318
+ share=False,
319
+ debug=False,
320
+ show_error=True
321
+ )
app_fixed.py ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import time
4
+ import traceback
5
+ import os
6
+ from OpenAITools.FetchTools import fetch_clinical_trials
7
+ from langchain_openai import ChatOpenAI
8
+ from langchain_groq import ChatGroq
9
+ from OpenAITools.CrinicalTrialTools import SimpleClinicalTrialAgent, GraderAgent, LLMTranslator, generate_ex_question_English
10
+
11
+ # 環境変数チェック
12
+ def check_environment():
13
+ """環境変数をチェックし、不足している場合は警告"""
14
+ missing_vars = []
15
+
16
+ if not os.getenv("GROQ_API_KEY"):
17
+ missing_vars.append("GROQ_API_KEY")
18
+
19
+ if not os.getenv("OPENAI_API_KEY"):
20
+ missing_vars.append("OPENAI_API_KEY")
21
+
22
+ if missing_vars:
23
+ print(f"⚠️ 環境変数が設定されていません: {', '.join(missing_vars)}")
24
+ print("一部の機能が制限される可能性があります。")
25
+
26
+ return len(missing_vars) == 0
27
+
28
+ # 環境変数チェック実行
29
+ env_ok = check_environment()
30
+
31
+ # モデルとエージェントの安全な初期化
32
+ def safe_init_agents():
33
+ """エージェントを安全に初期化"""
34
+ try:
35
+ groq = ChatGroq(model_name="llama3-70b-8192", temperature=0)
36
+ translator = LLMTranslator(groq)
37
+ criteria_agent = SimpleClinicalTrialAgent(groq)
38
+ grader_agent = GraderAgent(groq)
39
+ return translator, criteria_agent, grader_agent
40
+ except Exception as e:
41
+ print(f"エージェント初期化エラー: {e}")
42
+ return None, None, None
43
+
44
+ # エージェント初期化
45
+ translator, CriteriaCheckAgent, grader_agent = safe_init_agents()
46
+
47
+ # エラーハンドリング付きでエージェント評価を実行する関数
48
+ def evaluate_with_retry(agent, criteria, question, max_retries=3):
49
+ """エラーハンドリング付きでエージェント評価を実行"""
50
+ if agent is None:
51
+ return "評価エラー: エージェントが初期化されていません。API keyを確認してください。"
52
+
53
+ for attempt in range(max_retries):
54
+ try:
55
+ return agent.evaluate_eligibility(criteria, question)
56
+ except Exception as e:
57
+ if "missing variables" in str(e):
58
+ # プロンプトテンプレートの変数エラーの場合
59
+ print(f"プロンプトテンプレートエラー (試行 {attempt + 1}/{max_retries}): {e}")
60
+ return "評価エラー: プロンプトテンプレートの設定に問題があります"
61
+ elif "no healthy upstream" in str(e) or "InternalServerError" in str(e):
62
+ # Groqサーバーエラーの場合
63
+ print(f"Groqサーバーエラー (試行 {attempt + 1}/{max_retries}): {e}")
64
+ if attempt < max_retries - 1:
65
+ time.sleep(2) # 2秒待機してリトライ
66
+ continue
67
+ else:
68
+ return "評価エラー: サーバーに接続できませんでした"
69
+ elif "API key" in str(e) or "authentication" in str(e).lower():
70
+ return "評価エラー: API keyが無効または設定されていません"
71
+ else:
72
+ print(f"予期しないエラー (試行 {attempt + 1}/{max_retries}): {e}")
73
+ if attempt < max_retries - 1:
74
+ time.sleep(1)
75
+ continue
76
+ else:
77
+ return f"評価エラー: {str(e)}"
78
+ return "評価エラー: 最大リトライ回数に達しました"
79
+
80
+ def evaluate_grade_with_retry(agent, judgment, max_retries=3):
81
+ """エラーハンドリング付きでグレード評価を実行"""
82
+ if agent is None:
83
+ return "unclear"
84
+
85
+ for attempt in range(max_retries):
86
+ try:
87
+ return agent.evaluate_eligibility(judgment)
88
+ except Exception as e:
89
+ if "no healthy upstream" in str(e) or "InternalServerError" in str(e):
90
+ print(f"Groqサーバーエラー (グレード評価 - 試行 {attempt + 1}/{max_retries}): {e}")
91
+ if attempt < max_retries - 1:
92
+ time.sleep(2)
93
+ continue
94
+ else:
95
+ return "unclear"
96
+ elif "API key" in str(e) or "authentication" in str(e).lower():
97
+ return "unclear"
98
+ else:
99
+ print(f"予期しないエラー (グレード評価 - 試行 {attempt + 1}/{max_retries}): {e}")
100
+ if attempt < max_retries - 1:
101
+ time.sleep(1)
102
+ continue
103
+ else:
104
+ return "unclear"
105
+ return "unclear"
106
+
107
+ # データフレームを生成する関数
108
+ def generate_dataframe(age, sex, tumor_type, GeneMutation, Meseable, Biopsiable):
109
+ try:
110
+ # 入力検証
111
+ if not all([age, sex, tumor_type]):
112
+ return pd.DataFrame(), pd.DataFrame()
113
+
114
+ # 日本語の腫瘍タイプを英語に翻訳
115
+ try:
116
+ if translator is not None:
117
+ TumorName = translator.translate(tumor_type)
118
+ else:
119
+ print("翻訳エージェントが利用できません。元の値を使用します。")
120
+ TumorName = tumor_type
121
+ except Exception as e:
122
+ print(f"翻訳エラー: {e}")
123
+ TumorName = tumor_type # 翻訳に失敗した場合は元の値を使用
124
+
125
+ # 質問文を生成
126
+ try:
127
+ ex_question = generate_ex_question_English(age, sex, TumorName, GeneMutation, Meseable, Biopsiable)
128
+ except Exception as e:
129
+ print(f"質問生成エラー: {e}")
130
+ return pd.DataFrame(), pd.DataFrame()
131
+
132
+ # 臨床試験データの取得
133
+ try:
134
+ df = fetch_clinical_trials(TumorName)
135
+ if df.empty:
136
+ print("臨床試験データが見つかりませんでした")
137
+ return pd.DataFrame(), pd.DataFrame()
138
+ except Exception as e:
139
+ print(f"臨床試験データ取得エラー: {e}")
140
+ return pd.DataFrame(), pd.DataFrame()
141
+
142
+ df['AgentJudgment'] = None
143
+ df['AgentGrade'] = None
144
+
145
+ # 臨床試験の適格性の評価
146
+ NCTIDs = list(df['NCTID'])
147
+ progress = gr.Progress(track_tqdm=True)
148
+
149
+ for i, nct_id in enumerate(NCTIDs):
150
+ try:
151
+ target_criteria = df.loc[df['NCTID'] == nct_id, 'Eligibility Criteria'].values[0]
152
+
153
+ # エラーハンドリング付きで評価実行
154
+ agent_judgment = evaluate_with_retry(CriteriaCheckAgent, target_criteria, ex_question)
155
+ agent_grade = evaluate_grade_with_retry(grader_agent, agent_judgment)
156
+
157
+ # データフレームの更新
158
+ df.loc[df['NCTID'] == nct_id, 'AgentJudgment'] = agent_judgment
159
+ df.loc[df['NCTID'] == nct_id, 'AgentGrade'] = agent_grade
160
+
161
+ except Exception as e:
162
+ print(f"NCTID {nct_id} の評価中にエラー: {e}")
163
+ df.loc[df['NCTID'] == nct_id, 'AgentJudgment'] = f"エラー: {str(e)}"
164
+ df.loc[df['NCTID'] == nct_id, 'AgentGrade'] = "unclear"
165
+
166
+ progress((i + 1) / len(NCTIDs))
167
+
168
+ # 列を指定した順に並び替え
169
+ columns_order = ['NCTID', 'AgentGrade', 'Title', 'AgentJudgment', 'Japanes Locations',
170
+ 'Primary Completion Date', 'Cancer', 'Summary', 'Eligibility Criteria']
171
+
172
+ # 存在する列のみを選択
173
+ available_columns = [col for col in columns_order if col in df.columns]
174
+ df = df[available_columns]
175
+
176
+ return df, df # フィルタ用と表示用にデータフレームを返す
177
+
178
+ except Exception as e:
179
+ print(f"データフレーム生成中に予期しないエラー: {e}")
180
+ traceback.print_exc()
181
+ return pd.DataFrame(), pd.DataFrame()
182
+
183
+ # CSVとして保存しダウンロードする関数
184
+ def download_filtered_csv(df):
185
+ try:
186
+ if df is None or len(df) == 0:
187
+ return None
188
+ file_path = "filtered_data.csv"
189
+ df.to_csv(file_path, index=False)
190
+ return file_path
191
+ except Exception as e:
192
+ print(f"CSV保存エラー: {e}")
193
+ return None
194
+
195
+ # 全体結果をCSVとして保存しダウンロードする関数
196
+ def download_full_csv(df):
197
+ try:
198
+ if df is None or len(df) == 0:
199
+ return None
200
+ file_path = "full_data.csv"
201
+ df.to_csv(file_path, index=False)
202
+ return file_path
203
+ except Exception as e:
204
+ print(f"CSV保存エラー: {e}")
205
+ return None
206
+
207
+ # Gradioインターフェースの作成
208
+ with gr.Blocks(title="臨床試験適格性評価", theme=gr.themes.Soft()) as demo:
209
+ gr.Markdown("## 臨床試験適格性評価インターフェース")
210
+
211
+ # 環境変数状態の表示
212
+ if env_ok:
213
+ gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
214
+ else:
215
+ gr.Markdown("⚠️ **注意**: 一部の環境変数が設定されていません。機能が制限される可能性があります。")
216
+
217
+ gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Clinical Trials Data」をクリックしてください。")
218
+
219
+ # 各種入力フィールド
220
+ with gr.Row():
221
+ with gr.Column():
222
+ age_input = gr.Textbox(label="Age", placeholder="例: 65", value="")
223
+ sex_input = gr.Dropdown(choices=["男性", "女性"], label="Sex", value=None)
224
+ tumor_type_input = gr.Textbox(label="Tumor Type", placeholder="例: gastric cancer", value="")
225
+
226
+ with gr.Column():
227
+ gene_mutation_input = gr.Textbox(label="Gene Mutation", placeholder="例: HER2", value="")
228
+ measurable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Measurable Tumor", value=None)
229
+ biopsiable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Biopsiable Tumor", value=None)
230
+
231
+ # データフレーム表示エリア(修正版)
232
+ dataframe_output = gr.DataFrame(
233
+ label="Clinical Trials Results",
234
+ interactive=False,
235
+ wrap=True
236
+ )
237
+
238
+ # 内部状態用の非表示コンポーネント
239
+ original_df_state = gr.State(value=None)
240
+ filtered_df_state = gr.State(value=None)
241
+
242
+ # ボタン類
243
+ with gr.Row():
244
+ generate_button = gr.Button("Generate Clinical Trials Data", variant="primary")
245
+
246
+ with gr.Row():
247
+ yes_button = gr.Button("Show Eligible Trials", variant="secondary")
248
+ no_button = gr.Button("Show Ineligible Trials", variant="secondary")
249
+ unclear_button = gr.Button("Show Unclear Trials", variant="secondary")
250
+
251
+ with gr.Row():
252
+ download_filtered_button = gr.Button("Download Filtered Data")
253
+ download_full_button = gr.Button("Download Full Data")
254
+
255
+ # ダウンロードファイル
256
+ download_filtered_output = gr.File(label="Download Filtered Data", visible=False)
257
+ download_full_output = gr.File(label="Download Full Data", visible=False)
258
+
259
+ # イベントハンドリング
260
+ def update_dataframe_and_state(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
261
+ """データフレーム生成と状態更新"""
262
+ df, _ = generate_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
263
+ return df, df, df
264
+
265
+ def filter_and_update(original_df, grade):
266
+ """フィルタリングと表示更新"""
267
+ if original_df is None or len(original_df) == 0:
268
+ return original_df, original_df
269
+
270
+ try:
271
+ df_filtered = original_df[original_df['AgentGrade'] == grade]
272
+ return df_filtered, df_filtered
273
+ except Exception as e:
274
+ print(f"フィルタリングエラー: {e}")
275
+ return original_df, original_df
276
+
277
+ # ボタン動作の設定
278
+ generate_button.click(
279
+ fn=update_dataframe_and_state,
280
+ inputs=[age_input, sex_input, tumor_type_input, gene_mutation_input, measurable_input, biopsiable_input],
281
+ outputs=[dataframe_output, original_df_state, filtered_df_state]
282
+ )
283
+
284
+ yes_button.click(
285
+ fn=lambda df: filter_and_update(df, "yes"),
286
+ inputs=[original_df_state],
287
+ outputs=[dataframe_output, filtered_df_state]
288
+ )
289
+
290
+ no_button.click(
291
+ fn=lambda df: filter_and_update(df, "no"),
292
+ inputs=[original_df_state],
293
+ outputs=[dataframe_output, filtered_df_state]
294
+ )
295
+
296
+ unclear_button.click(
297
+ fn=lambda df: filter_and_update(df, "unclear"),
298
+ inputs=[original_df_state],
299
+ outputs=[dataframe_output, filtered_df_state]
300
+ )
301
+
302
+ download_filtered_button.click(
303
+ fn=download_filtered_csv,
304
+ inputs=[filtered_df_state],
305
+ outputs=[download_filtered_output]
306
+ )
307
+
308
+ download_full_button.click(
309
+ fn=download_full_csv,
310
+ inputs=[original_df_state],
311
+ outputs=[download_full_output]
312
+ )
313
+
314
+ if __name__ == "__main__":
315
+ demo.launch(
316
+ server_name="0.0.0.0",
317
+ server_port=7860,
318
+ share=False,
319
+ debug=False,
320
+ show_error=True
321
+ )
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
- # Core web framework (固定バージョンで安定性確保)
2
- gradio==4.44.0
3
 
4
  # Data processing
5
  pandas>=1.5.0
@@ -24,27 +24,19 @@ SQLAlchemy>=2.0.0,<3.0.0
24
  # Pydantic (LangChain互換性のため)
25
  pydantic>=2.5.0,<3.0.0
26
 
27
- # Text processing (軽量化)
28
  tiktoken>=0.4.0
29
 
30
  # Utilities
31
  tenacity>=8.0.0
32
  packaging>=23.0.0
33
 
34
- # Optional: Bio-related libraries (if needed for your specific use case)
35
- # Uncomment the following lines if bio-processing is required
36
  # biopython>=1.83
37
  # bio>=1.7.1
38
  # biothings-client>=0.3.1
39
  # mygene>=3.2.2
40
 
41
- # Optional: Advanced LangChain features (if needed)
42
  # langchainhub>=0.1.20
43
  # langgraph>=0.2.30
44
-
45
- # Optional: Additional LLama Index support (if needed)
46
- # Uncomment if you're using LlamaIndex in addition to LangChain
47
- # llama-index>=0.10.0
48
- # llama-index-core>=0.10.0
49
- # llama-index-llms-openai>=0.1.20
50
- # llama-index-llms-groq>=0.1.4
 
1
+ # Core web framework (安定バージョンに固定)
2
+ gradio==4.36.1
3
 
4
  # Data processing
5
  pandas>=1.5.0
 
24
  # Pydantic (LangChain互換性のため)
25
  pydantic>=2.5.0,<3.0.0
26
 
27
+ # Text processing
28
  tiktoken>=0.4.0
29
 
30
  # Utilities
31
  tenacity>=8.0.0
32
  packaging>=23.0.0
33
 
34
+ # Bio-related libraries (必要に応じて)
 
35
  # biopython>=1.83
36
  # bio>=1.7.1
37
  # biothings-client>=0.3.1
38
  # mygene>=3.2.2
39
 
40
+ # Optional: Advanced LangChain features
41
  # langchainhub>=0.1.20
42
  # langgraph>=0.2.30
 
 
 
 
 
 
 
requirements_old3.txt ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Core web framework (固定バージョンで安定性確保)
2
+ gradio==4.44.0
3
+
4
+ # Data processing
5
+ pandas>=1.5.0
6
+ numpy>=1.21.0
7
+ requests>=2.25.0
8
+
9
+ # LangChain ecosystem (互換性のあるバージョンに調整)
10
+ langchain==0.2.16
11
+ langchain-community==0.2.16
12
+ langchain-core==0.2.38
13
+ langchain-openai==0.1.23
14
+ langchain-groq==0.1.9
15
+ langchain-text-splitters==0.2.4
16
+
17
+ # LLM providers
18
+ openai>=1.0.0,<2.0.0
19
+ groq>=0.4.0
20
+
21
+ # Database utilities
22
+ SQLAlchemy>=2.0.0,<3.0.0
23
+
24
+ # Pydantic (LangChain互換性のため)
25
+ pydantic>=2.5.0,<3.0.0
26
+
27
+ # Text processing (軽量化)
28
+ tiktoken>=0.4.0
29
+
30
+ # Utilities
31
+ tenacity>=8.0.0
32
+ packaging>=23.0.0
33
+
34
+ # Optional: Bio-related libraries (if needed for your specific use case)
35
+ # Uncomment the following lines if bio-processing is required
36
+ # biopython>=1.83
37
+ # bio>=1.7.1
38
+ # biothings-client>=0.3.1
39
+ # mygene>=3.2.2
40
+
41
+ # Optional: Advanced LangChain features (if needed)
42
+ # langchainhub>=0.1.20
43
+ # langgraph>=0.2.30
44
+
45
+ # Optional: Additional LLama Index support (if needed)
46
+ # Uncomment if you're using LlamaIndex in addition to LangChain
47
+ # llama-index>=0.10.0
48
+ # llama-index-core>=0.10.0
49
+ # llama-index-llms-openai>=0.1.20
50
+ # llama-index-llms-groq>=0.1.4
requirements_spaces.txt ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Hugging Face Spaces最適化版
2
+ gradio==4.36.1
3
+ pandas==1.5.3
4
+ numpy==1.24.3
5
+ requests==2.31.0
6
+
7
+ # LangChain (軽量版)
8
+ langchain==0.1.20
9
+ langchain-community==0.0.38
10
+ langchain-core==0.1.52
11
+ langchain-openai==0.1.7
12
+ langchain-groq==0.1.5
13
+
14
+ # LLM providers
15
+ openai==1.12.0
16
+ groq==0.4.2
17
+
18
+ # Database
19
+ SQLAlchemy==2.0.23
20
+
21
+ # Pydantic
22
+ pydantic==2.5.3
23
+
24
+ # Utilities
25
+ tiktoken==0.5.2
26
+ tenacity==8.2.3