{
  "output": "import boto3\nfrom aws_utils import get_account_names, get_last_n_months_ranges, get_boto_session\n\n\ndef get_cost_for_range(ce_client, start_date, end_date, account_costs):\n    \"\"\"Fetches costs for a date range and updates account_costs dictionary.\"\"\"\n    try:\n        response = ce_client.get_cost_and_usage(\n            TimePeriod={\"Start\": start_date, \"End\": end_date},\n            Granularity=\"MONTHLY\",\n            Metrics=[\"UnblendedCost\", \"AmortizedCost\"],\n            GroupBy=[{\"Type\": \"DIMENSION\", \"Key\": \"LINKED_ACCOUNT\"}],\n        )\n\n        for result in response[\"ResultsByTime\"]:\n            for group in result[\"Groups\"]:\n                account_id = group[\"Keys\"][0]\n                unblended = float(group[\"Metrics\"][\"UnblendedCost\"][\"Amount\"])\n                amortized = float(group[\"Metrics\"][\"AmortizedCost\"][\"Amount\"])\n\n                if account_id not in account_costs:\n                    account_costs[account_id] = {\"unblended\": [], \"amortized\": []}\n\n                account_costs[account_id][\"unblended\"].append(unblended)\n                account_costs[account_id][\"amortized\"].append(amortized)\n    except Exception as e:\n        print(f\"Error fetching cost for range {start_date} to {end_date}: {e}\")\n\n\ndef main():\n    session = get_boto_session()\n    ce_client = session.client(\"ce\")\n    account_names = get_account_names()\n    account_costs = {}\n\n    ranges = get_last_n_months_ranges(3)\n    months_labels = [r[2] for r in ranges]\n\n    for start_date, end_date, _ in ranges:\n        get_cost_for_range(ce_client, start_date, end_date, account_costs)\n\n    # Sort accounts by the most recent month's amortized cost\n    sorted_accounts = sorted(\n        account_costs.items(),\n        key=lambda item: item[1][\"amortized\"][0] if item[1][\"amortized\"] else 0,\n        reverse=True,\n    )\n\n    print(\n        f\"\\nAWS Costs for the last 3 months (Amortized and Unblended, sorted by highest Amortized Cost in {months_labels[0]}):\"\n    )\n    header = f\"{'Account Name':<30} {' ' + months_labels[0] + ' (Amort)':<15} {' ' + months_labels[1] + ' (Amort)':<15} {' ' + months_labels[2] + ' (Amort)':<15} {' ' + months_labels[0] + ' (Unbl)':<15} {' ' + months_labels[1] + ' (Unbl)':<15} {' ' + months_labels[2] + ' (Unbl)':<15}\"\n    print(header)\n    print(\"-\" * 125)\n\n    for account_id, costs in sorted_accounts:\n        name = account_names.get(account_id, f\"Unknown ({account_id})\")\n\n        # Ensure we have 3 months of data\n        amortized = costs[\"amortized\"] + [0.0] * (3 - len(costs[\"amortized\"]))\n        unblended = costs[\"unblended\"] + [0.0] * (3 - len(costs[\"unblended\"]))\n\n        amortized_fmt = [f\"${c:,.2f}\" for c in amortized[:3]]\n        unblended_fmt = [f\"${c:,.2f}\" for c in unblended[:3]]\n\n        print(\n            f\"{name[:30]:<30} {amortized_fmt[0]:>15} {amortized_fmt[1]:>15} {amortized_fmt[2]:>15} {unblended_fmt[0]:>15} {unblended_fmt[1]:>15} {unblended_fmt[2]:>15}\"\n        )\n\n\nif __name__ == \"__main__\":\n    main()\n"
}