Cam commited on
Commit
604eb35
·
1 Parent(s): 9019284

adjusted app.py due to initiatlization error

Browse files
Files changed (1) hide show
  1. app.py +91 -134
app.py CHANGED
@@ -1,72 +1,21 @@
1
- import streamlit as st
2
- import os
3
- import sys
4
- import uuid
5
- import logging
6
- from pathlib import Path
7
- import subprocess
8
-
9
- # Configure page first (must be the first Streamlit command)
10
- st.set_page_config(
11
- page_title="Assurant 10-K Analysis & Risk Assessment App",
12
- page_icon="📊",
13
- layout="wide"
14
- )
15
-
16
- # Run setup script if environment variable is set
17
- if os.environ.get('STREAMLIT_RUN_SETUP', 'false').lower() == 'true':
18
- try:
19
- st.write("Setting up environment...")
20
- subprocess.call(['bash', 'setup.sh'])
21
- st.write("Setup completed!")
22
- except Exception as e:
23
- st.error(f"Setup failed: {e}")
24
-
25
- # Suppress PyTorch warnings that might appear in the console
26
- os.environ['PYTHONWARNINGS'] = 'ignore::RuntimeWarning'
27
-
28
- # Configure logging before imports
29
- logging.basicConfig(
30
- level=logging.INFO,
31
- format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
32
- handlers=[logging.StreamHandler()]
33
- )
34
- logger = logging.getLogger(__name__)
35
-
36
- # Determine the project root directory
37
- project_root = Path(__file__).parent.absolute()
38
- logger.info(f"Project root directory: {project_root}")
39
-
40
- # Add the project root to the Python path if it's not already there
41
- if str(project_root) not in sys.path:
42
- sys.path.insert(0, str(project_root))
43
- logger.info(f"Added project root to path: {project_root}")
44
-
45
- # Verify the src directory exists
46
- src_dir = project_root / "src"
47
- if not src_dir.exists():
48
- logger.error(f"Source directory not found: {src_dir}")
49
- st.error("Application structure is incorrect. The 'src' directory is missing.")
50
- else:
51
- logger.info(f"Source directory found: {src_dir}")
52
-
53
- # Import the necessary modules using direct imports
54
- try:
55
- # Use absolute imports based on the project structure
56
- from src.llamaindex_app.main import init_openai_client, setup_instrumentation, process_interaction
57
- from src.llamaindex_app.classifier import QueryClassifier
58
- from src.llamaindex_app.index_manager import IndexManager
59
- from src.llamaindex_app.config import Settings
60
- logger.info("Successfully imported all required modules")
61
- except ImportError as e:
62
- logger.error(f"Import error: {e}")
63
 
64
  def init_app():
65
  """Initialize everything just once using st.session_state."""
66
 
 
 
 
 
 
 
 
 
67
  if "initialized" not in st.session_state:
 
68
  try:
69
- st.session_state["initialized"] = True
 
70
  logger.info("Starting app initialization")
71
 
72
  # Load settings
@@ -87,21 +36,29 @@ def init_app():
87
 
88
  # (3) index manager & query engine
89
  with st.spinner("Loading index and query engine..."):
 
90
  index_manager = IndexManager(openai_client=openai_client)
91
  query_engine = index_manager.get_query_engine()
 
 
 
92
  st.session_state["query_engine"] = query_engine
93
  logger.info("Index and query engine loaded")
94
 
95
  # (4) classifier
96
  with st.spinner("Initializing query classifier..."):
97
- classifier = QueryClassifier(
98
- query_engine=query_engine,
99
- openai_client=openai_client
100
- )
101
- st.session_state["classifier"] = classifier
102
- logger.info("Query classifier initialized")
 
 
 
 
103
 
104
- st.session_state["chat_history"] = [] # store chat Q&A pairs
105
  logger.info("App initialization complete")
106
  st.success("App initialized successfully!")
107
 
@@ -115,6 +72,9 @@ def init_app():
115
 
116
  return "initialized" in st.session_state and st.session_state["initialized"]
117
 
 
 
 
118
  def main():
119
  """Main Streamlit app function."""
120
  st.title("Assurant 10-K Analysis & Risk Assessment App")
@@ -135,6 +95,10 @@ def main():
135
  # Debug section in sidebar
136
  if st.checkbox("Show debug info"):
137
  st.subheader("Debug Information")
 
 
 
 
138
  st.write("Python Path:")
139
  for path in sys.path:
140
  st.write(f"- {path}")
@@ -158,18 +122,6 @@ def main():
158
  if settings.OPENAI_ORG_ID:
