Gaurav-2273 commited on
Commit
fcd041f
·
verified ·
1 Parent(s): 37bb373

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -36
app.py CHANGED
@@ -4,20 +4,45 @@ import sqlite3
4
  import pandas as pd
5
  import os
6
 
7
- # 1. API CONFIG
 
 
8
  api_key = os.getenv("GEMINI_API_KEY")
9
  if api_key:
10
  genai.configure(api_key=api_key)
11
  else:
12
  st.error("⚠️ API Key missing! Go to Settings -> Secrets and add GEMINI_API_KEY.")
13
 
14
- # 2. DB INITIALIZATION
15
- if not os.path.exists("sales.db"):
16
- import generate_db
17
- generate_db.init_db()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
 
19
  def get_schema():
20
- conn = sqlite3.connect('sales.db')
21
  cursor = conn.cursor()
22
  cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
23
  tables = cursor.fetchall()
@@ -30,7 +55,7 @@ def get_schema():
30
  return schema_str
31
 
32
  def run_sql(sql):
33
- conn = sqlite3.connect('sales.db')
34
  try:
35
  df = pd.read_sql_query(sql, conn)
36
  return df, None
@@ -39,42 +64,63 @@ def run_sql(sql):
39
  finally:
40
  conn.close()
41
 
42
- # 3. AGENTIC LOGIC
43
  def sql_agent(user_prompt):
44
- # Force the model to use the most stable string
45
- # Try 'gemini-1.5-flash' first, but if it fails, 'gemini-pro' is the universal fallback
46
- try:
47
- model = genai.GenerativeModel('gemini-1.5-flash')
48
- # Test a small call to see if it's alive
49
- model.generate_content("test")
50
- except:
51
- # Fallback to the older, most stable naming convention
52
- model = genai.GenerativeModel('gemini-pro')
53
  schema = get_schema()
54
 
55
- # ATTEMPT 1
56
- full_prompt = f"Schema:\n{schema}\n\nUser: {user_prompt}\n\nOutput ONLY valid SQL."
57
- res = model.generate_content(full_prompt).text.strip().replace('```sql', '').replace('```', '')
 
 
 
 
58
 
59
- df, error = run_sql(res)
 
60
 
61
- # REFLECTION LOOP (Self-Correction)
62
- if error:
63
- st.warning("🔄 Query failed. Agent is self-correcting...")
64
- fix_prompt = f"The query {res} failed with error: {error}. Fix it based on this schema: {schema}. Output ONLY SQL."
65
- res = model.generate_content(fix_prompt).text.strip().replace('```sql', '').replace('```', '')
66
- df, error = run_sql(res)
67
 
68
- return df, error, res
 
 
 
 
 
 
 
 
 
 
69
 
70
- # 4. UI
71
  st.title("🕵️‍♂️ Agentic Text-to-SQL")
72
- query = st.text_input("Ask your Database:", "Show me all software products")
 
 
73
 
74
  if st.button("Run Agent"):
75
- data, err, final_sql = sql_agent(query)
76
- if err:
77
- st.error(f"Final Attempt Failed: {err}")
78
- else:
79
- st.code(final_sql, language="sql")
80
- st.dataframe(data)
 
 
 
 
 
 
 
 
4
  import pandas as pd
5
  import os
6
 
7
+ # --- 1. SETTINGS & API CONFIG ---
8
+ st.set_page_config(page_title="Agentic SQL", page_icon="🕵️‍♂️")
9
+
10
  api_key = os.getenv("GEMINI_API_KEY")
11
  if api_key:
12
  genai.configure(api_key=api_key)
13
  else:
14
  st.error("⚠️ API Key missing! Go to Settings -> Secrets and add GEMINI_API_KEY.")
15
 
16
+ # --- 2. DATABASE INITIALIZATION (Self-Contained) ---
17
+ DB_NAME = "sales.db"
18
+
19
+ def init_db():
20
+ """Creates a dummy database if it doesn't exist."""
21
+ conn = sqlite3.connect(DB_NAME)
22
+ c = conn.cursor()
23
+ # Create Tables
24
+ c.execute('''CREATE TABLE IF NOT EXISTS customers
25
+ (id INTEGER PRIMARY KEY, name TEXT, region TEXT)''')
26
+ c.execute('''CREATE TABLE IF NOT EXISTS products
27
+ (id INTEGER PRIMARY KEY, name TEXT, category TEXT, price REAL)''')
28
+ c.execute('''CREATE TABLE IF NOT EXISTS orders
29
+ (id INTEGER PRIMARY KEY, customer_id INTEGER, product_id INTEGER,
30
+ quantity INTEGER, order_date DATE)''')
31
+ # Insert Sample Data
32
+ c.execute("INSERT OR IGNORE INTO customers VALUES (1, 'Acme Corp', 'North')")
33
+ c.execute("INSERT OR IGNORE INTO customers VALUES (2, 'Globex', 'West')")
34
+ c.execute("INSERT OR IGNORE INTO products VALUES (1, 'AI Widget', 'Software', 1000.0)")
35
+ c.execute("INSERT OR IGNORE INTO products VALUES (2, 'Cloud Server', 'Hardware', 5000.0)")
36
+ c.execute("INSERT OR IGNORE INTO orders VALUES (101, 1, 1, 5, '2023-10-01')")
37
+ conn.commit()
38
+ conn.close()
39
+
40
+ if not os.path.exists(DB_NAME):
41
+ init_db()
42
 
43
+ # --- 3. HELPER FUNCTIONS ---
44
  def get_schema():
45
+ conn = sqlite3.connect(DB_NAME)
46
  cursor = conn.cursor()
47
  cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
48
  tables = cursor.fetchall()
 
55
  return schema_str
56
 
57
  def run_sql(sql):
58
+ conn = sqlite3.connect(DB_NAME)
59
  try:
60
  df = pd.read_sql_query(sql, conn)
61
  return df, None
 
64
  finally:
65
  conn.close()
66
 
67
+ # --- 4. AGENTIC LOGIC ---
68
  def sql_agent(user_prompt):
69
+ # Attempt to use Flash, fallback to Pro if the environment is restricted
70
+ try:
71
+ model = genai.GenerativeModel('gemini-1.5-flash')
72
+ except:
73
+ model = genai.GenerativeModel('gemini-pro')
74
+
 
 
 
75
  schema = get_schema()
76
 
77
+ # SYSTEM PROMPT
78
+ prompt = f"""
79
+ You are an expert SQL assistant. Based on the schema below, write a SQLite query to answer the user's request.
80
+ Schema:
81
+ {schema}
82
+
83
+ User Request: {user_prompt}
84
 
85
+ Return ONLY the raw SQL code. No markdown, no backticks, no explanations.
86
+ """
87
 
88
+ try:
89
+ response = model.generate_content(prompt)
90
+ raw_sql = response.text.strip().replace('```sql', '').replace('```', '')
91
+
92
+ # EXECUTION
93
+ data, error = run_sql(raw_sql)
94
 
95
+ # SELF-REFLECTION LOOP (If error, try once more)
96
+ if error:
97
+ st.warning("🔄 Query failed. Agent is self-correcting...")
98
+ fix_prompt = f"The SQL query '{raw_sql}' failed with error: {error}. Rewrite the SQL correctly based on this schema: {schema}. Return ONLY SQL."
99
+ response = model.generate_content(fix_prompt)
100
+ raw_sql = response.text.strip().replace('```sql', '').replace('```', '')
101
+ data, error = run_sql(raw_sql)
102
+
103
+ return data, error, raw_sql
104
+ except Exception as e:
105
+ return None, f"AI Error: {str(e)}", "None"
106
 
107
+ # --- 5. UI ---
108
  st.title("🕵️‍♂️ Agentic Text-to-SQL")
109
+ st.markdown("This agent writes SQL, executes it, and **fixes its own mistakes**.")
110
+
111
+ query = st.text_input("Ask your database:", value="Show all software products")
112
 
113
  if st.button("Run Agent"):
114
+ with st.spinner("Agent is thinking..."):
115
+ results, err, final_sql = sql_agent(query)
116
+
117
+ if err:
118
+ st.error(f"Execution Error: {err}")
119
+ else:
120
+ st.success("Query Successful!")
121
+ st.code(final_sql, language="sql")
122
+ st.dataframe(results, use_container_width=True)
123
+
124
+ st.divider()
125
+ with st.expander("See Database Schema"):
126
+ st.text(get_schema())