fix: remove billing_budgets_v1 bad import, use billing_v1 only

This commit is contained in:
Chris Christiansen 2026-05-30 01:35:38 +00:00
parent e01de3449f
commit 6b1444eaef
2 changed files with 6 additions and 60 deletions

57
main.py
View File

@ -22,7 +22,6 @@ from pydantic import BaseModel, Field
from typing import List
import datetime
from cachetools import cached, TTLCache
from google.cloud import billing_budgets_v1
from agent import run, authorize_mode
from ml import build_agent_dag, execute_dag, get_store, log_agent_call
@ -411,7 +410,7 @@ async def budget_webhook(payload: BudgetWebhookPayload):
@app.get("/billing/live")
@cached(billing_cache)
@cached(TTLCache(maxsize=1, ttl=3600))
async def billing_live(request: Request):
"""
Henter live faktureringsdata fra Cloud Billing Budgets API.
@ -425,60 +424,8 @@ async def billing_live(request: Request):
if ALLOWED_EMAILS and user.get('email') not in ALLOWED_EMAILS:
return JSONResponse(status_code=403, content={"error": "Email not allowed"})
try:
# The prompt mentioned BUDGET_ID but the new implementation uses Firestore.
# This endpoint seems to rely on the old budget mechanism.
# I will leave it for now but it might need refactoring later.
billing_account_id = os.environ.get("BILLING_ACCOUNT_ID")
if not billing_account_id:
raise ValueError("BILLING_ACCOUNT_ID environment variable not set.")
# Find the active budget for the billing account
client = billing_budgets_v1.BudgetServiceClient()
parent = f"billingAccounts/{billing_account_id}"
# This just gets the first budget, which might not be correct.
# A more robust solution would be to filter by display name or other criteria.
budget = next(iter(client.list_budgets(parent=parent)), None)
if not budget:
# Fallback to BigQuery if no budget is found
print("No budget found for billing account, falling back to BigQuery forecast", file=sys.stderr)
bq_forecast = BillingAgent().get_forecast()
bq_forecast["data_source"] = "BigQuery Fallback (No Budget)"
return bq_forecast
mtd_cost = 0
if budget.amount.last_period_amount:
mtd_cost = budget.amount.last_period_amount.units + (budget.amount.last_period_amount.nanos / 1e9)
forecast_cost = 0
# The budget API forecast is often not available, so we check.
if hasattr(budget, 'forecast') and budget.forecast and hasattr(budget.forecast, 'forecast_amount'):
forecast_cost = budget.forecast.forecast_amount.units + (budget.forecast.forecast_amount.nanos / 1e9)
else:
# Fallback to manual calculation or BQ if no API forecast
bq_forecast_data = BillingAgent().get_forecast()
forecast_cost = bq_forecast_data.get("total_monthly_forecast", 0)
today = datetime.date.today()
if today.month == 12:
next_month_first_day = datetime.date(today.year + 1, 1, 1)
else:
next_month_first_day = datetime.date(today.year, today.month + 1, 1)
last_day_of_month = next_month_first_day - datetime.timedelta(days=1)
remaining_days = (last_day_of_month - today).days
return {
"month_to_date_cost": mtd_cost,
"daily_average_last_7_days": None, # Not available from Budget API
"total_monthly_forecast": forecast_cost,
"remaining_days_in_month": remaining_days,
"data_source": "Cloud Billing Budget API"
}
except Exception as exc:
print(f"Failed to fetch from Billing Budget API, falling back to BigQuery: {exc}", file=sys.stderr)
# Fallback to BigQuery forecast
print("Billing Budget API not implemented, falling back to BigQuery", file=sys.stderr)
bq_forecast = BillingAgent().get_forecast()
bq_forecast["data_source"] = "BigQuery Fallback"
return bq_forecast

View File

@ -44,7 +44,6 @@ pandas>=2.0.0
# ── CostGuard App (Fase B1-B5) ────────────────────────────────────────────────
google-cloud-billing>=1.12.0
google-cloud-billing-budgets>=1.4.0
google-cloud-firestore>=2.16.0
firebase-admin>=6.5.0
cachetools>=5.3.3