Cam commited on
Commit
eeaf8a9
·
1 Parent(s): 4972d44

change approach via applauncher

Browse files
Files changed (1) hide show
  1. app_launcher.py +217 -0
app_launcher.py ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Streamlit app launcher - A simpler wrapper to ensure proper initialization
3
+ Place this file in the root of your project directory
4
+ """
5
+ import streamlit as st
6
+ import os
7
+ import sys
8
+ import logging
9
+ from pathlib import Path
10
+ import time
11
+
12
+ # Configure page
13
+ st.set_page_config(
14
+ page_title="Assurant 10-K Analysis & Risk Assessment App",
15
+ page_icon="📊",
16
+ layout="wide"
17
+ )
18
+
19
+ # Configure logging
20
+ logging.basicConfig(
21
+ level=logging.INFO,
22
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
23
+ handlers=[logging.StreamHandler()]
24
+ )
25
+ logger = logging.getLogger(__name__)
26
+
27
+ # Add project root to path
28
+ project_root = Path(__file__).parent.absolute()
29
+ sys.path.insert(0, str(project_root))
30
+ logger.info(f"Project root: {project_root}")
31
+
32
+ # Initialize session state
33
+ if "initialized" not in st.session_state:
34
+ st.session_state["initialized"] = False
35
+ st.session_state["initialization_error"] = None
36
+ st.session_state["chat_history"] = []
37
+
38
+ def initialize_app():
39
+ """Initialize all app components safely"""
40
+ if st.session_state["initialized"]:
41
+ return True
42
+
43
+ try:
44
+ st.info("Initializing application components... This may take a moment.")
45
+
46
+ # Import key components with proper error handling
47
+ try:
48
+ from src.llamaindex_app.instrumentation import setup_instrumentation
49
+ from src.llamaindex_app.config import Settings
50
+ from src.llamaindex_app.index_manager import IndexManager
51
+ from src.llamaindex_app.classifier import QueryClassifier
52
+ from src.llamaindex_app.main import init_openai_client, process_interaction
53
+ logger.info("Successfully imported all required modules")
54
+ except ImportError as e:
55
+ logger.error(f"Import error: {e}")
56
+ st.session_state["initialization_error"] = f"Failed to import modules: {str(e)}"
57
+ return False
58
+
59
+ # Initialize step by step
60
+ # 1. Settings
61
+ settings = Settings()
62
+ st.session_state["settings"] = settings
63
+ logger.info("Settings loaded")
64
+
65
+ # 2. OpenAI client
66
+ try:
67
+ openai_client = init_openai_client()
68
+ st.session_state["openai_client"] = openai_client
69
+ logger.info("OpenAI client initialized")
70
+ except Exception as e:
71
+ logger.error(f"OpenAI client error: {e}")
72
+ st.session_state["initialization_error"] = f"OpenAI client error: {str(e)}"
73
+ return False
74
+
75
+ # 3. Instrumentation
76
+ try:
77
+ tracer_provider = setup_instrumentation()
78
+ tracer = tracer_provider.get_tracer("llamaindex_app")
79
+ st.session_state["tracer"] = tracer
80
+ logger.info("Instrumentation setup complete")
81
+ except Exception as e:
82
+ logger.error(f"Instrumentation error: {e}")
83
+ st.session_state["initialization_error"] = f"Instrumentation error: {str(e)}"
84
+ return False
85
+
86
+ # 4. Index manager and query engine (most resource-intensive step)
87
+ try:
88
+ logger.info("Creating IndexManager...")
89
+ index_manager = IndexManager(openai_client=openai_client)
90
+ logger.info("Getting query engine...")
91
+ query_engine = index_manager.get_query_engine()
92
+
93
+ # Store in session state
94
+ st.session_state["index_manager"] = index_manager
95
+ st.session_state["query_engine"] = query_engine
96
+ logger.info("Index manager and query engine initialized")
97
+ except Exception as e:
98
+ logger.error(f"Index manager error: {e}")
99
+ st.session_state["initialization_error"] = f"Index/query engine error: {str(e)}"
100
+ return False
101
+
102
+ # 5. Classifier (depends on query engine)
103
+ try:
104
+ classifier = QueryClassifier(
105
+ query_engine=query_engine,
106
+ openai_client=openai_client
107
+ )
108
+ st.session_state["classifier"] = classifier
109
+ logger.info("Query classifier initialized")
110
+ except Exception as e:
111
+ logger.error(f"Classifier error: {e}")
112
+ st.session_state["initialization_error"] = f"Classifier error: {str(e)}"
113
+ return False
114
+
115
+ # If we get here, we're fully initialized
116
+ st.session_state["initialized"] = True
117
+ logger.info("App initialization complete")
118
+ return True
119
+
120
+ except Exception as e:
121
+ logger.error(f"Unexpected initialization error: {e}", exc_info=True)
122
+ st.session_state["initialization_error"] = f"Unexpected error: {str(e)}"
123
+ return False
124
+
125
+ def main():
126
+ """Main app function"""
127
+ st.title("Assurant 10-K Analysis & Risk Assessment App")
128
+
129
+ # Initialize app
130
+ if not st.session_state["initialized"]:
131
+ with st.spinner("Setting up application components..."):
132
+ success = initialize_app()
133
+
134
+ if not success:
135
+ st.error(f"Initialization failed: {st.session_state['initialization_error']}")
136
+
137
+ # Show troubleshooting info
138
+ with st.expander("Troubleshooting information"):
139
+ st.write("Please check that:")
140
+ st.write("1. All required environment variables are set (especially OPENAI_API_KEY)")
141
+ st.write("2. Your data directory contains the necessary PDF files")
142
+ st.write("3. All dependencies are installed correctly")
143
+
144
+ # Show environment info
145
+ st.subheader("Environment")
146
+ for key, value in os.environ.items():
147
+ if key.startswith(("OPENAI_", "LLAMA_", "STREAMLIT_")):
148
+ masked_value = "****" if "KEY" in key else value
149
+ st.write(f"- {key}: {masked_value}")
150
+
151
+ return
152
+
153
+ # App successfully initialized, show the interface
154
+ with st.sidebar:
155
+ st.subheader("About this app")
156
+ st.write("""
157
+ This application analyzes Assurant's 10-K reports and provides risk assessment.
158
+
159
+ You can ask questions about:
160
+ - Assurant's financial performance
161
+ - Risk factors
162
+ - Business operations
163
+ - Market trends
164
+ """)
165
+
166
+ # Query section
167
+ st.subheader("Ask a question about Assurant's 10-K")
168
+ user_question = st.text_input("Your question:", placeholder="e.g., How did Assurant perform last quarter?")
169
+
170
+ if st.button("Submit Question") and user_question.strip():
171
+ # Get components from session state
172
+ query_engine = st.session_state["query_engine"]
173
+ classifier = st.session_state["classifier"]
174
+ tracer = st.session_state["tracer"]
175
+ session_id = str(hash(user_question))
176
+
177
+ with st.spinner("Analyzing your question..."):
178
+ from src.llamaindex_app.main import process_interaction
179
+
180
+ response, error = process_interaction(
181
+ query_engine,
182
+ classifier,
183
+ tracer,
184
+ user_question,
185
+ session_id
186
+ )
187
+
188
+ # Store in chat history
189
+ st.session_state["chat_history"].append(("user", user_question))
190
+
191
+ if error:
192
+ st.session_state["chat_history"].append(("assistant", f"Error: {error}"))
193
+ st.error(f"Error: {error}")
194
+ else:
195
+ st.session_state["chat_history"].append(("assistant", response.response))
196
+
197
+ # Store sources if available
198
+ if hasattr(response, "source_nodes") and response.source_nodes:
199
+ sources = "\n".join([
200
+ f"- {node.metadata.get('file_name', 'Unknown source')}"
201
+ for node in response.source_nodes
202
+ ])
203
+ st.session_state["chat_history"].append(("sources", sources))
204
+
205
+ # Display conversation history
206
+ st.subheader("Conversation")
207
+ for idx, (role, content) in enumerate(st.session_state["chat_history"]):
208
+ if role == "user":
209
+ st.markdown(f"**You**: {content}")
210
+ elif role == "assistant":
211
+ st.markdown(f"**Assistant**: {content}")
212
+ elif role == "sources":
213
+ with st.expander("View Sources"):
214
+ st.markdown(content)
215
+
216
+ if __name__ == "__main__":
217
+ main()