{
  "output": "import boto3\nimport calendar\nfrom datetime import datetime, timedelta\nfrom aws_utils import (\n    get_account_names,\n    get_previous_month_range,\n    get_boto_session,\n    export_to_sheets,\n)\n\n\ndef get_storage_report(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 = {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[\"ResultsByTime\"]:\n                for group in result[\"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\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\n    except Exception as e:\n        print(f\"Error: {e}\")\n\n\nif __name__ == \"__main__\":\n    get_storage_report(100.0)\n"
}