{
  "output": "Successfully created and wrote to new file: /Users/bob/git/dxw/aws-stuff/audits/storage.py. Here is the updated code:\nimport boto3\nimport calendar\nfrom datetime import datetime, timedelta\nfrom botocore.exceptions import ClientError\nfrom aws_utils import (\n    get_account_names,\n    get_previous_month_range,\n    get_boto_session,\n    export_to_sheets,\n)\n\ndef fetch_storage(ce_client, start_date, end_date, all_accounts, hours_in_month):\n    \"\"\"\n    Fetches storage usage grouped by account.\n    Returns a dict: { account_id: total_gb }\n    \"\"\"\n    account_storage_totals = {acc_id: 0.0 for acc_id in all_accounts.keys()}\n    next_token = None\n\n    try:\n        while True:\n            params = {\n                \"TimePeriod\": {\"Start\": start_date, \"End\": end_date},\n                \"Granularity\": \"MONTHLY\",\n                \"Metrics\": [\"UsageQuantity\"],\n                \"GroupBy\": [\n                    {\"Type\": \"DIMENSION\", \"Key\": \"LINKED_ACCOUNT\"},\n                    {\"Type\": \"DIMENSION\", \"Key\": \"USAGE_TYPE\"},\n                ],\n                \"Filter\": {\n                    \"Dimensions\": {\n                        \"Key\": \"USAGE_TYPE_GROUP\",\n                        \"Values\": [\n                            \"S3: Storage - Standard\",\n                            \"S3: Storage - Infinite Archive\",\n                            \"EC2: EBS - Optimized Storage\",\n                            \"RDS: Storage\",\n                            \"EFS: Storage - Standard\",\n                            \"EFS: Storage - IA\",\n                            \"EFS: Storage - Archive\",\n                        ],\n                    }\n                },\n            }\n            if next_token:\n                params[\"NextPageToken\"] = next_token\n\n            response = ce_client.get_cost_and_usage(**params)\n\n            for result in response.get(\"ResultsByTime\", []):\n                for group in result.get(\"Groups\", []):\n                    acc_id = group[\"Keys\"][0]\n                    usage_amount = float(group[\"Metrics\"][\"UsageQuantity\"][\"Amount\"])\n                    unit = group[\"Metrics\"][\"UsageQuantity\"][\"Unit\"]\n\n                    if unit == \"ByteHrs\":\n                        usage_amount = (usage_amount / (1024**3)) / hours_in_month\n                    elif unit in [\"MB-Mo\", \"Megabyte-Months\"]:\n                        usage_amount /= 1024\n\n                    if acc_id in account_storage_totals:\n                        account_storage_totals[acc_id] += usage_amount\n\n            next_token = response.get(\"NextPageToken\")\n            if not next_token:\n                break\n    except ClientError as e:\n        print(f\"Error fetching storage: {e}\")\n        \n    return account_storage_totals\n\ndef run():\n    threshold_gb = 100.0\n    session = get_boto_session()\n    ce_client = session.client(\"ce\")\n    all_accounts = get_account_names()\n    start_date, end_date = get_previous_month_range()\n\n    # Calculate hours in the previous month for Byte-Hour conversion\n    dt_end = datetime.strptime(end_date, \"%Y-%m-%d\")\n    last_day_prev = dt_end - timedelta(days=1)\n    _, num_days = calendar.monthrange(last_day_prev.year, last_day_prev.month)\n    hours_in_month = num_days * 24\n\n    account_storage_totals = fetch_storage(ce_client, start_date, end_date, all_accounts, hours_in_month)\n\n    print(f\"\\n--- Storage Report ({start_date} to {end_date}) ---\")\n    print(f\"{'Account Name':<25} | {'Storage (GB)':<12} | {'Overage (>100GB)'}\")\n    print(\"-\" * 75)\n\n    rows = []\n    sorted_accounts = sorted(\n        account_storage_totals.items(), key=lambda x: x[1], reverse=True\n    )\n    for acc_id, total_gb in sorted_accounts:\n        acc_name = all_accounts.get(acc_id, acc_id)\n        overage = max(0, total_gb - threshold_gb)\n        status_icon = \"⚠️\" if overage > 0 else \"✅\"\n        print(\n            f\"{acc_name[:25]:<25} | {total_gb:>10.2f} GB | {overage:>8.2f} GB {status_icon}\"\n        )\n        rows.append([acc_name, acc_id, round(total_gb, 2), round(overage, 2)])\n\n    headers = [\n        \"Account Name\",\n        \"Account ID\",\n        f\"Storage GB ({start_date})\",\n        \"Overage (>100GB)\",\n    ]\n    export_to_sheets(\"AWS_Storage_Usage\", headers, rows)\n\nif __name__ == \"__main__\":\n    run()\n"
}