bharathmunakala commited on
Commit
5b41dc3
Β·
verified Β·
1 Parent(s): 888ae20

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +130 -45
app.py CHANGED
@@ -1,6 +1,5 @@
1
-
2
  import sqlite3
3
-
4
  import os
5
  import streamlit as st
6
  import chromadb
@@ -12,28 +11,41 @@ from llama_index.vector_stores.chroma import ChromaVectorStore
12
  from llama_index.llms.groq import Groq
13
  from llama_index.embeddings.cohere import CohereEmbedding
14
 
 
 
15
 
16
- from arize.otel import register
17
- from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
18
 
19
- # Setup OTel via Arize's convenience function
20
- tracer_provider = register(
21
- space_id=os.getenv("ARIZE_SPACE_ID"),
22
- api_key=os.getenv("ARIZE_API_KEY"),
23
- project_name="rbacrag" # Choose a project name
24
- )
25
-
26
- # Instrument LlamaIndex
27
- LlamaIndexInstrumentor().instrument(tracer_provider=tracer_provider)
 
 
 
 
 
 
 
28
 
29
  # Import database module
30
  from database import db, initialize_users
31
 
32
- # Load environment variables
33
- load_dotenv()
34
-
35
- # Initialize default users
36
- initialize_users()
 
 
 
 
37
 
38
  # Role-based access control for documents