159
  st.write(f"- OpenAI Organization: {settings.OPENAI_ORG_ID}")
160
 
161
- # Check if the required modules are properly imported
162
- if 'src.llamaindex_app.classifier' not in sys.modules:
163
- st.error("Failed to import required modules. Please check your project structure and try again.")
164
- st.info("""
165
- Troubleshooting steps:
166
- 1. Ensure you have proper __init__.py files in src/ and src/llamaindex_app/ directories
167
- 2. Verify that all Python modules are in the correct locations
168
- 3. Check that your imports use absolute paths (src.llamaindex_app.module)
169
- 4. Make sure all requirements are installed
170
- """)
171
- return
172
-
173
  # Initialize the app
174
  initialization_status = init_app()
175
 
@@ -178,51 +130,64 @@ def main():
178
  st.warning("Please check your environment variables and connection settings.")
179
  return
180
 
181
- # Query section
182
- st.subheader("Ask a question about Assurant's 10-K")
183
- user_question = st.text_input("Your question:", placeholder="e.g., How did Assurant perform last quarter?")
184
- submit = st.button("Submit Question")
185
-
186
- if submit and user_question.strip():
187
- # retrieve references from st.session_state
188
- query_engine = st.session_state["query_engine"]
189
- classifier = st.session_state["classifier"]
190
- tracer = st.session_state["tracer"]
191
-
192
- session_id = str(uuid.uuid4())
193
-
194
- with st.spinner("Analyzing your question..."):
195
  try:
196
- # Log the question being processed
197
- logger.info(f"Processing query: {user_question}")
 
198
 
199
- response, error = process_interaction(
200
- query_engine,
201
- classifier,
202
- tracer,
203
- user_question,
204
- session_id
205
- )
206
-
207
- # Store in st.session_state so we can display entire conversation
208
- if error:
209
- st.session_state["chat_history"].append(("user", user_question))
210
- st.session_state["chat_history"].append(("assistant", f"Error: {error}"))
211
- st.error(f"Error: {error}")
212
- logger.error(f"Query processing error: {error}")
213
- else:
214
- st.session_state["chat_history"].append(("user", user_question))
215
- st.session_state["chat_history"].append(("assistant", response.response))
216
- logger.info("Query processed successfully")
217
-
218
- # If there are any sources
219
- if getattr(response, "source_nodes", None):
220
- source_text = "\n".join(
221
- f"- {node.metadata.get('file_name', 'Unknown source')}"
222
- for node in response.source_nodes
223
- )
224
- st.session_state["chat_history"].append(("assistant_sources", source_text))
225
- logger.info(f"Found {len(response.source_nodes)} source nodes")
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  except Exception as e:
227
  st.error(f"Error processing your question: {str(e)}")
228
  logger.error(f"Process interaction error: {str(e)}", exc_info=True)
@@ -245,12 +210,4 @@ def main():
245
 
246
  # Add a separator between conversations
247
  if idx < len(st.session_state.get("chat_history", [])) - 1 and role == "assistant":
248
- st.markdown("---")
249
-
250
- if __name__ == "__main__":
251
- try:
252
- main()
253
- except Exception as e:
254
- logger.error(f"Unhandled exception in main app: {str(e)}", exc_info=True)
255
- st.error(f"An unexpected error occurred: {str(e)}")
256
- st.warning("Please check the logs for more details.")
 
1
+ # Modify the init_app function in app.py to ensure proper initialization and handling of errors:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  def init_app():
4
  """Initialize everything just once using st.session_state."""
5
 
6
+ # Initialize empty collections to prevent KeyError
7
+ if "chat_history" not in st.session_state:
8
+ st.session_state["chat_history"] = []
9
+
10
+ # Create a flag for initialization attempts
11
+ if "initialization_attempted" not in st.session_state:
12
+ st.session_state["initialization_attempted"] = False
13
+
14
  if "initialized" not in st.session_state:
15
+ st.session_state["initialization_attempted"] = True
16
  try:
17
+ # Add key presence checks before starting initialization
18
+ st.session_state["initialized"] = False # Mark as not initialized until complete
19
  logger.info("Starting app initialization")
20
 
21
  # Load settings
 
36
 
37
  # (3) index manager & query engine
38
  with st.spinner("Loading index and query engine..."):
39
+ # Create these objects explicitly
40
  index_manager = IndexManager(openai_client=openai_client)
41
  query_engine = index_manager.get_query_engine()
42
+
43
+ # Store them in session_state
44
+ st.session_state["index_manager"] = index_manager
45
  st.session_state["query_engine"] = query_engine
46
  logger.info("Index and query engine loaded")
47
 
48
  # (4) classifier
