Spaces:
Sleeping
Sleeping
| 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 | |
| async def health(): | |
| return {"status": "ok", "service": "finsync-backend"} | |
| # Analyze / natural language endpoint | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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) |