LightRT commited on
Commit
5d15658
Β·
verified Β·
1 Parent(s): 2845dc1

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +76 -84
src/streamlit_app.py CHANGED
@@ -1,134 +1,126 @@
1
  import streamlit as st
2
  import requests
3
  import uuid
 
4
  import os
5
- from dotenv import load_dotenv
6
 
7
- load_dotenv()
 
 
8
 
 
 
 
9
  HF_TOKEN = os.getenv("HF_TOKEN")
10
 
11
- # We are disguising the request to look exactly like a Google Chrome browser
12
  HEADERS = {
13
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
14
  "Accept": "application/json",
15
  "Content-Type": "application/json"
16
  }
17
 
18
- # Add the token if it exists
19
  if HF_TOKEN:
20
  HEADERS["Authorization"] = f"Bearer {HF_TOKEN}"
21
 
22
- # 1. PAGE CONFIGURATION
23
- st.set_page_config(page_title="Text2SQL Agent", page_icon="πŸ€–", layout="centered")
24
- st.title("πŸ—£οΈ Text2SQL Agent")
25
- st.markdown("Connect your database and ask questions about your data in plain English.")
 
26
 
27
- # 2. SESSION STATE INITIALIZATION (The Memory Bank)
28
- if "user_id" not in st.session_state:
29
- st.session_state.user_id = "tenant_" + str(uuid.uuid4())[:8]
30
  if "thread_id" not in st.session_state:
31
  st.session_state.thread_id = str(uuid.uuid4())
32
- if "messages" not in st.session_state:
33
- st.session_state.messages = []
34
  if "is_db_connected" not in st.session_state:
35
  st.session_state.is_db_connected = False
36
  if "connection_url" not in st.session_state:
37
  st.session_state.connection_url = ""
 
 
38
 
39
- # 3. SIDEBAR: DATABASE CONNECTION (The Handoff to FastAPI)
40
  with st.sidebar:
41
  st.header("βš™οΈ Database Setup")
42
 
43
- # Text input for the database URL
44
- db_input = st.text_input("Enter Database URL:", disabled=st.session_state.is_db_connected)
 
 
45
 
46
  if not st.session_state.is_db_connected:
47
- if st.button("Connect & Initialize"):
48
- if db_input:
49
- with st.spinner("Connecting to backend..."):
50
- payload_data = {
51
- "connection_url": db_input,
52
- "user_id": st.session_state.user_id
53
- }
54
-
55
  try:
56
- # Make sure your backend endpoint is actually /upload_url
57
- # (Check your FastAPI main.py to confirm this endpoint name!)
58
- response = requests.post(
59
- "https://lightrt-text2sql-backend.hf.space/upload_url",
60
- json=payload_data,
61
- headers=HEADERS
62
- )
63
 
64
  if response.status_code == 200:
65
  st.session_state.is_db_connected = True
66
  st.session_state.connection_url = db_input
 
 
 
67
  st.success("Database connected securely!")
68
- st.rerun() # Refresh to update the sidebar UI
 
 
69
  else:
70
- st.error(f"Connection failed: {response.text}")
71
-
72
  except requests.exceptions.ConnectionError:
73
- st.error("Cannot connect to backend. Is FastAPI running?")
74
- else:
75
- st.warning("Please enter a valid URL first.")
76
  else:
77
  st.success("βœ… Connected to Database")
78
  st.caption(f"URL: {st.session_state.connection_url}")
79
- if st.button("Disconnect & Reset"):
 
80
  st.session_state.clear()
81
  st.rerun()
82
 
83
- # 4. CHAT HISTORY RENDERING
84
- for msg in st.session_state.messages:
85
- with st.chat_message(msg["role"]):
86
- st.markdown(msg["content"])
87
 
88
- # 5. CHAT INPUT & BACKEND COMMUNICATION
89
- # Only show chat input if the database is connected
90
- if st.session_state.is_db_connected:
91
- if prompt := st.chat_input("Ask a question about your data..."):
 
 
 
 
92
 
93
- # Immediately render the user's new message to the UI
94
- st.session_state.messages.append({"role": "user", "content": prompt})
95
  with st.chat_message("user"):
96
- st.markdown(prompt)
97
-
98
- # Show a loading indicator while we wait for FastAPI
99
  with st.chat_message("assistant"):
100
- message_placeholder = st.empty()
101
- message_placeholder.markdown("*(Analyzing schema and generating SQL...)*")
102
-
103
- # Prepare the JSON payload for FastAPI
104
- payload = {
105
- "message": prompt,
106
- "user_id": st.session_state.user_id,
107
- "thread_id": st.session_state.thread_id,
108
- "connection_url": st.session_state.connection_url
109
- }
110
-
111
- try:
112
- # Send the question to your LangGraph backend
113
- chat_response = requests.post(
114
- "https://lightrt-text2sql-backend.hf.space/chat",
115
- json=payload,
116
- headers=HEADERS
117
- )
118
-
119
- if chat_response.status_code == 200:
120
- # Extract the answer from the JSON response
121
- answer = chat_response.json().get("response", "No response found.")
122
-
123
- # Update the UI placeholder with the actual answer
124
- message_placeholder.markdown(answer)
125
 
