Spaces:
Running
Running
| """Spend tracker β summarize this billing cycle's Modal spend for `make status`. | |
| Reads `modal billing report --json` (usage line items) and sums their cost, then | |
| frames it against the configured spend limit and credit budget so the $280 (expiry | |
| Jun 30) draws down visibly instead of by guesswork. | |
| The Modal billing report exposes *spend*, not the credit balance, so the credit | |
| total and spend limit are passed in via env (set in .env / Makefile): | |
| CREDIT_BUDGET total credits in the workspace (default 280) | |
| SPEND_LIMIT the hard cap you set in the dashboard (default 50) | |
| """ | |
| from __future__ import annotations | |
| import os | |
| import json | |
| import subprocess | |
| def _spend_this_month() -> float | None: | |
| try: | |
| out = subprocess.run( | |
| ["modal", "billing", "report", "--for", "this month", "--json"], | |
| capture_output=True, text=True, timeout=30, | |
| ) | |
| if out.returncode != 0: | |
| return None | |
| items = json.loads(out.stdout or "[]") | |
| except Exception: | |
| return None | |
| total = 0.0 | |
| for it in items if isinstance(items, list) else []: | |
| # Be tolerant of the line-item schema: sum any plausible cost field. | |
| for k in ("cost", "amount", "total", "cost_usd"): | |
| v = it.get(k) if isinstance(it, dict) else None | |
| if isinstance(v, (int, float)): | |
| total += float(v) | |
| break | |
| return total | |
| def main() -> None: | |
| budget = float(os.environ.get("CREDIT_BUDGET", "280")) | |
| limit = float(os.environ.get("SPEND_LIMIT", "50")) | |
| spent = _spend_this_month() | |
| if spent is None: | |
| print("credits: (could not read billing report)") | |
| return | |
| bar_n = 20 | |
| frac = min(1.0, spent / limit) if limit > 0 else 0.0 | |
| bar = "β" * int(frac * bar_n) + "β" * (bar_n - int(frac * bar_n)) | |
| warn = " β οΈ NEAR LIMIT" if frac >= 0.8 else "" | |
| print(f"spent this cycle: ${spent:,.2f} / ${limit:,.0f} limit [{bar}]{warn}") | |
| print(f"credits: ${budget:,.0f} total (expire Jun 30) Β· ${max(0, budget - spent):,.2f} left") | |
| if __name__ == "__main__": | |
| main() | |