cstats-core 0.1.1

Core library for cstats - statistical analysis and metrics collection
Documentation
//! Example usage of the Anthropic API client for fetching Claude Code usage statistics
//!
//! To run this example:
//! 1. Set the ANTHROPIC_API_KEY environment variable
//! 2. Run: cargo run --example anthropic_api_example

use cstats_core::api::ApiClient;
use std::env;

#[tokio::main]
async fn main() -> cstats_core::Result<()> {
    // Initialize tracing for debug output
    tracing_subscriber::fmt::init();

    println!("Claude Code Usage Statistics Example");
    println!("=====================================");

    // Check if API key is set
    if env::var("ANTHROPIC_API_KEY").is_err() {
        println!("Error: ANTHROPIC_API_KEY environment variable not set");
        println!("Please set your Anthropic API key to run this example:");
        println!("export ANTHROPIC_API_KEY=\"your-api-key-here\"");
        return Ok(());
    }

    // Create client from environment variables with caching enabled
    match ApiClient::from_env_with_cache().await {
        Ok(client) => {
            println!("✅ Successfully created API client with caching enabled");

            // Enable local usage tracking for demonstration
            if let Some(anthropic_client) = client.anthropic() {
                if let Some(tracker) = anthropic_client.usage_tracker() {
                    // Record some example API calls for demonstration
                    let _ = tracker
                        .record_call(
                            "claude-3-haiku-20240307",
                            1000,
                            500,
                            1200,
                            true,
                            Some("demo-request-1".to_string()),
                        )
                        .await;

                    let _ = tracker
                        .record_call(
                            "claude-3-sonnet-20240229",
                            2000,
                            1000,
                            1800,
                            true,
                            Some("demo-request-2".to_string()),
                        )
                        .await;

                    println!("✅ Local usage tracking enabled with demo data");
                } else {
                    println!("ℹ️  Local usage tracking not enabled");
                }
            }

            // Check if Anthropic client is configured
            if let Some(anthropic_client) = client.anthropic() {
                println!("✅ Anthropic API client is configured");

                // Test API connectivity
                match anthropic_client.health_check().await {
                    Ok(true) => println!("✅ API health check passed"),
                    Ok(false) => println!("❌ API health check failed"),
                    Err(e) => println!("⚠️  Could not perform health check: {}", e),
                }

                // Fetch rate limit information
                println!("\n📊 Fetching Rate Limit Information:");
                match client.fetch_rate_limit_info().await {
                    Ok(rate_limit) => {
                        println!(
                            "  Requests per minute limit: {}",
                            rate_limit.requests_per_minute
                        );
                        println!("  Requests remaining: {}", rate_limit.requests_remaining);
                        println!("  Reset time: {:?}", rate_limit.reset_time);
                        if let Some(tpm) = rate_limit.tokens_per_minute {
                            println!("  Tokens per minute limit: {}", tpm);
                        }
                        if let Some(remaining) = rate_limit.tokens_remaining {
                            println!("  Tokens remaining: {}", remaining);
                        }
                    }
                    Err(e) => println!("  ❌ Failed to fetch rate limit info: {}", e),
                }

                // Fetch usage stats for different periods
                println!("\n📈 Fetching Usage Statistics:");

                // Daily stats
                match client.fetch_daily_usage_stats().await {
                    Ok(daily_stats) => {
                        println!("  📅 Daily Usage (Last 24 hours):");
                        print_usage_stats(&daily_stats, "    ");
                    }
                    Err(e) => println!("  ❌ Failed to fetch daily usage stats: {}", e),
                }

                // Weekly stats
                match client.fetch_weekly_usage_stats().await {
                    Ok(weekly_stats) => {
                        println!("  📅 Weekly Usage (Last 7 days):");
                        print_usage_stats(&weekly_stats, "    ");
                    }
                    Err(e) => println!("  ❌ Failed to fetch weekly usage stats: {}", e),
                }

                // Monthly stats
                match client.fetch_monthly_usage_stats().await {
                    Ok(monthly_stats) => {
                        println!("  📅 Monthly Usage (Last 30 days):");
                        print_usage_stats(&monthly_stats, "    ");
                    }
                    Err(e) => println!("  ❌ Failed to fetch monthly usage stats: {}", e),
                }

                // Current month billing
                println!("\n💰 Fetching Billing Information:");
                match client.fetch_current_month_billing().await {
                    Ok(billing) => {
                        println!("  Current month total cost: ${:.4}", billing.total_cost_usd);
                        println!(
                            "  Estimated monthly cost: ${:.4}",
                            billing.estimated_monthly_cost_usd
                        );

                        if !billing.by_model.is_empty() {
                            println!("  Cost breakdown by model:");
                            for (model, cost) in billing.by_model.iter() {
                                println!(
                                    "    {}: ${:.4} (input: ${:.4}, output: ${:.4})",
                                    model, cost.cost_usd, cost.input_cost_usd, cost.output_cost_usd
                                );
                            }
                        }
                    }
                    Err(e) => println!("  ❌ Failed to fetch billing info: {}", e),
                }

                // Comprehensive usage summary
                println!("\n📊 Comprehensive Usage Summary:");
                match client.get_usage_summary().await {
                    Ok(summary) => {
                        println!("  Generated at: {}", summary.timestamp);
                        println!("  ");
                        println!("  Token Usage Comparison:");
                        println!(
                            "    Daily:   {:>10} tokens",
                            summary.daily.token_usage.total_tokens
                        );
                        println!(
                            "    Weekly:  {:>10} tokens",
                            summary.weekly.token_usage.total_tokens
                        );
                        println!(
                            "    Monthly: {:>10} tokens",
                            summary.monthly.token_usage.total_tokens
                        );
                        println!("  ");
                        println!("  API Call Comparison:");
                        println!(
                            "    Daily:   {:>10} calls",
                            summary.daily.api_calls.total_calls
                        );
                        println!(
                            "    Weekly:  {:>10} calls",
                            summary.weekly.api_calls.total_calls
                        );
                        println!(
                            "    Monthly: {:>10} calls",
                            summary.monthly.api_calls.total_calls
                        );
                        println!("  ");
                        println!("  Cost Comparison:");
                        println!("    Daily:   ${:>9.4}", summary.daily.costs.total_cost_usd);
                        println!("    Weekly:  ${:>9.4}", summary.weekly.costs.total_cost_usd);
                        println!(
                            "    Monthly: ${:>9.4}",
                            summary.monthly.costs.total_cost_usd
                        );
                    }
                    Err(e) => println!("  ❌ Failed to fetch usage summary: {}", e),
                }
            } else {
                println!("❌ Anthropic API not configured in the client");
            }
        }
        Err(e) => {
            println!("❌ Failed to create API client: {}", e);
        }
    }

    println!("\n✨ Example completed!");
    Ok(())
}