126
- # Save the AI's answer to the session state memory
127
- st.session_state.messages.append({"role": "assistant", "content": answer})
128
- else:
129
- message_placeholder.error(f"Error: {chat_response.text}")
130
 
131
- except requests.exceptions.ConnectionError:
132
- message_placeholder.error("Cannot connect to backend. Is FastAPI running?")
133
- else:
134
- st.info("πŸ‘ˆ Please connect your database in the sidebar to begin analyzing data.")
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import requests
3
  import uuid
4
+ import time
5
  import os
 
6
 
7
+ # --- CONFIGURATION ---
8
+ # Your FastAPI server URL on Hugging Face
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
+ # --- HUGGING FACE FIREWALL BYPASS (CHROME SPOOFING) ---
14
  HF_TOKEN = os.getenv("HF_TOKEN")
15
 
 
16
  HEADERS = {
17
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
18
  "Accept": "application/json",
19
  "Content-Type": "application/json"
20
  }
21
 
 
22
  if HF_TOKEN:
23
  HEADERS["Authorization"] = f"Bearer {HF_TOKEN}"
24
 
25
+ # (Optional) A quick UI check so you know the token loaded in the cloud
26
+ if not HF_TOKEN:
27
+ st.sidebar.error("⚠️ HF_TOKEN missing from Space Secrets!")
28
+ else:
29
+ st.sidebar.success("πŸ”‘ Token Loaded! Ready for cloud connection.")
30
 
31
+
32
+ # --- SESSION STATE INITIALIZATION ---
 
33
  if "thread_id" not in st.session_state:
34
  st.session_state.thread_id = str(uuid.uuid4())
35
+ if "user_id" not in st.session_state:
36
+ st.session_state.user_id = "tenant_" + str(uuid.uuid4())[:8]
37
  if "is_db_connected" not in st.session_state:
38
  st.session_state.is_db_connected = False
39
  if "connection_url" not in st.session_state:
40
  st.session_state.connection_url = ""
41
+ if "chat_history" not in st.session_state:
42
+ st.session_state.chat_history = []
43
 
44
+ # --- SIDEBAR: DATABASE CONNECTION ---
45
  with st.sidebar:
46
  st.header("βš™οΈ Database Setup")
47
 
48
+ db_input = st.text_input(
49
+ "Enter Database URL:",
50
+ disabled=st.session_state.is_db_connected
51
+ )
52
 
53
  if not st.session_state.is_db_connected:
54
+ if st.button("Connect & Initialize", type="primary", use_container_width=True):
55
+ if not db_input:
56
+ st.error("Please enter a valid URL.")
57
+ else:
58
+ with st.spinner("Building embeddings and initializing agent..."):
 
 
 
59
  try:
60
+ payload = {"connection_url": db_input, "user_id": st.session_state.user_id}
61
+
62
+ # Added headers=HEADERS here!
63
+ response = requests.post(f"{API_URL}/upload_url", json=payload, headers=HEADERS)
 
 
 
64
 
65
  if response.status_code == 200:
66
  st.session_state.is_db_connected = True
67
  st.session_state.connection_url = db_input
68
+
69
+ time.sleep(15)
70
+
71
  st.success("Database connected securely!")
72
+ st.rerun()
73
+ elif response.status_code == 429:
74
+ st.error("🚨 Rate Limited! Waiting for HF firewall cooldown.")
75
  else:
76
+ st.error(f"Failed to connect: {response.text}")
 
77
  except requests.exceptions.ConnectionError:
78
+ st.error("🚨 Cannot connect to backend. Is FastAPI running?")
 
 
79
  else:
80
  st.success("βœ… Connected to Database")
81
  st.caption(f"URL: {st.session_state.connection_url}")
82
+
83
+ if st.button("Disconnect & Reset", use_container_width=True):
84
  st.session_state.clear()
85
  st.rerun()
86
 
87
+ # --- MAIN CHAT INTERFACE ---
88
+ st.title("πŸ—£οΈ Text2SQL Agent")
 
 
89
 
90
+ if not st.session_state.is_db_connected:
91
+ st.info("πŸ‘ˆ Please connect your database in the sidebar to begin analyzing data.")
92
+ else:
93
+ for msg in st.session_state.chat_history:
94
+ with st.chat_message(msg["role"]):
95
+ st.markdown(msg["content"])
96
+
97
+ if user_query := st.chat_input("Ask a question about your data..."):
98
 
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=HEADERS here!
114
+ response = requests.post(f"{API_URL}/chat", json=payload, headers=HEADERS)
 
 
115
 
116
+ if response.status_code == 200:
117
+ answer = response.json().get("response", "No response found.")
118
+ st.markdown(answer)
119
+ st.session_state.chat_history.append({"role": "assistant", "content": answer})
120
+ elif response.status_code == 429:
121
+ st.error("🚨 Rate Limited by Hugging Face firewall.")
122
+ else:
123
+ st.error(f"Agent Error: {response.text}")
124
+
125
+ except requests.exceptions.ConnectionError:
126
+ st.error("🚨 Connection dropped. Ensure FastAPI is running.")