from fastapi import FastAPI, Request, HTTPException from fastapi.responses import HTMLResponse, JSONResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from pydantic import BaseModel from typing import Dict from groq import Groq # ─── CONFIG ───────────────────────────────────────────── GROQ_API_KEY = "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" MODEL = "llama-3.3-70b-versatile" # ──────────────────────────────────────────────────────── app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") templates = Jinja2Templates(directory="templates") class BudgetInput(BaseModel): salary: float risk_tolerance: str expenses: Dict[str, Dict[str, float]] @app.get("/", response_class=HTMLResponse) async def get_chat(request: Request): return templates.TemplateResponse("index.html", {"request": request}) @app.post("/analyze") async def analyze(data: BudgetInput): try: total = sum( amt for category in data.expenses.values() for amt in category.values() ) remaining = data.salary - total # build messages system_msg = { "role": "system", "content": ( "You are a helpful financial advisor assistant " "Based on a user's monthly salary, categorized expenses, and risk tolerance, and don't gave them desclaimer about anything " "provide secure, actionable investment suggestions in a friendly tone , make sure give them concise on point and stats of it , list of where can you invest, is there any way ." ) } lines = [] for cat, vals in data.expenses.items(): for name, amt in vals.items(): lines.append(f"{name}: ₹{amt:.2f}") user_msg = { "role": "user", "content": ( f"I have a monthly salary of ₹{data.salary:.2f}.\n" f"My expenses:\n" + "\n".join(lines) + "\n" f"Remaining balance: ₹{remaining:.2f}\n" f"My risk tolerance is '{data.risk_tolerance}'.\n" "Please suggest how I should invest this amount securely." ) } client = Groq(api_key=GROQ_API_KEY) resp = client.chat.completions.create( model=MODEL, messages=[system_msg, user_msg], temperature=0.5, max_tokens=1024, top_p=1.0, ) advice_md = resp.choices[0].message.content return JSONResponse({ "summary": { "salary": data.salary, "total_expenses": total, "remaining_balance": remaining, "expense_breakdown": data.expenses, }, "groq_advice_markdown": advice_md }) except Exception as e: raise HTTPException(status_code=500, detail=str(e))