shukdevdattaEX commited on
Commit
b7c4fee
·
verified ·
1 Parent(s): 944a160

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +148 -284
app.py CHANGED
@@ -1,13 +1,8 @@
1
- import gradio as gr
2
  from groq import Groq
3
  from pydantic import BaseModel
4
  import json
5
- import sqlite3
6
- import re
7
- from datetime import datetime, timedelta
8
- import random
9
 
10
- # Pydantic models for structured output
11
  class ValidationStatus(BaseModel):
12
  is_valid: bool
13
  syntax_errors: list[str]
@@ -19,186 +14,20 @@ class SQLQueryGeneration(BaseModel):
19
  estimated_complexity: str
20
  execution_notes: list[str]
21
  validation_status: ValidationStatus
 
 
 
 
22
 
23
- def generate_sample_data(query, tables_used):
24
- """Generate sample data based on the query and tables used"""
25
- conn = sqlite3.connect(':memory:')
26
- cursor = conn.cursor()
27
-
28
- sample_data = {}
29
-
30
- # Generate data based on common table patterns
31
- if 'customers' in tables_used:
32
- cursor.execute('''
33
- CREATE TABLE customers (
34
- customer_id INTEGER PRIMARY KEY,
35
- name TEXT,
36
- email TEXT
37
- )
38
- ''')
39
-
40
- customers = [
41
- (1, 'Alice Johnson', 'alice@example.com'),
42
- (2, 'Bob Smith', 'bob@example.com'),
43
- (3, 'Carol Williams', 'carol@example.com'),
44
- (4, 'David Brown', 'david@example.com'),
45
- (5, 'Eve Davis', 'eve@example.com')
46
- ]
47
-
48
- cursor.executemany('INSERT INTO customers VALUES (?, ?, ?)', customers)
49
- sample_data['customers'] = customers
50
-
51
- if 'orders' in tables_used:
52
- cursor.execute('''
53
- CREATE TABLE orders (
54
- order_id INTEGER PRIMARY KEY,
55
- customer_id INTEGER,
56
- total_amount REAL,
57
- order_date TEXT
58
- )
59
- ''')
60
-
61
- today = datetime.now()
62
- orders = [
63
- (101, 1, 600, (today - timedelta(days=10)).strftime('%Y-%m-%d')),
64
- (102, 1, 450, (today - timedelta(days=5)).strftime('%Y-%m-%d')),
65
- (103, 2, 1200, (today - timedelta(days=15)).strftime('%Y-%m-%d')),
66
- (104, 3, 300, (today - timedelta(days=20)).strftime('%Y-%m-%d')),
67
- (105, 3, 800, (today - timedelta(days=2)).strftime('%Y-%m-%d')),
68
- (106, 4, 550, (today - timedelta(days=7)).strftime('%Y-%m-%d')),
69
- (107, 5, 1500, (today - timedelta(days=12)).strftime('%Y-%m-%d'))
70
- ]
71
-
72
- cursor.executemany('INSERT INTO orders VALUES (?, ?, ?, ?)', orders)
73
- sample_data['orders'] = orders
74
-
75
- if 'products' in tables_used:
76
- cursor.execute('''
77
- CREATE TABLE products (
78
- product_id INTEGER PRIMARY KEY,
79
- product_name TEXT,
80
- price REAL,
81
- category TEXT
82
- )
83
- ''')
84
-
85
- products = [
86
- (1, 'Laptop', 999.99, 'Electronics'),
87
- (2, 'Mouse', 29.99, 'Electronics'),
88
- (3, 'Keyboard', 79.99, 'Electronics'),
89
- (4, 'Monitor', 299.99, 'Electronics'),
90
- (5, 'Desk', 199.99, 'Furniture')
91
- ]
92
-
93
- cursor.executemany('INSERT INTO products VALUES (?, ?, ?, ?)', products)
94
- sample_data['products'] = products
95
-
96
- if 'employees' in tables_used:
97
- cursor.execute('''
98
- CREATE TABLE employees (
99
- employee_id INTEGER PRIMARY KEY,
100
- name TEXT,
101
- department TEXT,
102
- salary REAL
103
- )
104
- ''')
105
-
106
- employees = [
107
- (1, 'John Doe', 'Engineering', 85000),
108
- (2, 'Jane Smith', 'Marketing', 75000),
109
- (3, 'Mike Johnson', 'Sales', 70000),
110
- (4, 'Sarah Williams', 'Engineering', 90000),
111
- (5, 'Tom Brown', 'HR', 65000)
112
- ]
113
-
114
- cursor.executemany('INSERT INTO employees VALUES (?, ?, ?, ?)', employees)
115
- sample_data['employees'] = employees
116
-
117
- return conn, cursor, sample_data
118
-
119
- def execute_sql_query(cursor, query):
120
- """Execute the SQL query and return results"""
121
  try:
122
- # Convert MySQL/PostgreSQL specific functions to SQLite
123
- sqlite_query = query.replace('DATE_SUB(NOW(), INTERVAL 30 DAY)',
124
- f"date('now', '-30 days')")
125
- sqlite_query = sqlite_query.replace('NOW()', "date('now')")
126
-
127
- cursor.execute(sqlite_query)
128
- results = cursor.fetchall()
129
- columns = [description[0] for description in cursor.description]
130
- return results, columns, None
131
- except Exception as e:
132
- return None, None, str(e)
133
-
134
- def format_sample_tables(sample_data):
135
- """Format sample tables as HTML for display"""
136
- html = "<div style='margin: 20px 0;'>"
137
-
138
- for table_name, data in sample_data.items():
139
- html += f"<h3>📊 Sample {table_name} Table</h3>"
140
- html += "<table style='border-collapse: collapse; width: 100%; margin-bottom: 20px;'>"
141
-
142
- if table_name == 'customers':
143
- html += "<tr style='background-color: #f0f0f0;'><th style='border: 1px solid #ddd; padding: 8px;'>customer_id</th><th style='border: 1px solid #ddd; padding: 8px;'>name</th><th style='border: 1px solid #ddd; padding: 8px;'>email</th></tr>"
144
- for row in data:
145
- html += f"<tr><td style='border: 1px solid #ddd; padding: 8px;'>{row[0]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[1]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[2]}</td></tr>"
146
-
147
- elif table_name == 'orders':
148
- html += "<tr style='background-color: #f0f0f0;'><th style='border: 1px solid #ddd; padding: 8px;'>order_id</th><th style='border: 1px solid #ddd; padding: 8px;'>customer_id</th><th style='border: 1px solid #ddd; padding: 8px;'>total_amount</th><th style='border: 1px solid #ddd; padding: 8px;'>order_date</th></tr>"
149
- for row in data:
150
- html += f"<tr><td style='border: 1px solid #ddd; padding: 8px;'>{row[0]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[1]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[2]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[3]}</td></tr>"
151
-
152
- elif table_name == 'products':
153
- html += "<tr style='background-color: #f0f0f0;'><th style='border: 1px solid #ddd; padding: 8px;'>product_id</th><th style='border: 1px solid #ddd; padding: 8px;'>product_name</th><th style='border: 1px solid #ddd; padding: 8px;'>price</th><th style='border: 1px solid #ddd; padding: 8px;'>category</th></tr>"
154
- for row in data:
155
- html += f"<tr><td style='border: 1px solid #ddd; padding: 8px;'>{row[0]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[1]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[2]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[3]}</td></tr>"
156
 
157
- elif table_name == 'employees':
158
- html += "<tr style='background-color: #f0f0f0;'><th style='border: 1px solid #ddd; padding: 8px;'>employee_id</th><th style='border: 1px solid #ddd; padding: 8px;'>name</th><th style='border: 1px solid #ddd; padding: 8px;'>department</th><th style='border: 1px solid #ddd; padding: 8px;'>salary</th></tr>"
159
- for row in data:
160
- html += f"<tr><td style='border: 1px solid #ddd; padding: 8px;'>{row[0]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[1]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[2]}</td><td style='border: 1px solid #ddd; padding: 8px;'>{row[3]}</td></tr>"
161
 
