lune-lune commited on
Commit
94de047
·
verified ·
1 Parent(s): a023c24

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +140 -0
app.py CHANGED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import google.generativeai as genai
3
+ import time
4
+ import os
5
+
6
+ # 外部ファイルの読み込み(news_collector.py と ai_analyst.py が同じ場所にある前提)
7
+ from news_collector import fetch_rss_news
8
+ from ai_analyst import analyze_news
9
+
10
+ def run_insight_process(api_key):
11
+ """
12
+ ニュース取得から解析までを順次実行し、ログをリアルタイムで画面に返す関数
13
+ """
14
+ if not api_key or len(api_key) < 10:
15
+ yield "❌ エラー: 有効なGemini APIキーをサイドバーに入力してください。"
16
+ return
17
+
18
+ # APIキーのセット(ai_analyst.pyが参照できるように環境変数にもセット)
19
+ os.environ["GEMINI_API_KEY"] = api_key
20
+ genai.configure(api_key=api_key)
21
+
22
+ log_output = "🚀 投資インサイト解析を開始します...\n"
23
+ yield log_output
24
+
25
+ try:
26
+ # 1. ニュース収集
27
+ log_output += "📡 ニュースサイトから最新記事を収集中...\n"
28
+ yield log_output
29
+ articles = fetch_rss_news()
30
+
31
+ if not articles:
32
+ yield log_output + "❌ ニュースの取得に失敗したか、記事が見つかりませんでした。"
33
+ return
34
+
35
+ log_output += f"✅ {len(articles)}件のニュースを取得しました。上位5件を解析します。\n\n"
36
+ yield log_output
37
+
38
+ # 2. 解析ループ(上位5件)
39
+ top_articles = articles[:5]
40
+ for i, article in enumerate(top_articles):
41
+ log_output += f"🔍 解析中 ({i+1}/{len(top_articles)}): {article['title']}\n"
42
+ yield log_output
43
+
44
+ # AI解析の実行
45
+ try:
46
+ res = analyze_news(article)
47
+
48
+ # スコアの数値化とバリデーション
49
+ try:
50
+ score = int(res.get('market_impact_score', 0))
51
+ except:
52
+ score = 0
53
+
54
+ # スコアに応じたアイコンと符号
55
+ if score > 0:
56
+ score_display = f"+{score}"
57
+ icon = "📈"
58
+ elif score < 0:
59
+ score_display = f"{score}"
60
+ icon = "📉"
61
+ else:
62
+ score_display = "0"
63
+ icon = "➖"
64
+
65
+ # レポートの構築(文字バラバラ対策済み)
66
+ report = f"===== 【分析結果】 {icon} スコア: {score_display} / 10 =====\n"
67
+ report += f"■ 歴史的類似性:\n{res.get('historical_precedent', '情報なし')}\n\n"
68
+
69
+ # リスト形式のデータ(弱気視点)が文章で返ってきた場合でも正しく表示する処理
70
+ report += f"■ 警戒すべきリスク/弱気視点:\n"
71
+ bearish = res.get('bearish_view', [])
72
+ if isinstance(bearish, list):
73
+ for r in bearish:
74
+ report += f" ・{str(r)}\n"
75
+ else:
76
+ report += f" ・{str(bearish)}\n"
77
+
78
+ # リスト形式のデータ(影響セクター)の表示処理
79
+ report += f"\n■ 影響セクター:\n"
80
+ sectors = res.get('sector_impact', [])
81
+ if isinstance(sectors, list):
82
+ report += f"{', '.join([str(s) for s in sectors])}\n"
83
+ else:
84
+ report += f"{str(sectors)}\n"
85
+
86
+ report += "==========================================\n\n"
87
+
88
+ log_output += report
89
+ yield log_output
90
+
91
+ except Exception as e:
92
+ log_output += f"⚠️ この記事の解析中にエラーが発生しました: {str(e)}\n\n"
93
+ yield log_output
94
+
95
+ # 無料枠のAPI制限を考慮して少し待機
96
+ if i < len(top_articles) - 1:
97
+ time.sleep(2)
98
+
99
+ log_output += "🎉 すべての解析作業が完了しました。"
100
+ yield log_output
101
+
102
+ except Exception as e:
103
+ yield log_output + f"\n❌ システムエラーが発生しました: {str(e)}"
104
+
105
+ # --- Gradio UIのデザイン ---
106
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
107
+ gr.Markdown("""
108
+ # 📈 AI投資インサイト・アナライザー
109
+ 最新の経済ニュースを取得し、Gemini 1.5 Flashが投資判断を21段階でスコアリングします。
110
+ """)
111
+
112
+ with gr.Sidebar():
113
+ gr.Markdown("### 設定")
114
+ api_input = gr.Textbox(
115
+ label="1. Gemini API Key",
116
+ type="password",
117
+ placeholder="AI Studioのキーを貼り付け"
118
+ )
119
+ start_btn = gr.Button("解析実行", variant="primary")
120
+ gr.Markdown("---")
121
+ gr.Markdown("[APIキーの取得はこちら(無料)](https://aistudio.google.com/app/apikey)")
122
+
123
+ # 実行ログ兼レポート表示エリア
124
+ status_log = gr.Textbox(
125
+ label="実行ログおよび詳細レポート",
126
+ lines=30,
127
+ interactive=False,
128
+ show_copy_button=True
129
+ )
130
+
131
+ # ボタンクリック時の動作
132
+ start_btn.click(
133
+ fn=run_insight_process,
134
+ inputs=[api_input],
135
+ outputs=status_log
136
+ )
137
+
138
+ # アプリの起動
139
+ if __name__ == "__main__":
140
+ demo.launch()