/// Helper function to print usage statistics
fn print_usage_stats(stats: &cstats_core::api::AnthropicUsageStats, indent: &str) {
    println!("{}Total tokens: {}", indent, stats.token_usage.total_tokens);
    println!("{}Input tokens: {}", indent, stats.token_usage.input_tokens);
    println!(
        "{}Output tokens: {}",
        indent, stats.token_usage.output_tokens
    );
    println!("{}Total API calls: {}", indent, stats.api_calls.total_calls);
    println!(
        "{}Successful calls: {}",
        indent, stats.api_calls.successful_calls
    );
    println!("{}Failed calls: {}", indent, stats.api_calls.failed_calls);
    println!(
        "{}Success rate: {:.2}%",
        indent,
        (stats.api_calls.successful_calls as f64 / stats.api_calls.total_calls.max(1) as f64)
            * 100.0
    );
    println!(
        "{}Average response time: {:.2}ms",
        indent, stats.api_calls.avg_response_time_ms
    );
    println!("{}Total cost: ${:.4}", indent, stats.costs.total_cost_usd);

    if !stats.model_usage.is_empty() {
        println!("{}Model breakdown:", indent);
        for model in &stats.model_usage {
            println!(
                "{}  {}: {} requests, {} tokens, ${:.4}",
                indent, model.model, model.requests, model.tokens.total_tokens, model.cost.cost_usd
            );
        }
    }

    println!(); // Empty line for spacing
}