fix: remove billing_budgets_v1 bad import, use billing_v1 only
This commit is contained in:
parent
e01de3449f
commit
6b1444eaef
65
main.py
65
main.py
|
|
@ -22,7 +22,6 @@ from pydantic import BaseModel, Field
|
||||||
from typing import List
|
from typing import List
|
||||||
import datetime
|
import datetime
|
||||||
from cachetools import cached, TTLCache
|
from cachetools import cached, TTLCache
|
||||||
from google.cloud import billing_budgets_v1
|
|
||||||
|
|
||||||
from agent import run, authorize_mode
|
from agent import run, authorize_mode
|
||||||
from ml import build_agent_dag, execute_dag, get_store, log_agent_call
|
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")
|
@app.get("/billing/live")
|
||||||
@cached(billing_cache)
|
@cached(TTLCache(maxsize=1, ttl=3600))
|
||||||
async def billing_live(request: Request):
|
async def billing_live(request: Request):
|
||||||
"""
|
"""
|
||||||
Henter live faktureringsdata fra Cloud Billing Budgets API.
|
Henter live faktureringsdata fra Cloud Billing Budgets API.
|
||||||
|
|
@ -425,63 +424,11 @@ async def billing_live(request: Request):
|
||||||
if ALLOWED_EMAILS and user.get('email') not in ALLOWED_EMAILS:
|
if ALLOWED_EMAILS and user.get('email') not in ALLOWED_EMAILS:
|
||||||
return JSONResponse(status_code=403, content={"error": "Email not allowed"})
|
return JSONResponse(status_code=403, content={"error": "Email not allowed"})
|
||||||
|
|
||||||
try:
|
# Fallback to BigQuery forecast
|
||||||
# The prompt mentioned BUDGET_ID but the new implementation uses Firestore.
|
print("Billing Budget API not implemented, falling back to BigQuery", file=sys.stderr)
|
||||||
# This endpoint seems to rely on the old budget mechanism.
|
bq_forecast = BillingAgent().get_forecast()
|
||||||
# I will leave it for now but it might need refactoring later.
|
bq_forecast["data_source"] = "BigQuery Fallback"
|
||||||
billing_account_id = os.environ.get("BILLING_ACCOUNT_ID")
|
return bq_forecast
|
||||||
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
|
|
||||||
bq_forecast = BillingAgent().get_forecast()
|
|
||||||
bq_forecast["data_source"] = "BigQuery Fallback"
|
|
||||||
return bq_forecast
|
|
||||||
|
|
||||||
|
|
||||||
# ── AWS BILLING ENDPOINTS (CG6) ──────────────────────────────────────────────
|
# ── AWS BILLING ENDPOINTS (CG6) ──────────────────────────────────────────────
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ pandas>=2.0.0
|
||||||
|
|
||||||
# ── CostGuard App (Fase B1-B5) ────────────────────────────────────────────────
|
# ── CostGuard App (Fase B1-B5) ────────────────────────────────────────────────
|
||||||
google-cloud-billing>=1.12.0
|
google-cloud-billing>=1.12.0
|
||||||
google-cloud-billing-budgets>=1.4.0
|
|
||||||
google-cloud-firestore>=2.16.0
|
google-cloud-firestore>=2.16.0
|
||||||
firebase-admin>=6.5.0
|
firebase-admin>=6.5.0
|
||||||
cachetools>=5.3.3
|
cachetools>=5.3.3
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user