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

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +79 -97
src/streamlit_app.py CHANGED
@@ -1,133 +1,115 @@
1
  import streamlit as st
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:
26
  st.session_state.is_db_connected = False
27
  if "connection_url" not in st.session_state:
28
  st.session_state.connection_url = ""
29
- if "chat_history" not in st.session_state:
30
- st.session_state.chat_history = []
31
 
32
- # --- SIDEBAR: DATABASE CONNECTION ---
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
39
- )
40
 
41
  if not st.session_state.is_db_connected:
42
- if st.button("Connect & Initialize", type="primary", use_container_width=True):
43
- if not db_input:
44
- st.error("Please enter a valid URL.")
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()
82
 
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.")
 
 
 
 
 
1
  import streamlit as st
2
  import requests
3
  import uuid
 
 
 
 
 
 
4
 
5
+ # 1. PAGE CONFIGURATION
6
  st.set_page_config(page_title="Text2SQL Agent", page_icon="πŸ€–", layout="centered")
7
+ st.title("πŸ—£οΈ Text2SQL Agent")
8
+ st.markdown("Connect your database and ask questions about your data in plain English.")
9
 
10
+ # 2. SESSION STATE INITIALIZATION (The Memory Bank)
 
 
 
 
 
 
 
 
 
11
  if "user_id" not in st.session_state:
12
  st.session_state.user_id = "tenant_" + str(uuid.uuid4())[:8]
13
+ if "thread_id" not in st.session_state:
14
+ st.session_state.thread_id = str(uuid.uuid4())
15
+ if "messages" not in st.session_state:
16
+ st.session_state.messages = []
17
  if "is_db_connected" not in st.session_state:
18
  st.session_state.is_db_connected = False
19
  if "connection_url" not in st.session_state:
20
  st.session_state.connection_url = ""
 
 
21
 
22
+ # 3. SIDEBAR: DATABASE CONNECTION (The Handoff to FastAPI)
23
  with st.sidebar:
24
  st.header("βš™οΈ Database Setup")
25
 
26
+ # Text input for the database URL
27
+ db_input = st.text_input("Enter Database URL:", disabled=st.session_state.is_db_connected)
 
 
28
 
29
  if not st.session_state.is_db_connected:
30
+ if st.button("Connect & Initialize"):
31
+ if db_input:
32
+ with st.spinner("Connecting to backend..."):
33
+ payload_data = {
34
+ "connection_url": db_input,
35
+ "user_id": st.session_state.user_id
36
+ }
37
+
38
  try:
39
+ # Make sure your backend endpoint is actually /upload_url
40
+ # (Check your FastAPI main.py to confirm this endpoint name!)
 
41
  response = requests.post(
42
+ "https://lightrt-text2sql-backend.hf.space/upload_url",
43
+ json=payload_data
 
 
44
  )
45
 
46
  if response.status_code == 200:
47
  st.session_state.is_db_connected = True
48
  st.session_state.connection_url = db_input
 
 
 
 
49
  st.success("Database connected securely!")
50
+ st.rerun() # Refresh to update the sidebar UI
 
 
51
  else:
52
+ st.error(f"Connection failed: {response.text}")
53
+
54
  except requests.exceptions.ConnectionError:
55
+ st.error("Cannot connect to backend. Is FastAPI running?")
56
+ else:
57
+ st.warning("Please enter a valid URL first.")
58
  else:
59
  st.success("βœ… Connected to Database")
60
  st.caption(f"URL: {st.session_state.connection_url}")
61
+ if st.button("Disconnect & Reset"):
 
62
  st.session_state.clear()
63
  st.rerun()
64
 
65
+ # 4. CHAT HISTORY RENDERING
66
+ for msg in st.session_state.messages:
67
+ with st.chat_message(msg["role"]):
68
+ st.markdown(msg["content"])
 
 
 
 
 
 
69
 
70
+ # 5. CHAT INPUT & BACKEND COMMUNICATION
71
+ # Only show chat input if the database is connected
72
+ if st.session_state.is_db_connected:
73
+ if prompt := st.chat_input("Ask a question about your data..."):
74
 
75
+ # Immediately render the user's new message to the UI
76
+ st.session_state.messages.append({"role": "user", "content": prompt})
77
+ with st.chat_message("user"):
78
+ st.markdown(prompt)
79
+
80
+ # Show a loading indicator while we wait for FastAPI
81
+ with st.chat_message("assistant"):
82
+ message_placeholder = st.empty()
83
+ message_placeholder.markdown("*(Analyzing schema and generating SQL...)*")
84
+
85
+ # Prepare the JSON payload for FastAPI
86
+ payload = {
87
+ "message": prompt,
88
+ "user_id": st.session_state.user_id,
89
+ "thread_id": st.session_state.thread_id,
90
+ "connection_url": st.session_state.connection_url
91
+ }
92
+
93
+ try:
94
+ # Send the question to your LangGraph backend
95
+ chat_response = requests.post(
96
+ "https://lightrt-text2sql-backend.hf.space/chat",
97
+ json=payload
98
+ )
99
+
100
+ if chat_response.status_code == 200:
101
+ # Extract the answer from the JSON response
102
+ answer = chat_response.json().get("response", "No response found.")
103
+
104
+ # Update the UI placeholder with the actual answer
105
+ message_placeholder.markdown(answer)
106
+
107
+ # Save the AI's answer to the session state memory
108
+ st.session_state.messages.append({"role": "assistant", "content": answer})
109
+ else:
110
+ message_placeholder.error(f"Error: {chat_response.text}")
111
+
112
+ except requests.exceptions.ConnectionError:
113
+ message_placeholder.error("Cannot connect to backend. Is FastAPI running?")
114
+ else:
115
+ st.info("πŸ‘ˆ Please connect your database in the sidebar to begin analyzing data.")