39
  ROLE_ACCESS = {
@@ -43,7 +55,6 @@ ROLE_ACCESS = {
43
  "marketing": ["marketing", "general"]
44
  }
45
 
46
- # Initialize session state
47
  def initialize_session_state():
48
  """Initialize or reset the session state"""
49
  if "authenticated" not in st.session_state:
@@ -70,7 +81,6 @@ st.set_page_config(
70
  # Initialize session state
71
  initialize_session_state()
72
 
73
- # Authentication functions
74
  def login(username: str, password: str) -> bool:
75
  """
76
  Authenticate user and set session state
@@ -91,7 +101,7 @@ def login(username: str, password: str) -> bool:
91
  st.session_state.messages = [
92
  {"role": "assistant", "content": f"Welcome, {user['username']}! How can I assist you today?"}
93
  ]
94
- st.rerun() # Rerun to update the UI
95
  return True
96
  return False
97
  except Exception as e:
@@ -99,23 +109,23 @@ def login(username: str, password: str) -> bool:
99
  return False
100
 
101
  def logout():
102
- """
103
- Log out the current user and clear session state
104
- """
105
  username = st.session_state.get('username', 'Unknown')
106
  st.session_state.clear()
107
  initialize_session_state()
108
  st.success(f"Successfully logged out {username}")
109
- st.rerun() # Rerun to update the UI
110
 
111
  @st.cache_resource
112
  def load_vector_index(role: str):
113
- """Load the ChromaDB index for the user's role"""
114
  try:
115
  # Initialize Cohere embeddings
116
  cohere_api_key = os.getenv("COHERE_API_KEY")
117
  if not cohere_api_key:
118
- raise ValueError("COHERE_API_KEY not found in environment variables")
 
 
119
 
120
  embed_model = CohereEmbedding(
121
  cohere_api_key=cohere_api_key,
@@ -124,12 +134,59 @@ def load_vector_index(role: str):
124
  )
125
  Settings.embed_model = embed_model
126
 
127
- # Initialize Chroma client
128
  persist_dir = f"./chroma_db/{role}"
129
- chroma_client = chromadb.PersistentClient(path=persist_dir)
130
 
131
- # Get the collection
132
- chroma_collection = chroma_client.get_collection("documents")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
  # Create vector store
135
  vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
@@ -137,22 +194,36 @@ def load_vector_index(role: str):
137
  # Create storage context
138
  storage_context = StorageContext.from_defaults(vector_store=vector_store)
139
 
140
- # Load the index
141
- index = VectorStoreIndex.from_vector_store(
142
- vector_store=vector_store,
143
- storage_context=storage_context,
144
- embed_model=embed_model
145
- )
 
 
 
 
 
 
 
 
146
 
147
  return index
 
148
  except Exception as e:
149
- st.error(f"Error loading vector index: {str(e)}")
 
 
 
 
 
150
  st.stop()
151
 
152
  def chat_interface():
153
  """Main chat interface"""
154
  # Add styled heading
155
- st.markdown(f"<h2 style='color: #1407fa;'>πŸ’¬ {st.session_state.role.capitalize()} Department Chat</h3>", unsafe_allow_html=True)
156
 
157
  # Display chat messages
158
  for message in st.session_state.messages:
@@ -164,9 +235,15 @@ def chat_interface():
164
 
165
  # Initialize Groq LLM
166
  try:
 
 
 
 
 
 
167
  llm = Groq(
168
  model="llama3-8b-8192",
169
- api_key=os.getenv("GROQ_API_KEY"),
170
  temperature=0.5,
171
  system_prompt=f"You are a helpful assistant specialized in {st.session_state.role} department documents. Answer the user queries with the help of the provided context with high accuracy and precision."
172
  )
@@ -178,8 +255,8 @@ def chat_interface():
178
  response_mode="compact"
179
  )
180
  except Exception as e:
181
- st.error(f"Error initializing LLM: {str(e)}")
182
- st.warning("Falling back to default LLM settings. Some features may be limited.")
183
  query_engine = index.as_query_engine(
184
  similarity_top_k=3,
185
  response_mode="compact"
@@ -205,7 +282,7 @@ def chat_interface():
205
  full_response = str(response)
206
  message_placeholder.markdown(full_response)
207
  except Exception as e:
208
- error_msg = f"Error generating response: {str(e)}"
209
  message_placeholder.error(error_msg)
210
  full_response = error_msg
211
 
@@ -284,7 +361,6 @@ def show_login_form():
284
 
285
  st.markdown('<p style="text-align: center; margin-top: 2rem; color: #a0a0b0;">2025 Department RAG System</p>', unsafe_allow_html=True)
286
 
287
-
288
  def main():
289
  """
290
  Main application entry point
@@ -292,7 +368,6 @@ def main():
292
  """
293
  # Sidebar for logout and user info
294
  if st.session_state.authenticated:
295
- st.set_page_config(layout="wide", initial_sidebar_state="expanded")
296
  with st.sidebar:
297
  st.markdown(f"### Welcome, {st.session_state.username}")
298
  st.markdown(f"**Role:** {st.session_state.role.capitalize()}")
@@ -307,6 +382,16 @@ def main():
307
  This is a secure departmental RAG system that provides
308
  role-based access to information across different departments.
309
  """)
 
 
 
 
 
 
 
 
 
 
310
 
311
  # Main content area
312
  if not st.session_state.authenticated:
 
1
+ # app.py - Fixed version with proper error handling
2
  import sqlite3
 
3
  import os
4
  import streamlit as st
5
  import chromadb
 
11
  from llama_index.llms.groq import Groq
12
  from llama_index.embeddings.cohere import CohereEmbedding
13
 
14
+ # Load environment variables first
15
+ load_dotenv()
16
 
17
+ # Disable ChromaDB telemetry to remove the warning
18
+ os.environ["ANONYMIZED_TELEMETRY"] = "False"
19
 
20
+ # Setup OTel via Arize's convenience function with error handling
21
+ try:
22
+ from arize.otel import register
23
+ from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
24
+
25
+ if os.getenv("ARIZE_SPACE_ID") and os.getenv("ARIZE_API_KEY"):
26
+ tracer_provider = register(
27
+ space_id=os.getenv("ARIZE_SPACE_ID"),
28
+ api_key=os.getenv("ARIZE_API_KEY"),
29
+ project_name="rbacrag"
30
+ )
31
+ LlamaIndexInstrumentor().instrument(tracer_provider=tracer_provider)
32
+ else:
33
+ print("Arize credentials not found, skipping instrumentation")
34
+ except Exception as e:
35
+ print(f"Warning: Arize instrumentation failed: {e}")
36
 
37
  # Import database module
38
  from database import db, initialize_users
39
 
40
+ # Initialize default users with better error handling
41
+ try:
42
+ success_count, error_count = initialize_users()
43
+ if error_count > 0:
44
+ print(f"Database initialization completed with {error_count} errors (likely users already exist)")
45
+ else:
46
+ print(f"Database initialization successful: {success_count} users ready")
47
+ except Exception as e:
48
+ print(f"Error during user initialization: {e}")
49
 
50
  # Role-based access control for documents
51
  ROLE_ACCESS = {
 
55
  "marketing": ["marketing", "general"]
56
  }
57
 
 
58
  def initialize_session_state():
59
  """Initialize or reset the session state"""
60
  if "authenticated" not in st.session_state:
 
81
  # Initialize session state
82
  initialize_session_state()
83
 
 
84
  def login(username: str, password: str) -> bool:
85
  """
86
  Authenticate user and set session state
 
101
  st.session_state.messages = [
102
  {"role": "assistant", "content": f"Welcome, {user['username']}! How can I assist you today?"}
103
  ]
104
+ st.rerun()
105
  return True
106
  return False
107
  except Exception as e:
 
109
  return False
110
 
111
  def logout():
112
+ """Log out the current user and clear session state"""
 
 
113
  username = st.session_state.get('username', 'Unknown')
114
  st.session_state.clear()
115
  initialize_session_state()
116
  st.success(f"Successfully logged out {username}")
117
+ st.rerun()
118
 
119
  @st.cache_resource
120
  def load_vector_index(role: str):
121
+ """Load the ChromaDB index for the user's role with enhanced error handling"""
122
  try:
123
  # Initialize Cohere embeddings
124
  cohere_api_key = os.getenv("COHERE_API_KEY")
125
  if not cohere_api_key:
126
+ st.error("❌ COHERE_API_KEY not found in environment variables")
127
+ st.info("Please set your Cohere API key in the .env file")
128
+ st.stop()
129
 
130
  embed_model = CohereEmbedding(
131
  cohere_api_key=cohere_api_key,
 
134
  )
135
  Settings.embed_model = embed_model
136
 
137
+ # Docker-compatible ChromaDB initialization
138
  persist_dir = f"./chroma_db/{role}"
 
139
 
140
+ # Ensure directory exists
141
+ Path(persist_dir).mkdir(parents=True, exist_ok=True)
142
+
143
+ # Initialize Chroma client with telemetry disabled
144
+ try:
145
+ chroma_client = chromadb.PersistentClient(
146
+ path=persist_dir,
147
+ settings=chromadb.Settings(
148
+ anonymized_telemetry=False,
149
+ allow_reset=True
150
+ )
151
+ )
152
+ except Exception as e:
153
+ st.warning(f"Failed to connect to persistent ChromaDB: {e}")
154
+ st.info("Attempting to create new collection...")
155
+
156
+ # Try to reset and recreate
157
+ try:
158
+ chroma_client = chromadb.PersistentClient(path=persist_dir)
159
+ chroma_client.reset()
160
+ chroma_client = chromadb.PersistentClient(
161
+ path=persist_dir,
162
+ settings=chromadb.Settings(
163
+ anonymized_telemetry=False,
164
+ allow_reset=True
165
+ )
166
+ )
167
+ except:
168
+ # Fallback to in-memory client
169
+ st.warning("⚠️ Using in-memory ChromaDB (data will not persist)")
170
+ chroma_client = chromadb.Client(
171
+ settings=chromadb.Settings(anonymized_telemetry=False)
172
+ )
173
+
174
+ # Try to get existing collection, create if it doesn't exist
175
+ collection_name = "documents"
176
+ try:
177
+ chroma_collection = chroma_client.get_collection(collection_name)
178
+ st.success(f"βœ… Connected to existing collection for {role} role")
179
+ except Exception:
180
+ st.warning(f"⚠️ Collection '{collection_name}' not found for role '{role}'. Creating empty collection.")
181
+ try:
182
+ chroma_collection = chroma_client.create_collection(
183
+ name=collection_name,
184
+ metadata={"hnsw:space": "cosine"}
185
+ )
186
+ st.info("πŸ“ Created new empty collection. You may need to add documents first.")
187
+ except Exception as create_error:
188
+ st.error(f"❌ Failed to create collection: {create_error}")
189
+ st.stop()
190
 
191
  # Create vector store
192
  vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
 
194
  # Create storage context
195
  storage_context = StorageContext.from_defaults(vector_store=vector_store)
196
 
197
+ # Check if collection has documents
198
+ if chroma_collection.count() == 0:
199
+ st.warning(f"πŸ“­ No documents found in {role} collection.")
200
+ st.info("The system will work, but responses will be limited without documents.")
201
+ # Create empty index for now
202
+ index = VectorStoreIndex([], storage_context=storage_context, embed_model=embed_model)
203
+ else:
204
+ st.info(f"πŸ“š Found {chroma_collection.count()} documents in {role} collection")
205
+ # Load the index
206
+ index = VectorStoreIndex.from_vector_store(
207
+ vector_store=vector_store,
208
+ storage_context=storage_context,
209
+ embed_model=embed_model
210
+ )
211
 
212
  return index
213
+
214
  except Exception as e:
215
+ st.error(f"❌ Error loading vector index: {str(e)}")
216
+ st.info("**Possible solutions:**")
217
+ st.info("1. Check that ChromaDB collections exist for this role")
218
+ st.info("2. Verify database files are properly mounted in Docker")
219
+ st.info("3. Check permissions on the database directory")
220
+ st.info("4. Ensure COHERE_API_KEY is set correctly")
221
  st.stop()
222
 
223
  def chat_interface():
224
  """Main chat interface"""
225
  # Add styled heading
226
+ st.markdown(f"<h2 style='color: #1407fa;'>πŸ’¬ {st.session_state.role.capitalize()} Department Chat</h2>", unsafe_allow_html=True)
227
 
228
  # Display chat messages
229
  for message in st.session_state.messages:
 
235
 
236
  # Initialize Groq LLM
237
  try:
238
+ groq_api_key = os.getenv("GROQ_API_KEY")
239
+ if not groq_api_key:
240
+ st.error("❌ GROQ_API_KEY not found in environment variables")
241
+ st.info("Please set your Groq API key in the .env file")
242
+ st.stop()
243
+
244
  llm = Groq(
245
  model="llama3-8b-8192",
246
+ api_key=groq_api_key,
247
  temperature=0.5,
248
  system_prompt=f"You are a helpful assistant specialized in {st.session_state.role} department documents. Answer the user queries with the help of the provided context with high accuracy and precision."
249
  )
 
255
  response_mode="compact"
256
  )
257
  except Exception as e:
258
+ st.error(f"❌ Error initializing LLM: {str(e)}")
259
+ st.warning("⚠️ Falling back to default LLM settings. Some features may be limited.")
260
  query_engine = index.as_query_engine(
261
  similarity_top_k=3,
262
  response_mode="compact"
 
282
  full_response = str(response)
283
  message_placeholder.markdown(full_response)
284
  except Exception as e:
285
+ error_msg = f"❌ Error generating response: {str(e)}"
286
  message_placeholder.error(error_msg)
287
  full_response = error_msg
288
 
 
361
 
362
  st.markdown('<p style="text-align: center; margin-top: 2rem; color: #a0a0b0;">2025 Department RAG System</p>', unsafe_allow_html=True)
363
 
 
364
  def main():
365
  """
366
  Main application entry point
 
368
  """
369
  # Sidebar for logout and user info
370
  if st.session_state.authenticated:
 
371
  with st.sidebar:
372
  st.markdown(f"### Welcome, {st.session_state.username}")
373
  st.markdown(f"**Role:** {st.session_state.role.capitalize()}")
 
382
  This is a secure departmental RAG system that provides
383
  role-based access to information across different departments.
384
  """)
385
+
386
+ # Show database status
387
+ try:
388
+ users = db.list_users()
389
+ st.markdown("---")
390
+ st.markdown("### System Status")
391
+ st.markdown(f"βœ… Database: {len(users)} users")
392
+ st.markdown("βœ… Authentication: Active")
393
+ except:
394
+ st.markdown("⚠️ Database: Connection issues")
395
 
396
  # Main content area
397
  if not st.session_state.authenticated: