Skip to content

Commit

Permalink
remove unit, exclude private offer
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Jan 30, 2026
1 parent a48c788 commit 08d8eee
Showing 1 changed file with 14 additions and 26 deletions.
40 changes: 14 additions & 26 deletions local-app/python-tools/billing/aws_monthly_cost.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,19 @@
from botocore.exceptions import ClientError, ProfileNotFound
from dateutil.parser import parse

__version__ = "1.0.2"
__version__ = "1.0.3"

def get_monthly_range(date_str=None):
"""
Parses a date string and returns the first day of that month
and the first day of the following month.
"""
if date_str:
try:
target_date = parse(date_str).date()
except ValueError:
except (ValueError, TypeError):
print(f"❌ Error: Could not parse date '{date_str}'. Use YYYY-MM or YYYY-MM-DD.")
sys.exit(1)
else:
target_date = datetime.date.today()

# Start of the month for the provided date
start = target_date.replace(day=1)

# Start of the next month
if start.month == 12:
end = start.replace(year=start.year + 1, month=1)
else:
Expand All @@ -43,8 +36,7 @@ def fetch_aws_costs(profile, region, date_arg):
start_date, end_date = get_monthly_range(date_arg)

print(f"--- AWS Monthly Cost Summary v{__version__} ---")
print(f"Profile: {profile or 'default'}")
print(f"Period: {start_date} to {end_date}\n")
print(f"Period: {start_date} to {end_date}\n")

response = client.get_cost_and_usage(
TimePeriod={'Start': start_date, 'End': end_date},
Expand All @@ -61,42 +53,38 @@ def fetch_aws_costs(profile, region, date_arg):
m = group['Metrics']

qty = float(m['UsageQuantity']['Amount'])
unit = m['UsageQuantity']['Unit']
blended = float(m['BlendedCost']['Amount'])
unblended = float(m['UnblendedCost']['Amount'])
amortized = float(m['AmortizedCost']['Amount'])

rows.append([service_name, f"{qty:.2f}", unit, f"{blended:.2f}", f"{unblended:.2f}", f"{amortized:.2f}"])
rows.append([service_name, f"{qty:.2f}", f"{blended:.2f}", f"{unblended:.2f}", f"{amortized:.2f}"])

grand_totals['blended'] += blended
grand_totals['unblended'] += unblended
grand_totals['amortized'] += amortized

rows.sort(key=lambda x: float(x[5]), reverse=True)
rows.sort(key=lambda x: float(x[4]), reverse=True)

filename = f"aws_cost_{start_date[:7]}.csv"
with open(filename, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Service', 'Usage Quantity', 'Unit', 'Blended Cost', 'Unblended Cost', 'Total (Amortized)'])
writer.writerow(['Service', 'Usage Quantity', 'Blended Cost', 'Unblended Cost', 'Total (Amortized)'])
writer.writerows(rows)
writer.writerow(['GRAND TOTAL', 'NA', 'NA',
writer.writerow(['GRAND TOTAL', 'NA',
f"{grand_totals['blended']:.2f}",
f"{grand_totals['unblended']:.2f}",
f"{grand_totals['amortized']:.2f}"])

print(f"✅ Success! Report saved as: {filename}")
print(f"✅ Report saved: {filename}")

except ProfileNotFound:
print(f"❌ Error: Profile '{profile}' not found.")
except ClientError as e:
print(f"❌ AWS Error: {e}")
except Exception as e:
print(f"❌ Error: {e}")

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="AWS Monthly Cost to CSV")
parser.add_argument('date', nargs='?', help="Date in YYYY-MM or YYYY-MM-DD format (default: today)")
parser.add_argument('--profile', type=str, help="AWS CLI profile")
parser.add_argument('--region', type=str, default='us-east-1', help="AWS region")
parser = argparse.ArgumentParser()
parser.add_argument('date', nargs='?', help="YYYY-MM or YYYY-MM-DD")
parser.add_argument('--profile', type=str)
parser.add_argument('--region', type=str, default='us-east-1')
parser.add_argument('--version', action='version', version=f'%(prog)s {__version__}')

args = parser.parse_args()
fetch_aws_costs(args.profile, args.region, args.date)

0 comments on commit 08d8eee

Please sign in to comment.