File size: 11,888 Bytes
efd08fc
3e26011
 
 
 
70ea730
222f393
463ed4c
efd08fc
3e26011
44466e8
 
 
 
70ea730
 
 
463ed4c
 
 
 
 
70ea730
 
 
 
 
463ed4c
 
 
 
efd08fc
463ed4c
222f393
463ed4c
 
 
 
 
 
 
 
 
 
222f393
 
463ed4c
222f393
463ed4c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222f393
463ed4c
 
 
 
222f393
3e26011
 
463ed4c
3e26011
 
222f393
463ed4c
 
 
222f393
463ed4c
 
 
 
 
 
 
 
222f393
463ed4c
 
 
 
 
 
70ea730
 
463ed4c
 
 
70ea730
 
222f393
463ed4c
222f393
463ed4c
 
 
 
 
 
 
 
 
 
222f393
463ed4c
70ea730
 
463ed4c
 
 
 
 
 
70ea730
463ed4c
70ea730
 
463ed4c
 
3e26011
463ed4c
3e26011
463ed4c
 
 
3e26011
463ed4c
3e26011
 
70ea730
3e26011
463ed4c
 
 
222f393
 
 
463ed4c
3e26011
463ed4c
3e26011
463ed4c
3e26011
 
70ea730
 
 
222f393
70ea730
 
3e26011
463ed4c
222f393
463ed4c
222f393
463ed4c
 
 
 
222f393
463ed4c
3e26011
222f393
463ed4c
 
 
 
3e26011
463ed4c
 
 
 
 
 
 
 
3e26011
463ed4c
 
 
 
efd08fc
3e26011
 
 
 
 
 
 
 
 
efd08fc
 
3e26011
 
 
 
70ea730
 
3e26011
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463ed4c
 
 
 
 
 
 
 
 
 
222f393
3e26011
05efe29
 
 
 
 
 
 
 
 
 
 
 
3e26011
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222f393
 
463ed4c
 
 
 
3e26011
 
70ea730
 
 
 
 
463ed4c
 
 
 
 
 
 
 
222f393
 
3e26011
 
 
463ed4c
3e26011
efd08fc
3e26011
efd08fc
fc73385
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
import gradio as gr
import requests
import pandas as pd
import base64
from io import BytesIO
import json
import time
import traceback

# πŸ”§ CONFIGURE: Replace with your EC2 public IP
API_URL = "http://3.14.153.135:5000/ask"
HEALTH_URL = "http://3.14.153.135:5000/health"
SIMPLE_TEST_URL = "http://3.14.153.135:5000/simple-test"
DEBUG_URL = "http://3.14.153.135:5000/debug"

def test_connection():
    try:
        print("=== TESTING CONNECTION ===")
        response = requests.get(HEALTH_URL, timeout=30)
        print(f"Connection test status: {response.status_code}")
        print(f"Connection test response: {response.text}")
        
        if response.status_code == 200:
            return f"βœ… Connection successful! Status: {response.status_code}\nResponse: {response.text}"
        else:
            return f"⚠️ Connection returned status: {response.status_code}\nResponse: {response.text}"
    except Exception as e:
        error_msg = f"Connection error: {str(e)}"
        print(f"Connection error: {error_msg}")
        print(f"Traceback: {traceback.format_exc()}")
        return f"❌ {error_msg}"

def test_simple_endpoint():
    try:
        print("=== TESTING SIMPLE ENDPOINT ===")
        response = requests.post(
            SIMPLE_TEST_URL,
            json={"question": "test question"},
            timeout=30
        )
        
        print(f"Simple test status: {response.status_code}")
        print(f"Simple test response: {response.text}")
        
        if response.status_code == 200:
            result = response.json()
            return f"βœ… Simple test successful! SQL: {result.get('sql', 'N/A')}", None
        else:
            return f"❌ Simple test failed: {response.status_code} - {response.text}", None
    except Exception as e:
        error_msg = f"Simple test error: {str(e)}"
        print(f"Simple test error: {error_msg}")
        print(f"Traceback: {traceback.format_exc()}")
        return f"❌ {error_msg}", None

def test_debug_endpoint():
    try:
        print("=== TESTING DEBUG ENDPOINT ===")
        response = requests.post(
            DEBUG_URL,
            json={"test": "data"},
            timeout=30
        )
        
        print(f"Debug test status: {response.status_code}")
        print(f"Debug test response: {response.text}")
        
        return f"Debug response: {response.text}", None
    except Exception as e:
        error_msg = f"Debug test error: {str(e)}"
        print(f"Debug test error: {error_msg}")
        print(f"Traceback: {traceback.format_exc()}")
        return f"❌ {error_msg}", None

