TradingAgents/docs/011_Reddit_CLI_Commands_Imp...

6.7 KiB
Raw Blame History

チケット #011: Reddit CLIコマンド実装typer使用

概要

Reddit データ取得のためのCLIコマンドインターフェースのtyperを使用した実装

目的

  • 対話形式での過去データ取得
  • 日次更新コマンド
  • データ状況の確認機能
  • 既存CLIフレームワークtyperとの統合

実装要件

1. コマンド構造

cli/
├── main.py          # 既存のtyperアプリ
└── commands/
    └── reddit.py    # Redditコマンド実装

2. typerコマンド統合

# cli/main.py への統合
from cli.commands import reddit

# 既存のappにサブコマンドを追加
app.add_typer(reddit.app, name="reddit", help="Reddit data management")

3. Redditコマンド実装

# cli/commands/reddit.py
import typer
from rich.console import Console
import questionary

app = typer.Typer()
console = Console()

@app.command()
def fetch_historical(
    interactive: bool = typer.Option(True, "--interactive/--no-interactive",
                                    help="Use interactive mode for configuration")
):
    """Fetch historical Reddit data"""
    if interactive:
        # 対話形式
        config = interactive_configuration()
    else:
        # オプション指定
        config = parse_command_options()
    
    fetcher = create_reddit_fetcher(config)
    fetcher.run()

4. 対話形式の実装questionary使用

def interactive_configuration():
    """
    対話形式でデータ取得設定を行う
    既存のquestionaryを活用
    """
    console = Console()
    
    # カテゴリ選択
    category = questionary.select(
        "Which category?",
        choices=["global_news", "company_news", "both"]
    ).ask()
    
    # 期間選択(推奨期間の表示付き)
    date_range = interactive_date_range_selection()
    
    # ティッカー選択(プリセット対応)
    if category in ["company_news", "both"]:
        tickers = interactive_ticker_selection()
    
    # 確認と実行
    if confirm_execution(category, date_range, tickers):
        return build_config(category, date_range, tickers)

4. ティッカー選択インターフェース

def interactive_ticker_selection():
    """
    デフォルトTickerリストから選択
    """
    choice = questionary.select(
        "Select ticker preset or enter custom:",
        choices=[
            "1. Popular Tech Stocks (15 tickers)",
            "2. S&P 500 Top 20",
            "3. Global Indices (22 ETFs)",  # 日経225追加済み
            "4. All Combined (50+ tickers)",
            "5. Quick Test (5 tickers)",
            "6. Custom (enter your own)"
        ]
    ).ask()
    
    if choice.startswith("6"):
        # カスタム入力
        custom = questionary.text(
            "Enter tickers (comma-separated):"
        ).ask()
        return parse_custom_tickers(custom)
    else:
        # プリセット使用
        return get_preset_tickers(choice)

5. 日次更新コマンド

@app.command()
def update(
    date: str = typer.Option('yesterday', help='Date to fetch (YYYY-MM-DD or "yesterday")'),
    auto: bool = typer.Option(False, help='Run in automatic mode (no prompts)')
):
    """Update Reddit data for specific date"""
    
    if date == 'yesterday':
        target_date = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
    else:
        target_date = validate_date(date)
    
    if auto:
        # 設定ファイルから自動実行
        config = load_auto_config()
    else:
        # 確認プロンプト表示
        if not click.confirm(f"Fetch data for {target_date}?"):
            return
    
    execute_update(target_date, config)

6. ステータス確認コマンド

@app.command()
def status(
    start: str = typer.Option(None, help='Start date (YYYY-MM-DD)'),
    end: str = typer.Option(None, help='End date (YYYY-MM-DD)'),
    category: str = typer.Option('all', help='Category to check')
):
    """Check Reddit data cache status"""
    
    cache_manager = RedditCacheManager(get_reddit_data_dir())
    
    # データ可用性の表示
    table = Table(title="Reddit Data Status")
    table.add_column("Date", style="cyan")
    table.add_column("Global News", style="green")
    table.add_column("Company News", style="yellow")
    table.add_column("Total Posts", style="magenta")
    
    # 統計情報の表示
    display_cache_statistics(cache_manager, start, end, category)

7. データ検証コマンド

@app.command()
def verify(
    start: str = typer.Argument(..., help='Start date'),
    end: str = typer.Argument(..., help='End date'),
    fix: bool = typer.Option(False, help='Attempt to fix issues')
):
    """Verify data integrity and completeness"""
    
    validator = RedditDataValidator()
    issues = validator.check_period(start, end)
    
    if issues['missing_dates']:
        console.print("[yellow]Missing dates found:[/yellow]")
        for date in issues['missing_dates']:
            console.print(f"  - {date}")
    
    if fix and issues['missing_dates']:
        if click.confirm("Fetch missing data?"):
            fetch_missing_data(issues['missing_dates'])

8. プログレス表示

def show_fetch_progress(total_requests: int):
    """
    取得進捗の表示
    """
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        BarColumn(),
        TaskProgressColumn(),
        TimeRemainingColumn(),
    ) as progress:
        task = progress.add_task("Fetching Reddit data...", total=total_requests)
        yield progress, task

受け入れ条件

  • 対話形式での直感的な操作
  • デフォルトTickerリストの選択機能
  • 日次更新の自動実行対応
  • 進捗表示とエラーハンドリング
  • データ状況の可視化
  • typer CLIフレームワークとの統合
  • 単体テストの実装(モック使用)
  • USE_PRAW_APIフラグでの切り替え

依存関係

  • typer既存CLIフレームワーク
  • richTUI表示
  • questionary対話形式入力
  • RedditDataFetcherチケット#009
  • RedditCacheManagerチケット#010

タスク

  • 単体テストの作成TDD
  • reddit.pyコマンドモジュールの作成
  • typerアプリへの統合
  • fetch-historicalコマンド実装
  • 対話形式インターフェース
  • デフォルトTickerリスト選択機能
  • updateコマンド実装
  • statusコマンド実装
  • verifyコマンド実装
  • プログレス表示機能
  • エラーハンドリング
  • ヘルプメッセージの充実
  • 段階的実装フラグのテスト
  • 統合テスト