#!/usr/bin/env python3 """ Compare costs from three different sources by daily breakdown. This script compares: 1. analytics.json - Cost data from Analytics API (in cents) 2. costs.json - Cost data from Usage API (in dollars) 3. cost_report.json - Direct cost data from Cost Report API (in dollars) It aggregates costs by date and identifies days with >$5 differences. """ import json from collections import defaultdict from pathlib import Path from typing import Any def load_json(file_path: Path) -> dict[str, Any]: """Load a JSON file.""" with open(file_path) as f: return json.load(f) def aggregate_analytics_costs(data: dict[str, Any]) -> dict[str, float]: """ Aggregate costs from analytics.json by date. Structure: actors[].time_periods[] with period_cost_cents Cost is in cents, convert to dollars. """ daily_costs: dict[str, float] = defaultdict(float) for actor in data.get('actors', []): for period in actor.get('time_periods', []): date = period.get('time_period') cost_cents = period.get('period_cost_cents', 0) if date: daily_costs[date] += cost_cents / 100.0 return dict(daily_costs) def aggregate_usage_costs(data: dict[str, Any]) -> dict[str, float]: """ Aggregate costs from costs.json (Usage API) by date. Structure: api_keys[].time_periods[] with period_cost Cost is already in dollars. """ daily_costs: dict[str, float] = defaultdict(float) for api_key in data.get('api_keys', []): for period in api_key.get('time_periods', []): date = period.get('time_period') cost = period.get('period_cost', 0) if date: daily_costs[date] += cost return dict(daily_costs) def aggregate_cost_report_costs(data: dict[str, Any]) -> dict[str, float]: """ Aggregate costs from cost_report.json by date. Structure: workspaces[].time_periods[] with cost Sum costs across ALL workspaces for each date. Date is extracted from starting_at field (ISO format). Cost is in cents, convert to dollars. """ daily_costs: dict[str, float] = defaultdict(float) workspaces = data.get('workspaces', {}) for workspace_id, workspace_data in workspaces.items(): for period in workspace_data.get('time_periods', []): starting_at = period.get('starting_at') cost_cents = period.get('cost', 0) if starting_at: # Extract date from ISO timestamp (YYYY-MM-DD) date = starting_at.split('T')[0] # Cost is in cents, convert to dollars daily_costs[date] += cost_cents / 100.0 return dict(daily_costs) def compare_costs( analytics_costs: dict[str, float], usage_costs: dict[str, float], cost_report_costs: dict[str, float], threshold: float = 5.0, ) -> dict[str, Any]: """ Compare costs across the three sources and identify significant differences. Args: analytics_costs: Daily costs from analytics API usage_costs: Daily costs from usage API cost_report_costs: Daily costs from cost report API threshold: Dollar threshold for flagging differences Returns: Dictionary with comparison results """ # Get all unique dates all_dates = set(analytics_costs.keys()) | set(usage_costs.keys()) | set(cost_report_costs.keys()) differences = [] days_with_significant_diff = 0 for date in sorted(all_dates): analytics_cost = analytics_costs.get(date, 0.0) usage_cost = usage_costs.get(date, 0.0) cost_report_cost = cost_report_costs.get(date, 0.0) # Calculate differences between each pair diff_analytics_usage = abs(analytics_cost - usage_cost) diff_analytics_cost_report = abs(analytics_cost - cost_report_cost) diff_usage_cost_report = abs(usage_cost - cost_report_cost) # Check if any difference exceeds threshold has_significant_diff = diff_analytics_usage > threshold or diff_analytics_cost_report > threshold or diff_usage_cost_report > threshold if has_significant_diff: days_with_significant_diff += 1 differences.append( { 'date': date, 'analytics_cost': round(analytics_cost, 2), 'usage_cost': round(usage_cost, 2), 'cost_report_cost': round(cost_report_cost, 2), 'diff_analytics_usage': round(diff_analytics_usage, 2), 'diff_analytics_cost_report': round(diff_analytics_cost_report, 2), 'diff_usage_cost_report': round(diff_usage_cost_report, 2), 'has_significant_difference': has_significant_diff, } ) return { 'differences': differences, 'summary': { 'total_days_compared': len(all_dates), 'days_with_differences_over_threshold': days_with_significant_diff, 'threshold_dollars': threshold, }, } def main() -> None: """Main entry point.""" # Define paths project_root = Path(__file__).parent.parent.parent analytics_path = project_root / 'output' / 'analytics' / 'analytics.json' usage_path = project_root / 'output' / 'usage' / 'costs.json' cost_report_path = project_root / 'output' / 'cost_report' / 'cost_report.json' output_path = project_root / 'output' / 'debug' / 'differences.json' # Create output directory output_path.parent.mkdir(parents=True, exist_ok=True) print('Loading data files...') analytics_data = load_json(analytics_path) usage_data = load_json(usage_path) cost_report_data = load_json(cost_report_path) print('Aggregating costs by date...') analytics_costs = aggregate_analytics_costs(analytics_data) usage_costs = aggregate_usage_costs(usage_data) cost_report_costs = aggregate_cost_report_costs(cost_report_data) print(f' Analytics: {len(analytics_costs)} days') print(f' Usage: {len(usage_costs)} days') print(f' Cost Report: {len(cost_report_costs)} days') print('\nComparing costs...') results = compare_costs(analytics_costs, usage_costs, cost_report_costs, 5) # Save results with open(output_path, 'w') as f: json.dump(results, f, indent=2) print(f'\nResults saved to: {output_path}') print('\nSummary:') print(f' Total days compared: {results["summary"]["total_days_compared"]}') print(f' Days with differences >${results["summary"]["threshold_dollars"]}: {results["summary"]["days_with_differences_over_threshold"]}') # Show a few examples of significant differences significant_diffs = [d for d in results['differences'] if d['has_significant_difference']] if significant_diffs: print('\nFirst 5 days with significant differences:') for diff in significant_diffs[:5]: print(f'\n {diff["date"]}:') print(f' Analytics: ${diff["analytics_cost"]:.2f}') print(f' Usage: ${diff["usage_cost"]:.2f}') print(f' Cost Rpt: ${diff["cost_report_cost"]:.2f}') print(f' Max diff: ${max(diff["diff_analytics_usage"], diff["diff_analytics_cost_report"], diff["diff_usage_cost_report"]):.2f}') if __name__ == '__main__': main()