| import gradio as gr |
| from google import genai |
| import time |
| import os |
|
|
| |
| from news_collector import fetch_rss_news |
| from ai_analyst import analyze_news |
|
|
| def run_insight_process(api_key): |
| """ |
| ニュース取得から解析までを順次実行し、ログをリアルタイムで画面に返す関数 |
| """ |
| if not api_key or len(api_key) < 10: |
| yield "❌ エラー: 有効なGemini APIキーをサイドバーに入力してください。" |
| return |
|
|
| |
| |
|
|
| log_output = "🚀 投資インサイト解析を開始します...\n" |
| yield log_output |
|
|
| try: |
| |
| log_output += "📡 ニュースサイトから最新記事を収集中...\n" |
| yield log_output |
| articles = fetch_rss_news() |
| |
| if not articles: |
| yield log_output + "❌ ニュースの取得に失敗したか、記事が見つかりませんでした。" |
| return |
|
|
| log_output += f"✅ {len(articles)}件のニュースを取得しました。上位5件を解析します。\n\n" |
| yield log_output |
|
|
| |
| top_articles = articles[:5] |
| for i, article in enumerate(top_articles): |
| log_output += f"🔍 解析中 ({i+1}/{len(top_articles)}): {article['title']}\n" |
| yield log_output |
| |
| |
| try: |
| res = analyze_news(article, api_key) |
| |
| |
| try: |
| score = int(res.get('market_impact_score', 0)) |
| except: |
| score = 0 |
| |
| |
| if score > 0: |
| score_display = f"+{score}" |
| icon = "📈" |
| elif score < 0: |
| score_display = f"{score}" |
| icon = "📉" |
| else: |
| score_display = "0" |
| icon = "➖" |
|
|
| |
| report = f"===== 【分析結果】 {icon} スコア: {score_display} / 10 =====\n" |
| report += f"■ 歴史的類似性:\n{res.get('historical_precedent', '情報なし')}\n\n" |
| |
| |
| report += f"■ 警戒すべきリスク/弱気視点:\n" |
| bearish = res.get('bearish_view', []) |
| if isinstance(bearish, list): |
| for r in bearish: |
| report += f" ・{str(r)}\n" |
| else: |
| report += f" ・{str(bearish)}\n" |
|
|
| |
| report += f"\n■ 影響セクター:\n" |
| sectors = res.get('sector_impact', []) |
| if isinstance(sectors, list): |
| report += f"{', '.join([str(s) for s in sectors])}\n" |
| else: |
| report += f"{str(sectors)}\n" |
| |
| report += "==========================================\n\n" |
| |
| log_output += report |
| yield log_output |
|
|
| except Exception as e: |
| log_output += f"⚠️ この記事の解析中にエラーが発生しました: {str(e)}\n\n" |
| yield log_output |
| |
| |
| if i < len(top_articles) - 1: |
| time.sleep(2) |
|
|
| log_output += "🎉 すべての解析作業が完了しました。" |
| yield log_output |
|
|
| except Exception as e: |
| yield log_output + f"\n❌ システムエラーが発生しました: {str(e)}" |
|
|
| |
| with gr.Blocks() as demo: |
| gr.Markdown(""" |
| # 📈 AI投資インサイト・アナライザー |
| 最新の経済ニュースを取得し、Gemini 2.5 Flashが投資判断を21段階でスコアリングします。 |
| """) |
| |
| with gr.Sidebar(): |
| gr.Markdown("### 設定") |
| api_input = gr.Textbox( |
| label="1. Gemini API Key", |
| type="password", |
| placeholder="AI Studioのキーを貼り付け" |
| ) |
| start_btn = gr.Button("解析実行", variant="primary") |
| gr.Markdown("---") |
| gr.Markdown("[APIキーの取得はこちら(無料)](https://aistudio.google.com/app/apikey)") |
| |
| |
| status_log = gr.Textbox( |
| label="実行ログおよび詳細レポート", |
| lines=30, |
| interactive=False |
| ) |
|
|
| |
| start_btn.click( |
| fn=run_insight_process, |
| inputs=[api_input], |
| outputs=status_log |
| ) |
|
|
| |
| if __name__ == "__main__": |
| demo.launch(theme=gr.themes.Soft()) |