FinSync-AI / backend /main.py
JARVISXIRONMAN's picture
Upload main.py
45df06e verified
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import uvicorn
import os
from dotenv import load_dotenv
from typing import Any, Dict
load_dotenv()
# Local module imports (we'll implement these next)
from backend import ai_agent
from backend import expense_manager
from backend import budget_allocator
from backend import reminder_system
# App init
app = FastAPI(title="FinSync AI Backend")
# Allow CORS from Streamlit / local dev
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Pydantic models
class AnalyzeRequest(BaseModel):
user_id: str
text: str
class ExpenseRequest(BaseModel):
user_id: str
name: str
amount: float
category: str = ""
date: str = ""
class ReminderRequest(BaseModel):
user_id: str
name: str
date: str
amount: float = 0.0
notes: str = ""
# Simple health check
@app.get("/health")
async def health():
return {"status": "ok", "service": "finsync-backend"}
# Analyze / natural language endpoint
@app.post("/analyze")
async def analyze(req: AnalyzeRequest):
"""
Send user natural command to AI agent; AI responds with action/intention and human-readable reply.
Example use-cases:
- "Show my expenses this month"
- "Set reminder to pay rent on 2025-11-10"
- "Add expense Rent 500"
"""
try:
response: Dict[str, Any] = ai_agent.parse_and_respond(user_id=req.user_id, text=req.text)
return {"ok": True, "result": response}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# Add expense endpoint
@app.post("/add_expense")
async def add_expense(req: ExpenseRequest):
"""
Add an expense into the database.json (demo DB).
"""
try:
entry = {
"user_id": req.user_id,
"name": req.name,
"amount": float(req.amount),
"category": req.category or "Uncategorized",
"date": req.date or expense_manager.today_iso(),
}
expense_manager.add_expense(entry)
return {"ok": True, "expense": entry}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# List expenses for a user
@app.get("/expenses")
async def get_expenses(user_id: str):
try:
items = expense_manager.list_expenses(user_id=user_id)
return {"ok": True, "expenses": items}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# Get budget suggestion
@app.get("/budget")
async def get_budget(user_id: str):
try:
expenses = expense_manager.list_expenses(user_id=user_id)
suggestion = budget_allocator.suggest_budget(user_id=user_id, expenses=expenses)
return {"ok": True, "budget": suggestion}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# Add reminder
@app.post("/reminder")
async def add_reminder(req: ReminderRequest):
try:
reminder = {
"user_id": req.user_id,
"name": req.name,
"date": req.date,
"amount": float(req.amount),
"notes": req.notes
}
reminder_system.add_reminder(reminder)
return {"ok": True, "reminder": reminder}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# List reminders
@app.get("/reminders")
async def list_reminders(user_id: str):
try:
items = reminder_system.list_reminders(user_id=user_id)
return {"ok": True, "reminders": items}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
port = int(os.environ.get("BACKEND_PORT", 8000))
uvicorn.run("backend.main:app", host="0.0.0.0", port=port, reload=True)