LalitChaudhari3 commited on
Commit
f6b402d
Β·
verified Β·
1 Parent(s): 195c226

Rename api_server.py to app.py

Browse files
Files changed (1) hide show
  1. api_server.py β†’ app.py +141 -128
api_server.py β†’ app.py RENAMED
@@ -1,128 +1,141 @@
1
- import sys
2
- import os
3
- import uvicorn
4
- import re
5
-
6
- # 🚨 FORCE PYTHON TO FIND THE 'src' FOLDER
7
- sys.path.append(os.path.dirname(os.path.abspath(__file__)))
8
-
9
- from fastapi import FastAPI, HTTPException
10
- from fastapi.middleware.cors import CORSMiddleware
11
- from pydantic import BaseModel
12
- from typing import List, Optional
13
-
14
- # Import your custom modules
15
- from src.db_connector import Database
16
- from src.rag_manager import RAGSystem
17
- from src.sql_generator import SQLGenerator
18
-
19
- app = FastAPI()
20
-
21
- app.add_middleware(
22
- CORSMiddleware,
23
- allow_origins=["*"],
24
- allow_credentials=True,
25
- allow_methods=["*"],
26
- allow_headers=["*"],
27
- )
28
-
29
- class ChatRequest(BaseModel):
30
- question: str
31
- history: Optional[List[dict]] = []
32
-
33
- # --- HELPER: CLEAN AI OUTPUT ---
34
- def clean_sql(sql_text: str) -> str:
35
- """Removes markdown, 'sql' tags, and extra whitespace."""
36
- if not sql_text:
37
- return ""
38
- # Remove markdown code blocks (```sql ... ```)
39
- cleaned = re.sub(r"```sql|```", "", sql_text, flags=re.IGNORECASE).strip()
40
- # Remove trailing semicolons for consistency (optional, depending on DB driver)
41
- cleaned = cleaned.rstrip(';')
42
- return cleaned
43
-
44
- print("--- πŸš€ SYSTEM STARTUP SEQUENCE ---")
45
- try:
46
- print(" ...Connecting to Database")
47
- db = Database()
48
- print(" βœ… Database Connection: SUCCESS")
49
-
50
- print(" ...Initializing RAG System")
51
- rag = RAGSystem(db)
52
- print(" βœ… RAG System: ONLINE")
53
-
54
- print(" ...Loading AI Model")
55
- generator = SQLGenerator()
56
- print(" βœ… AI Model: LOADED")
57
-
58
- except Exception as e:
59
- print(f" ❌ CRITICAL STARTUP ERROR: {e}")
60
-
61
- @app.post("/chat")
62
- def chat_endpoint(request: ChatRequest):
63
- print(f"\nπŸ“¨ NEW REQUEST: {request.question}")
64
-
65
- try:
66
- # 1. Get Context
67
- context = rag.get_relevant_schema(request.question)
68
-
69
- # 2. Generate SQL
70
- raw_sql, explanation, friendly_msg = generator.generate_sql(request.question, context, request.history)
71
-
72
- # 3. Clean and Validate SQL
73
- # If the generator returned an error string directly (Error 1 fix)
74
- if "Error:" in raw_sql or "Invalid Query" in raw_sql:
75
- return {
76
- "answer": [],
77
- "sql": raw_sql,
78
- "message": "I couldn't generate a safe query for that request. Try asking for specific data like 'Show me users' or 'List orders'.",
79
- "follow_ups": ["Show top 10 rows from users", "Count total orders"]
80
- }
81
-
82
- cleaned_sql = clean_sql(raw_sql)
83
- print(f" 🧹 Cleaned SQL: {cleaned_sql}")
84
-
85
- # Safety check: Ensure it's a SELECT
86
- if not cleaned_sql.upper().startswith("SELECT"):
87
- return {
88
- "answer": [],
89
- "sql": cleaned_sql,
90
- "message": "Security Alert: I can only perform READ (SELECT) operations.",
91
- "follow_ups": []
92
- }
93
-
94
- # 4. Run Query (Error 2 fix)
95
- try:
96
- results = db.run_query(cleaned_sql)
97
- except Exception as db_err:
98
- # Catch MySQL Syntax errors specifically
99
- print(f" ⚠️ DB Error: {db_err}")
100
- return {
101
- "answer": [f"Error: {str(db_err)}"], # This puts the error in a safe list
102
- "sql": cleaned_sql,
103
- "message": "There was a syntax error in the generated SQL. I have displayed the error above.",
104
- "follow_ups": []
105
- }
106
-
107
- # 5. Generate Follow-ups
108
- follow_ups = generator.generate_followup_questions(request.question, cleaned_sql)
109
-
110
- return {
111
- "answer": results,
112
- "sql": cleaned_sql,
113
- "explanation": explanation,
114
- "message": friendly_msg,
115
- "follow_ups": follow_ups
116
- }
117
-
118
- except Exception as e:
119
- print(f"❌ General Processing Error: {e}")
120
- return {
121
- "answer": [],
122
- "sql": "-- System Error",
123
- "message": f"Critical Error: {str(e)}",
124
- "follow_ups": []
125
- }
126
-
127
- if __name__ == "__main__":
128
- uvicorn.run(app, host="0.0.0.0", port=8000)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+ import uvicorn
4
+ import re
5
+ from fastapi import FastAPI, HTTPException
6
+ from fastapi.middleware.cors import CORSMiddleware
7
+ from fastapi.responses import HTMLResponse # <--- ADDED THIS
8
+ from pydantic import BaseModel
9
+ from typing import List, Optional
10
+
11
+ # 🚨 FORCE PYTHON TO FIND THE 'src' FOLDER
12
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
13
+
14
+ # Import your custom modules
15
+ from src.db_connector import Database
16
+ from src.rag_manager import RAGSystem
17
+ from src.sql_generator import SQLGenerator
18
+
19
+ app = FastAPI()
20
+
21
+ app.add_middleware(
22
+ CORSMiddleware,
23
+ allow_origins=["*"],
24
+ allow_credentials=True,
25
+ allow_methods=["*"],
26
+ allow_headers=["*"],
27
+ )
28
+
29
+ class ChatRequest(BaseModel):
30
+ question: str
31
+ history: Optional[List[dict]] = []
32
+
33
+ # --- HELPER: CLEAN AI OUTPUT ---
34
+ def clean_sql(sql_text: str) -> str:
35
+ """Removes markdown, 'sql' tags, and extra whitespace."""
36
+ if not sql_text:
37
+ return ""
38
+ # Remove markdown code blocks (```sql ... ```)
39
+ cleaned = re.sub(r"```sql|```", "", sql_text, flags=re.IGNORECASE).strip()
40
+ # Remove trailing semicolons for consistency
41
+ cleaned = cleaned.rstrip(';')
42
+ return cleaned
43
+
44
+ # --- INITIALIZATION SEQUENCE ---
45
+ print("--- πŸš€ SYSTEM STARTUP SEQUENCE ---")
46
+ try:
47
+ print(" ...Connecting to Database")
48
+ db = Database()
49
+ print(" βœ… Database Connection: SUCCESS")
50
+
51
+ print(" ...Initializing RAG System")
52
+ rag = RAGSystem(db)
53
+ print(" βœ… RAG System: ONLINE")
54
+
55
+ print(" ...Loading AI Model")
56
+ generator = SQLGenerator()
57
+ print(" βœ… AI Model: LOADED")
58
+
59
+ except Exception as e:
60
+ print(f" ❌ CRITICAL STARTUP ERROR: {e}")
61
+
62
+
63
+ # --- 1. NEW ROUTE TO SERVE THE UI ---
64
+ @app.get("/", response_class=HTMLResponse)
65
+ async def serve_ui():
66
+ """Serves the index.html file when user visits the root URL"""
67
+ try:
68
+ with open("index.html", "r", encoding="utf-8") as f:
69
+ return f.read()
70
+ except FileNotFoundError:
71
+ return "Error: index.html not found. Make sure it is in the root folder."
72
+
73
+
74
+ # --- 2. CHAT API ENDPOINT ---
75
+ @app.post("/chat")
76
+ def chat_endpoint(request: ChatRequest):
77
+ print(f"\nπŸ“¨ NEW REQUEST: {request.question}")
78
+
79
+ try:
80
+ # 1. Get Context
81
+ context = rag.get_relevant_schema(request.question)
82
+
83
+ # 2. Generate SQL
84
+ raw_sql, explanation, friendly_msg = generator.generate_sql(request.question, context, request.history)
85
+
86
+ # 3. Clean and Validate SQL
87
+ if "Error:" in raw_sql or "Invalid Query" in raw_sql:
88
+ return {
89
+ "answer": [],
90
+ "sql": raw_sql,
91
+ "message": "I couldn't generate a safe query for that request. Try asking for specific data like 'Show me users' or 'List orders'.",
92
+ "follow_ups": ["Show top 10 rows from users", "Count total orders"]
93
+ }
94
+
95
+ cleaned_sql = clean_sql(raw_sql)
96
+ print(f" 🧹 Cleaned SQL: {cleaned_sql}")
97
+
98
+ # Safety check: Ensure it's a SELECT
99
+ if not cleaned_sql.upper().startswith("SELECT"):
100
+ return {
101
+ "answer": [],
102
+ "sql": cleaned_sql,
103
+ "message": "Security Alert: I can only perform READ (SELECT) operations.",
104
+ "follow_ups": []
105
+ }
106
+
107
+ # 4. Run Query
108
+ try:
109
+ results = db.run_query(cleaned_sql)
110
+ except Exception as db_err:
111
+ print(f" ⚠️ DB Error: {db_err}")
112
+ return {
113
+ "answer": [f"Error: {str(db_err)}"],
114
+ "sql": cleaned_sql,
115
+ "message": "There was a syntax error in the generated SQL. I have displayed the error above.",
116
+ "follow_ups": []
117
+ }
118
+
119
+ # 5. Generate Follow-ups
120
+ follow_ups = generator.generate_followup_questions(request.question, cleaned_sql)
121
+
122
+ return {
123
+ "answer": results,
124
+ "sql": cleaned_sql,
125
+ "explanation": explanation,
126
+ "message": friendly_msg,
127
+ "follow_ups": follow_ups
128
+ }
129
+
130
+ except Exception as e:
131
+ print(f"❌ General Processing Error: {e}")
132
+ return {
133
+ "answer": [],
134
+ "sql": "-- System Error",
135
+ "message": f"Critical Error: {str(e)}",
136
+ "follow_ups": []
137
+ }
138
+
139
+ if __name__ == "__main__":
140
+ uvicorn.run(app, host="0.0.0.0", port=8000)
141
+