162
- html += "</table>"
163
-
164
- html += "</div>"
165
- return html
166
-
167
- def format_execution_result(results, columns):
168
- """Format SQL execution results as HTML table"""
169
- if not results:
170
- return "<p>No results found.</p>"
171
-
172
- html = "<div style='margin: 20px 0;'>"
173
- html += "<h3>✅ SQL Execution Result (Final Output Table)</h3>"
174
- html += "<table style='border-collapse: collapse; width: 100%;'>"
175
-
176
- # Header
177
- html += "<tr style='background-color: #4CAF50; color: white;'>"
178
- for col in columns:
179
- html += f"<th style='border: 1px solid #ddd; padding: 8px;'>{col}</th>"
180
- html += "</tr>"
181
-
182
- # Rows
183
- for row in results:
184
- html += "<tr>"
185
- for cell in row:
186
- html += f"<td style='border: 1px solid #ddd; padding: 8px;'>{cell}</td>"
187
- html += "</tr>"
188
-
189
- html += "</table></div>"
190
- return html
191
-
192
- def process_query(api_key, user_query):
193
- """Main function to process natural language query"""
194
- if not api_key:
195
- return "❌ Please enter your Groq API key", "", "", ""
196
-
197
- if not user_query:
198
- return "❌ Please enter a query", "", "", ""
199
-
200
- try:
201
- # Step 1: Generate SQL using Groq
202
  client = Groq(api_key=api_key)
203
 
