PlainSQL-Agent / app.py
LalitChaudhari3's picture
Update app.py
3665fc5 verified
import sys
import os
import uvicorn
import re
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from pydantic import BaseModel
from typing import List, Optional
# 🚨 FORCE PYTHON TO FIND THE 'src' FOLDER
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# Import custom modules
from src.db_connector import Database
from src.rag_manager import RAGSystem
from src.sql_generator import SQLGenerator
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class ChatRequest(BaseModel):
question: str
history: Optional[List[dict]] = []
# --- HELPER: CLEAN AI OUTPUT ---
def clean_sql(sql_text: str) -> str:
if not sql_text: return ""
cleaned = re.sub(r"```sql|```", "", sql_text, flags=re.IGNORECASE).strip()
return cleaned.rstrip(';')
# --- πŸš€ SAFE INITIALIZATION ---
# Initialize as None so the app doesn't crash if DB fails
db = None
rag = None
generator = None
startup_error = None
print("--- πŸš€ SYSTEM STARTUP SEQUENCE ---")
try:
print(" ...Connecting to Database")
# ⚠️ IF THIS FAILS, THE APP WILL NOW CATCH IT GRACEFULLY
db = Database()
print(" βœ… Database Connection: SUCCESS")
print(" ...Initializing RAG System")
rag = RAGSystem(db)
print(" βœ… RAG System: ONLINE")
print(" ...Loading AI Model")
generator = SQLGenerator()
print(" βœ… AI Model: LOADED")
except Exception as e:
startup_error = str(e)
print(f" ❌ CRITICAL STARTUP ERROR: {e}")
# --- ROUTES ---
@app.get("/", response_class=HTMLResponse)
async def serve_ui():
try:
with open("index.html", "r", encoding="utf-8") as f:
return f.read()
except FileNotFoundError:
return "Error: index.html not found."
@app.post("/chat")
def chat_endpoint(request: ChatRequest):
# 🚨 CHECK FOR STARTUP ERRORS FIRST
if rag is None or db is None:
return {
"answer": [f"System Error: {startup_error}"],
"sql": "-- Database Connection Failed",
"message": f"I cannot connect to the database. Reason: {startup_error}. Please check the Logs tab.",
"follow_ups": []
}
try:
context = rag.get_relevant_schema(request.question)
raw_sql, explanation, friendly_msg = generator.generate_sql(request.question, context, request.history)
# Clean SQL
cleaned_sql = clean_sql(raw_sql)
# Security Check
if not cleaned_sql.upper().startswith("SELECT"):
return {"answer": [], "sql": cleaned_sql, "message": "Security Alert: Read-Only Mode.", "follow_ups": []}
# Run Query
try:
results = db.run_query(cleaned_sql)
except Exception as db_err:
return {"answer": [f"SQL Error: {str(db_err)}"], "sql": cleaned_sql, "message": "Syntax Error in SQL.", "follow_ups": []}
return {
"answer": results,
"sql": cleaned_sql,
"message": friendly_msg,
"follow_ups": []
}
except Exception as e:
return {"answer": [], "sql": "-- Error", "message": f"Processing Error: {str(e)}", "follow_ups": []}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)