LightRT commited on
Commit
867b3d0
Β·
verified Β·
1 Parent(s): d6eac0c

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +64 -45
src/streamlit_app.py CHANGED
@@ -2,16 +2,24 @@ import streamlit as st
2
  import requests
3
  import uuid
4
  import time
 
5
 
6
  # --- CONFIGURATION ---
7
- API_URL = "https://lightrt-text2sql-backend.hf.space" # Your FastAPI server URL
 
8
 
9
- st.set_page_config(page_title="Text@SQL Agent", page_icon="πŸ€–", layout="centered")
 
 
 
 
 
 
 
10
 
11
  # --- SESSION STATE INITIALIZATION ---
12
- # This ensures variables survive when Streamlit re-renders the page
13
  if "thread_id" not in st.session_state:
14
- st.session_state.thread_id = str(uuid.uuid4()) # Unique session ID for LangGraph memory
15
  if "user_id" not in st.session_state:
16
  st.session_state.user_id = "tenant_" + str(uuid.uuid4())[:8]
17
  if "is_db_connected" not in st.session_state:
@@ -25,7 +33,6 @@ if "chat_history" not in st.session_state:
25
  with st.sidebar:
26
  st.header("βš™οΈ Database Setup")
27
 
28
- # If already connected, disable the input to enforce ONE database connection
29
  db_input = st.text_input(
30
  "Enter Database URL:",
31
  disabled=st.session_state.is_db_connected
@@ -38,31 +45,37 @@ with st.sidebar:
38
  else:
39
  with st.spinner("Building embeddings and initializing agent..."):
40
  try:
41
- # 1. Hit your FastAPI upload endpoint
42
  payload = {"connection_url": db_input, "user_id": st.session_state.user_id}
43
- response = requests.post(f"{API_URL}/upload_url", json=payload)
 
 
 
 
 
 
 
44
 
45
  if response.status_code == 200:
46
- # 2. Lock the connection and unlock the chat
47
  st.session_state.is_db_connected = True
48
  st.session_state.connection_url = db_input
49
 
50
- # Because your FastAPI upload uses BackgroundTasks, it returns instantly.
51
- # We add a 2-second UI buffer here so the Qdrant embeddings have time to finish
52
- # before the user fires off their first chat question.
53
  time.sleep(15)
54
 
55
  st.success("Database connected securely!")
56
- st.rerun() # Refresh UI to unlock the chat window
 
 
57
  else:
58
- st.error(f"Failed to connect: {response.text}")
59
  except requests.exceptions.ConnectionError:
60
- st.error("🚨 Cannot connect to backend. Is FastAPI running?")
 
 
61
  else:
62
  st.success("βœ… Connected to Database")
63
  st.caption(f"URL: {st.session_state.connection_url}")
64
 
65
- # Add a reset button just in case they want to start completely over
66
  if st.button("Disconnect & Reset", use_container_width=True):
67
  st.session_state.clear()
68
  st.rerun()
@@ -70,45 +83,51 @@ with st.sidebar:
70
  # --- MAIN CHAT INTERFACE ---
71
  st.title("πŸ—£οΈ Text2SQL Agent")
72
 
73
- # The Lock: Do not render the chat if DB is not connected
74
  if not st.session_state.is_db_connected:
75
  st.info("πŸ‘ˆ Please connect your database in the sidebar to begin analyzing data.")
76
  else:
77
- # 1. Display previous chat messages from session state
78
  for msg in st.session_state.chat_history:
79
  with st.chat_message(msg["role"]):
80
  st.markdown(msg["content"])
81
 
82
- # 2. The Chat Input box
83
  if user_query := st.chat_input("Ask a question about your data..."):
84
 
85
- # Immediately display the user's question in the UI
86
- st.session_state.chat_history.append({"role": "user", "content": user_query})
87
- with st.chat_message("user"):
88
- st.markdown(user_query)
 
89
 
90
- # 3. Call the LangGraph Backend
91
- with st.chat_message("assistant"):
92
- with st.spinner("Analyzing schema and generating SQL..."):
93
- try:
94
- payload = {
95
- "message": user_query,
96
- "thread_id": st.session_state.thread_id,
97
- "user_id": st.session_state.user_id,
98
- "connection_url": st.session_state.connection_url
99
- }
100
-
101
- response = requests.post(f"{API_URL}/chat", json=payload)
102
-
103
- if response.status_code == 200:
104
- # Extract the final_result from your FastAPI JSON response
105
- answer = response.json().get("response", "No response found.")
106
- st.markdown(answer)
107
 
108
- # Save the assistant's answer to the UI history
109
- st.session_state.chat_history.append({"role": "assistant", "content": answer})
110
- else:
111
- st.error(f"Agent Error: {response.text}")
 
 
 
112
 
113
- except requests.exceptions.ConnectionError:
114
- st.error("🚨 Connection dropped. Ensure FastAPI is running.")
 
 
 
 
 
 
 
 
 
 
 
 
2
  import requests
3
  import uuid
4
  import time
5
+ import os
6
 
7
  # --- CONFIGURATION ---
8
+ # Replace this with your exact direct backend Space URL (no trailing slash)
9
+ API_URL = "https://lightrt-text2sql-backend.hf.space"
10
 
11
+ st.set_page_config(page_title="Text2SQL Agent", page_icon="πŸ€–", layout="centered")
12
+
13
+ # --- HEADERS TO BYPASS HUGGING FACE PROXY FILTERS ---
14
+ # Adding a definitive User-Agent prevents Hugging Face from flagging server-to-server calls as scraping bots
15
+ HEADERS = {
16
+ "User-Agent": "Text2SQL-Frontend-Service",
17
+ "Content-Type": "application/json"
18
+ }
19
 
20
  # --- SESSION STATE INITIALIZATION ---
 
21
  if "thread_id" not in st.session_state:
22
+ st.session_state.thread_id = str(uuid.uuid4())
23
  if "user_id" not in st.session_state:
24
  st.session_state.user_id = "tenant_" + str(uuid.uuid4())[:8]
25
  if "is_db_connected" not in st.session_state:
 
33
  with st.sidebar:
34
  st.header("βš™οΈ Database Setup")
35
 
 
36
  db_input = st.text_input(
37
  "Enter Database URL:",
38
  disabled=st.session_state.is_db_connected
 
45
  else:
46
  with st.spinner("Building embeddings and initializing agent..."):
47
  try:
 
48
  payload = {"connection_url": db_input, "user_id": st.session_state.user_id}
49
+
50
+ # Added HEADERS here
51
+ response = requests.post(
52
+ f"{API_URL}/upload_url",
53
+ json=payload,
54
+ headers=HEADERS,
55
+ timeout=30
56
+ )
57
 
58
  if response.status_code == 200:
 
59
  st.session_state.is_db_connected = True
60
  st.session_state.connection_url = db_input
61
 
62
+ # Keeping your buffer for Qdrant storage compilation
 
 
63
  time.sleep(15)
64
 
65
  st.success("Database connected securely!")
66
+ st.rerun()
67
+ elif response.status_code == 429:
68
+ st.error("🚨 Hugging Face is rate-limiting the connection. Please wait 2-3 minutes before clicking again.")
69
  else:
70
+ st.error(f"Failed to connect: {response.status_code} - {response.text}")
71
  except requests.exceptions.ConnectionError:
72
+ st.error("🚨 Cannot connect to backend. Verify your API_URL is correct and the Space is running.")
73
+ except requests.exceptions.Timeout:
74
+ st.error("🚨 Connection timed out. The backend server took too long to reply.")
75
  else:
76
  st.success("βœ… Connected to Database")
77
  st.caption(f"URL: {st.session_state.connection_url}")
78
 
 
79
  if st.button("Disconnect & Reset", use_container_width=True):
80
  st.session_state.clear()
81
  st.rerun()
 
83
  # --- MAIN CHAT INTERFACE ---
84
  st.title("πŸ—£οΈ Text2SQL Agent")
85
 
 
86
  if not st.session_state.is_db_connected:
87
  st.info("πŸ‘ˆ Please connect your database in the sidebar to begin analyzing data.")
88
  else:
89
+ # Display message history safely
90
  for msg in st.session_state.chat_history:
91
  with st.chat_message(msg["role"]):
92
  st.markdown(msg["content"])
93
 
94
+ # Chat Input Box
95
  if user_query := st.chat_input("Ask a question about your data..."):
96
 
97
+ # Guard against empty submissions triggering extra calls
98
+ if user_query.strip() != "":
99
+ st.session_state.chat_history.append({"role": "user", "content": user_query})
100
+ with st.chat_message("user"):
101
+ st.markdown(user_query)
102
 
103
+ with st.chat_message("assistant"):
104
+ with st.spinner("Analyzing schema and generating SQL..."):
105
+ try:
106
+ payload = {
107
+ "message": user_query,
108
+ "thread_id": st.session_state.thread_id,
109
+ "user_id": st.session_state.user_id,
110
+ "connection_url": st.session_state.connection_url
111
+ }
 
 
 
 
 
 
 
 
112
 
113
+ # Added HEADERS and explicit timeout handling
114
+ response = requests.post(
115
+ f"{API_URL}/chat",
116
+ json=payload,
117
+ headers=HEADERS,
118
+ timeout=60
119
+ )
120
 
121
+ if response.status_code == 200:
122
+ answer = response.json().get("response", "No response found.")
123
+ st.markdown(answer)
124
+ st.session_state.chat_history.append({"role": "assistant", "content": answer})
125
+ elif response.status_code == 429:
126
+ st.error("🚨 Rate limit tripped on Hugging Face. Give it a brief pause before submitting another question.")
127
+ else:
128
+ st.error(f"Agent Error: {response.status_code} - {response.text}")
129
+
130
+ except requests.exceptions.ConnectionError:
131
+ st.error("🚨 Connection dropped. Ensure backend Space is still awake.")
132
+ except requests.exceptions.Timeout:
133
+ st.error("🚨 The LLM execution timed out waiting for an answer.")