49
  with st.spinner("Initializing query classifier..."):
50
+ # Create classifier only when we are sure query_engine exists
51
+ if "query_engine" in st.session_state:
52
+ classifier = QueryClassifier(
53
+ query_engine=st.session_state["query_engine"],
54
+ openai_client=openai_client
55
+ )
56
+ st.session_state["classifier"] = classifier
57
+ logger.info("Query classifier initialized")
58
+ else:
59
+ raise ValueError("Query engine not initialized properly")
60
 
61
+ st.session_state["initialized"] = True # Now mark as fully initialized
62
  logger.info("App initialization complete")
63
  st.success("App initialized successfully!")
64
 
 
72
 
73
  return "initialized" in st.session_state and st.session_state["initialized"]
74
 
75
+
76
+ # Modify the main function to handle errors more gracefully:
77
+
78
  def main():
79
  """Main Streamlit app function."""
80
  st.title("Assurant 10-K Analysis & Risk Assessment App")
 
95
  # Debug section in sidebar
96
  if st.checkbox("Show debug info"):
97
  st.subheader("Debug Information")
98
+ st.write("Session State Keys:")
99
+ for key in st.session_state:
100
+ st.write(f"- {key}: {'Present' if st.session_state[key] is not None else 'None'}")
101
+
102
  st.write("Python Path:")
103
  for path in sys.path:
104
  st.write(f"- {path}")
 
122
  if settings.OPENAI_ORG_ID:
123
  st.write(f"- OpenAI Organization: {settings.OPENAI_ORG_ID}")
124
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  # Initialize the app
126
  initialization_status = init_app()
127
 
 
130
  st.warning("Please check your environment variables and connection settings.")
131
  return
132
 
133
+ # Safety check - if we've attempted initialization but still don't have key components
134
+ if st.session_state.get("initialization_attempted", False) and not st.session_state.get("initialized", False):
135
+ st.warning("The application is still initializing or had problems during initialization. Please wait or refresh the page.")
136
+ return
137
+
138
+ # Query section - Only show if properly initialized
139
+ if st.session_state.get("initialized", False):
140
+ st.subheader("Ask a question about Assurant's 10-K")
141
+ user_question = st.text_input("Your question:", placeholder="e.g., How did Assurant perform last quarter?")
142
+ submit = st.button("Submit Question")
143
+
144
+ if submit and user_question.strip():
145
+ # Safely retrieve references from st.session_state with error handling
 
146
  try:
147
+ # Check that all required components exist
148
+ required_keys = ["query_engine", "classifier", "tracer"]
149
+ missing_keys = [key for key in required_keys if key not in st.session_state]
150
 
151
+ if missing_keys:
152
+ st.error(f"Missing required components: {', '.join(missing_keys)}")
153
+ return
154
+
155
+ query_engine = st.session_state["query_engine"]
156
+ classifier = st.session_state["classifier"]
157
+ tracer = st.session_state["tracer"]
158
+ session_id = str(uuid.uuid4())
159
+
160
+ with st.spinner("Analyzing your question..."):
161
+ # Log the question being processed
162
+ logger.info(f"Processing query: {user_question}")
163
+
164
+ response, error = process_interaction(
165
+ query_engine,
166
+ classifier,
167
+ tracer,
168
+ user_question,
169
+ session_id
170
+ )
171
+
172
+ # Store in st.session_state so we can display entire conversation
173
+ if error:
174
+ st.session_state["chat_history"].append(("user", user_question))
175
+ st.session_state["chat_history"].append(("assistant", f"Error: {error}"))
176
+ st.error(f"Error: {error}")
177
+ logger.error(f"Query processing error: {error}")
178
+ else:
179
+ st.session_state["chat_history"].append(("user", user_question))
180
+ st.session_state["chat_history"].append(("assistant", response.response))
181
+ logger.info("Query processed successfully")
182
+
183
+ # If there are any sources
184
+ if getattr(response, "source_nodes", None):
185
+ source_text = "\n".join(
186
+ f"- {node.metadata.get('file_name', 'Unknown source')}"
187
+ for node in response.source_nodes
188
+ )
189
+ st.session_state["chat_history"].append(("assistant_sources", source_text))
190
+ logger.info(f"Found {len(response.source_nodes)} source nodes")
191
  except Exception as e:
192
  st.error(f"Error processing your question: {str(e)}")
193
  logger.error(f"Process interaction error: {str(e)}", exc_info=True)
 
210
 
211
  # Add a separator between conversations
212
  if idx < len(st.session_state.get("chat_history", [])) - 1 and role == "assistant":
213
+ st.markdown("---")