204
  response = client.chat.completions.create(
@@ -206,9 +35,24 @@ def process_query(api_key, user_query):
206
  messages=[
207
  {
208
  "role": "system",
209
- "content": "You are a SQL expert. Generate structured SQL queries from natural language descriptions with proper syntax validation and metadata. Use standard SQL syntax compatible with MySQL.",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  },
211
- {"role": "user", "content": user_query},
212
  ],
213
  response_format={
214
  "type": "json_schema",
@@ -223,125 +67,145 @@ def process_query(api_key, user_query):
223
  json.loads(response.choices[0].message.content)
224
  )
225
 
226
- # Step 2: Format the structured output
227
- step1_output = f"""
228
- ## 🎯 Step 1: Understand User Intent
229
-
230
- **User Query:** "{user_query}"
231
-
232
- **Identified Components:**
233
- - **Tables:** {', '.join(sql_query_generation.tables_used)}
234
- - **Query Type:** {sql_query_generation.query_type}
235
- - **Complexity:** {sql_query_generation.estimated_complexity}
236
- """
237
-
238
- step2_output = f"""
239
- ## 🔧 Step 2: Generate Structured SQL
240
-
241
- ```json
242
- {json.dumps(sql_query_generation.model_dump(), indent=2)}
243
- ```
244
-
245
- **Generated SQL Query:**
246
- ```sql
247
- {sql_query_generation.query}
248
- ```
249
- """
250
-
251
- # Step 3: Generate sample data
252
- conn, cursor, sample_data = generate_sample_data(
253
- sql_query_generation.query,
254
- sql_query_generation.tables_used
255
- )
256
-
257
- step3_output = f"""
258
- ## 📊 Step 3: Auto-Generate Sample Database Tables
259
-
260
- {format_sample_tables(sample_data)}
261
- """
262
-
263
- # Step 4: Execute query
264
- results, columns, error = execute_sql_query(cursor, sql_query_generation.query)
265
-
266
- if error:
267
- step4_output = f"""
268
- ## ⚠️ Step 4: SQL Execution
269
-
270
- **Error:** {error}
271
-
272
- **Note:** The query might use database-specific functions. The sample execution uses SQLite.
273
- """
274
  else:
275
- step4_output = f"""
276
- ## 🚀 Step 4: Execute Generated SQL on Sample Tables
277
-
278
- **Applied Conditions:**
279
- {chr(10).join([f"- {note}" for note in sql_query_generation.execution_notes])}
280
-
281
- {format_execution_result(results, columns)}
282
-
283
- **Total Rows Returned:** {len(results)}
284
- """
285
-
286
- conn.close()
287
-
288
- return step1_output, step2_output, step3_output, step4_output
 
 
 
 
 
 
 
289
 
290
  except Exception as e:
291
- error_msg = f"❌ **Error:** {str(e)}"
292
- return error_msg, "", "", ""
293
 
294
  # Create Gradio interface
295
- with gr.Blocks(title="Natural Language to SQL Query Executor", theme=gr.themes.Soft()) as app:
296
- gr.Markdown("""
297
- # 🔍 Natural Language to SQL Query Executor
298
-
299
- Convert natural language queries to SQL, auto-generate sample data, and execute queries!
300
-
301
- **Example queries to try:**
302
- - "Find all customers who made orders over $500 in the last 30 days, show their name, email, and total order amount"
303
- - "Get all employees in the Engineering department with salary above 80000"
304
- - "Show top 5 products by price"
305
- """)
306
 
307
  with gr.Row():
308
  with gr.Column():
309
  api_key_input = gr.Textbox(
310
- label="🔑 Groq API Key",
311
- placeholder="Enter your Groq API key here...",
312
- type="password"
 
313
  )
 
314
  query_input = gr.Textbox(
315
- label="💬 Natural Language Query",
316
- placeholder="Enter your query in plain English...",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  lines=3
318
  )
319
- submit_btn = gr.Button("🚀 Generate & Execute SQL", variant="primary", size="lg")
320
 
321
  with gr.Row():
322
  with gr.Column():
323
- step1_output = gr.Markdown(label="Step 1: Understanding")
324
- step2_output = gr.Markdown(label="Step 2: SQL Generation")
325
- step3_output = gr.HTML(label="Step 3: Sample Data")
326
- step4_output = gr.HTML(label="Step 4: Execution Results")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
 
328
- submit_btn.click(
329
- fn=process_query,
330
  inputs=[api_key_input, query_input],
331
- outputs=[step1_output, step2_output, step3_output, step4_output]
 
 
 
 
 
 
 
332
  )
333
 
334
- gr.Markdown("""
335
- ---
336
- ### 📝 How it works:
337
- 1. **Understand Intent:** Analyzes your natural language query
338
- 2. **Generate SQL:** Creates structured SQL with metadata
339
- 3. **Create Sample Data:** Auto-generates realistic sample tables
340
- 4. **Execute & Display:** Runs the query and shows results
341
-
342
- ### 🔗 Get your Groq API key:
343
- Visit [console.groq.com](https://console.groq.com) to get your free API key!
344
- """)
 
 
 
 
345
 
346
  if __name__ == "__main__":
347
- app.launch()
 
 
1
  from groq import Groq
2
  from pydantic import BaseModel
3
  import json
4
+ import gradio as gr
 
 
 
5
 
 
6
  class ValidationStatus(BaseModel):
7
  is_valid: bool
8
  syntax_errors: list[str]
 
14
  estimated_complexity: str
15
  execution_notes: list[str]
16
  validation_status: ValidationStatus
17
+ table_schema: str
18
+ sample_data: str
19
+ execution_results: str
20
+ optimization_notes: list[str]
21
 
22
+ def generate_sql_query(api_key, user_query):
23
+ """Generate SQL query from natural language using GROQ API"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  try:
25
+ if not api_key:
26
+ return "Error: Please enter your GROQ API key", "", "", "", "", ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ if not user_query:
29
+ return "Error: Please enter a query description", "", "", "", "", ""
 
 
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  client = Groq(api_key=api_key)
32
 
33
  response = client.chat.completions.create(
 
35
  messages=[
36
  {
37
  "role": "system",
38
+ "content": """You are a SQL expert. Generate structured SQL queries from natural language descriptions with proper syntax validation and metadata.
39
+ After generating the SQL query, you must:
40
+ 1. Create a sample SQL table schema based on the natural language description, including all necessary columns with appropriate data types
41
+ 2. Populate the table with realistic sample data that demonstrates the query's functionality
42
+ 3. Execute the generated SQL query against the sample table
43
+ 4. Display the SQL table structure and data clearly
44
+ 5. Show the query execution results
45
+ Always present your response in this order:
46
+ - Generated SQL query with syntax explanation
47
+ - Table schema (CREATE TABLE statement)
48
+ - Sample data (INSERT statements or table visualization)
49
+ - Query execution results
50
+ - Any relevant notes about assumptions made or query optimization suggestions""",
51
+ },
52
+ {
53
+ "role": "user",
54
+ "content": user_query
55
  },
 
56
  ],
57
  response_format={
58
  "type": "json_schema",
 
67
  json.loads(response.choices[0].message.content)
68
  )
69
 
70
+ # Format validation status
71
+ validation_text = f"Valid: {sql_query_generation.validation_status.is_valid}\n"
72
+ if sql_query_generation.validation_status.syntax_errors:
73
+ validation_text += "Errors:\n" + "\n".join(
74
+ f"- {error}" for error in sql_query_generation.validation_status.syntax_errors
75
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  else:
77
+ validation_text += "No syntax errors found"
78
+
79
+ # Format metadata
80
+ metadata = f"""Query Type: {sql_query_generation.query_type}
81
+ Tables Used: {', '.join(sql_query_generation.tables_used)}
82
+ Complexity: {sql_query_generation.estimated_complexity}
83
+
84
+ Execution Notes:
85
+ {chr(10).join(f"- {note}" for note in sql_query_generation.execution_notes)}
86
+
87
+ Optimization Notes:
88
+ {chr(10).join(f"- {note}" for note in sql_query_generation.optimization_notes)}"""
89
+
90
+ return (
91
+ sql_query_generation.query,
92
+ metadata,
93
+ sql_query_generation.table_schema,
94
+ sql_query_generation.sample_data,
95
+ sql_query_generation.execution_results,
96
+ validation_text
97
+ )
98
 
99
  except Exception as e:
100
+ error_msg = f"Error: {str(e)}"
101
+ return error_msg, "", "", "", "", ""
102
 
103
  # Create Gradio interface
104
+ with gr.Blocks(title="SQL Query Generator", theme=gr.themes.Soft()) as demo:
105
+ gr.Markdown(
106
+ """
107
+ # 🗄️ Natural Language to SQL Query Generator
108
+ Convert your natural language descriptions into structured SQL queries with validation and execution results.
109
+ """
110
+ )
 
 
 
 
111
 
112
  with gr.Row():
113
  with gr.Column():
114
  api_key_input = gr.Textbox(
115
+ label="GROQ API Key",
116
+ type="password",
117
+ placeholder="Enter your GROQ API key here...",
118
+ info="Your API key is not stored and only used for this session"
119
  )
120
+
121
  query_input = gr.Textbox(
122
+ label="Natural Language Query",
123
+ placeholder="e.g., Find all the students who scored more than 90 out of 100",
124
+ lines=3,
125
+ value="Find all the students who scored more than 90 out of 100"
126
+ )
127
+
128
+ generate_btn = gr.Button("Generate SQL Query", variant="primary", size="lg")
129
+
130
+ gr.Examples(
131
+ examples=[
132
+ ["Find all the students who scored more than 90 out of 100"],
133
+ ["Get the top 5 customers by total purchase amount"],
134
+ ["List all employees hired in the last 6 months"],
135
+ ["Find products with price between $50 and $100"],
136
+ ["Show average salary by department"]
137
+ ],
138
+ inputs=query_input,
139
+ label="Example Queries"
140
+ )
141
+
142
+ with gr.Row():
143
+ with gr.Column():
144
+ sql_output = gr.Code(
145
+ label="Generated SQL Query",
146
+ language="sql",
147
+ lines=5
148
+ )
149
+
150
+ metadata_output = gr.Textbox(
151
+ label="Query Metadata",
152
+ lines=8
153
+ )
154
+
155
+ validation_output = gr.Textbox(
156
+ label="Validation Status",
157
  lines=3
158
  )
 
159
 
160
  with gr.Row():
161
  with gr.Column():
162
+ schema_output = gr.Code(
163
+ label="Table Schema",
164
+ language="sql",
165
+ lines=8
166
+ )
167
+
168
+ with gr.Column():
169
+ sample_data_output = gr.Code(
170
+ label="Sample Data",
171
+ language="sql",
172
+ lines=8
173
+ )
174
+
175
+ with gr.Row():
176
+ execution_output = gr.Textbox(
177
+ label="Execution Results",
178
+ lines=10
179
+ )
180
 
181
+ generate_btn.click(
182
+ fn=generate_sql_query,
183
  inputs=[api_key_input, query_input],
184
+ outputs=[
185
+ sql_output,
186
+ metadata_output,
187
+ schema_output,
188
+ sample_data_output,
189
+ execution_output,
190
+ validation_output
191
+ ]
192
  )
193
 
194
+ gr.Markdown(
195
+ """
196
+ ---
197
+ ### How to use:
198
+ 1. Enter your GROQ API key (get one from [console.groq.com](https://console.groq.com))
199
+ 2. Type your natural language query description
200
+ 3. Click "Generate SQL Query" to see the results
201
+
202
+ The app will provide:
203
+ - A validated SQL query
204
+ - Table schema and sample data
205
+ - Execution results
206
+ - Optimization suggestions
207
+ """
208
+ )
209
 
210
  if __name__ == "__main__":
211
+ demo.launch(share=True)