def query_database(question):
    if not question.strip():
        return "", None, None, "⚠️ Please enter a question.", "", ""
    
    try:
        start_time = time.time()
        print("\n" + "="*50)
        print("=== NEW QUERY REQUEST ===")
        print(f"Time: {time.strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"Question: {question}")
        print("="*50)
        
        # Prepare the request
        headers = {
            'Content-Type': 'application/json',
            'User-Agent': 'HuggingFace-Space/1.0'
        }
        payload = {"question": question}
        
        print(f"Request URL: {API_URL}")
        print(f"Request headers: {headers}")
        print(f"Request payload: {payload}")
        
        # Make the request
        print("Sending request...")
        response = requests.post(
            API_URL, 
            json=payload, 
            headers=headers,
            timeout=300
        )
        
        elapsed_time = time.time() - start_time
        print(f"\n=== RESPONSE RECEIVED ===")
        print(f"Response time: {elapsed_time:.2f} seconds")
        print(f"Response status: {response.status_code}")
        print(f"Response headers: {dict(response.headers)}")
        print(f"Response text length: {len(response.text)} characters")
        print(f"Response text: {response.text}")
        
        # Check if response is empty
        if not response.text:
            error_msg = "Empty response from server"
            print(f"ERROR: {error_msg}")
            return "", None, None, f"❌ {error_msg}", f"Request time: {elapsed_time:.2f}s", "Empty response"
        
        # Try to parse JSON response
        try:
            result = response.json()
            print(f"Parsed JSON successfully: {type(result)}")
        except json.JSONDecodeError as e:
            error_msg = f"Invalid JSON response: {str(e)}"
            print(f"ERROR: {error_msg}")
            print(f"Response text (first 500 chars): {response.text[:500]}")
            return "", None, None, f"❌ {error_msg}", f"Request time: {elapsed_time:.2f}s", "JSON parse error"
        
        # Check HTTP status
        if response.status_code != 200:
            error_msg = result.get("error", f"HTTP {response.status_code}")
            print(f"ERROR: HTTP status {response.status_code}: {error_msg}")
            return "", None, None, f"❌ Server error: {error_msg}", f"Request time: {elapsed_time:.2f}s", "HTTP error"
        
        # Check for application error
        if "error" in result:
            error_msg = result['error']
            print(f"ERROR: Application error: {error_msg}")
            return "", None, None, f"❌ {error_msg}", f"Request time: {elapsed_time:.2f}s", "Application error"
        
        # Extract data
        sql = result.get("sql", "N/A")
        rows = result.get("result", [])
        chart_data = result.get("chart")
        
        print(f"\n=== EXTRACTED DATA ===")
        print(f"SQL: {sql[:100] if sql else 'None'}...")
        print(f"Rows count: {len(rows)}")
        print(f"Chart data received: {'Yes' if chart_data else 'No'}")
        print(f"Chart data length: {len(chart_data) if chart_data else 0}")
        
        # Create DataFrame
        df = pd.DataFrame(rows) if rows else pd.DataFrame()
        print(f"DataFrame shape: {df.shape}")
        
        # Process chart
        chart_image = None
        if chart_data:
            try:
                image_bytes = base64.b64decode(chart_data)
                chart_image = BytesIO(image_bytes)
                print("Chart decoded successfully")
            except Exception as e:
                print(f"Error decoding chart: {e}")
        
        # Prepare details
        details = f"Request time: {elapsed_time:.2f}s\n"
        details += f"Status code: {response.status_code}\n"
        details += f"Rows returned: {len(rows)}\n"
        details += f"Chart generated: {'Yes' if chart_data else 'No'}\n"
        details += f"Response size: {len(response.text)} bytes"
        
        print(f"=== REQUEST COMPLETED SUCCESSFULLY ===")
        
        return sql, df, chart_image, "βœ… Query completed successfully!", details, "Success"
    
    except requests.exceptions.ConnectionError as e:
        error_msg = f"Connection failed: {str(e)}"
        print(f"CONNECTION ERROR: {error_msg}")
        print(f"Traceback: {traceback.format_exc()}")
        return "", None, None, f"❌ {error_msg}", "Connection error", "Connection error"
    except requests.exceptions.Timeout:
        error_msg = "Request timed out after 300 seconds"
        print(f"TIMEOUT ERROR: {error_msg}")
        return "", None, None, f"⏱️ {error_msg}", "Timeout error", "Timeout error"
    except requests.exceptions.RequestException as e:
        error_msg = f"Request exception: {str(e)}"
        print(f"REQUEST ERROR: {error_msg}")
        print(f"Traceback: {traceback.format_exc()}")
        return "", None, None, f"❌ {error_msg}", "Request error", "Request error"
    except Exception as e:
        error_msg = f"Unexpected error: {str(e)}"
        print(f"UNEXPECTED ERROR: {error_msg}")
        print(f"Traceback: {traceback.format_exc()}")
        return "", None, None, f"🚨 {error_msg}", f"Error: {str(e)}", "Unexpected error"

# 🎨 Theme: Enterprise Dark Blue
theme = gr.themes.Default(
    primary_hue="blue",
    secondary_hue="gray",
    neutral_hue="slate",
    font=["Inter", "sans-serif"]
).set(
    body_background_fill="*neutral_950",
    background_fill_secondary="*neutral_900"
)

# πŸš€ UI Layout
with gr.Blocks(theme=theme, title="Enterprise SQL Assistant") as demo:
    gr.HTML("""
    <div style="text-align: center; padding: 20px;">
        <h1 style="color: #3B82F6; margin-bottom: 5px;">πŸ“Š Enterprise SQL Assistant</h1>
        <p style="color: #9CA3AF; font-size: 1.1em; margin-top: 0;">
            Ask questions about your data. Get SQL, results, and insights.
        </p>
    </div>
    """)
    
    with gr.Row():
        with gr.Column(scale=1):
            gr.Markdown("### πŸ” Ask a Question")
            question_input = gr.Textbox(
                placeholder="E.g., How many members are there?",
                label="Natural Language Query",
                lines=3
            )
            submit_btn = gr.Button("πŸš€ Generate SQL & Results", variant="primary")
            
            gr.Markdown("### πŸ”§ Connection Tests")
            with gr.Accordion("Connection Tests", open=True):
                test_btn = gr.Button("Test Connection to EC2")
                connection_status = gr.Textbox(label="Connection Status", interactive=False)
                
                simple_test_btn = gr.Button("Test Simple Endpoint")
                simple_test_status = gr.Textbox(label="Simple Test Status", interactive=False)
                
                debug_test_btn = gr.Button("Test Debug Endpoint")
                debug_test_status = gr.Textbox(label="Debug Test Status", interactive=False)
            
            gr.Markdown("### πŸ’‘ Example Queries")
            gr.Markdown("""
            Try these example queries:
            
            - How many members are there?
            - What is the total transaction amount?
            - Show members with their account balances
            - Which member has the highest balance?
            - Show transaction trends over time
            - Count of members by status
            - Show me the first 10 rows
            - What is the average age of members?
            """)
        
        with gr.Column(scale=2):
            gr.Markdown("### πŸ“„ Results")
            status = gr.Textbox(label="Status", interactive=False)
            
            with gr.Tabs():
                with gr.Tab("SQL Query"):
                    sql_output = gr.Code(label="", language="sql")
                
                with gr.Tab("Data Results"):
                    results_output = gr.Dataframe(
                        label="Query Results",
                        interactive=False,
                        wrap=True
                    )
                
                with gr.Tab("Visual Insights"):
                    chart_output = gr.Image(
                        label="Chart",
                        type="pil",
                        height=400,
                        elem_classes="chart-container"
                    )
            
            gr.Markdown("### πŸ“Š Request Details")
            request_details = gr.Textbox(label="Request Details", interactive=False, lines=6)
            
            gr.Markdown("### πŸ” Error Details")
            error_details = gr.Textbox(label="Error Details", interactive=False, lines=4)
    
    # Events
    test_btn.click(
        fn=test_connection,
        outputs=[connection_status]
    )
    
    simple_test_btn.click(
        fn=test_simple_endpoint,
        outputs=[simple_test_status]
    )
    
    debug_test_btn.click(
        fn=test_debug_endpoint,
        outputs=[debug_test_status]
    )
    
    submit_btn.click(
        fn=query_database,
        inputs=question_input,
        outputs=[sql_output, results_output, chart_output, status, request_details, error_details]
    )

# Launch
if __name__ == "__main__":
    demo.launch()