Mpavan45 commited on
Commit
55bc799
Β·
verified Β·
1 Parent(s): 2f11409

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +60 -65
src/streamlit_app.py CHANGED
@@ -23,8 +23,6 @@ st.markdown("""
23
  </style>
24
  """, unsafe_allow_html=True)
25
 
26
-
27
-
28
  # Header
29
  with st.container():
30
  st.markdown('<div class="header">', unsafe_allow_html=True)
@@ -36,14 +34,14 @@ with st.container():
36
  with st.sidebar:
37
  st.header("βš™οΈ Settings")
38
 
39
- # API key from Hugging Face Secrets
40
- try:
41
- GOOGLE_API_KEY = st.secrets.get["GOOGLE_API_KEY"]
42
- st.success("API Key loaded from Hugging Face Secrets!")
43
- except KeyError:
44
- st.error("Google API Key not found in Hugging Face Secrets. Please set 'GOOGLE_API_KEY'.")
45
- GOOGLE_API_KEY = None
46
 
 
 
 
 
 
47
  # Theme toggle
48
  theme = st.selectbox("Theme", ["Light", "Dark"], index=0)
49
  if theme == "Dark":
@@ -53,8 +51,6 @@ with st.sidebar:
53
  @st.cache_resource
54
  def initialize_vectorstore(_api_key):
55
  embedding = GoogleGenerativeAIEmbeddings(model="models/embedding-001", google_api_key=_api_key)
56
-
57
- # Extract chroma_db1.zip
58
  zip_path = "./chroma_db1.zip"
59
  extract_dir = "chroma_db2"
60
  if os.path.exists(zip_path):
@@ -63,54 +59,52 @@ def initialize_vectorstore(_api_key):
63
  zip_ref.extractall(extract_dir)
64
  vectorstore = Chroma(persist_directory=extract_dir, embedding_function=embedding)
65
  vectorstore.persist()
66
- if vectorstore._collection.count() > 0: # Check if DB has data
67
  return vectorstore
68
  else:
69
- st.error("Chroma DB from chroma_db1.zip is empty. Please provide a valid database.")
70
- return None
71
  except Exception as e:
72
- st.error(f"Failed to load Chroma DB from chroma_db1.zip: {str(e)}. Please check the zip file.")
73
- return None
74
  else:
75
- st.error(f"chroma_db1.zip not found at {zip_path}. Please upload the zip file.")
76
- return None
77
 
78
  # Initialize vectorstore and retriever
 
79
  if GOOGLE_API_KEY:
80
- try:
81
- vectorstore = initialize_vectorstore(GOOGLE_API_KEY)
82
- retriever = vectorstore.as_retriever(search_type="mmr", search_kwargs={"k": 3, "lambda_mult": 1}) if vectorstore else None
83
- except Exception as e:
84
- st.error(f"Error initializing vectorstore: {str(e)}")
85
- retriever = None
86
- else:
87
- retriever = None
88
 
89
  # Prompt template
90
  prompt = ChatPromptTemplate.from_messages([
91
  ("system",
92
- """
93
- You are a domain-specific AI financial analyst focused on company-level performance evaluation.
94
-
95
- Your task is to analyze and respond to user financial queries *strictly based on the provided transcript data*: {context}.
96
-
97
- Rules:
98
- 1. ONLY extract facts, figures, and insights that are explicitly available in the transcript.
99
- 2. If data is *missing or partially available*, clearly state: "The required data is not available in the current transcript."
100
- 3. Do not assume or hallucinate values. Be transparent and evidence-driven.
101
- 4. Prioritize answers for ITC Ltd., but keep the structure reusable.
102
- 5. Use bullet points or structure year-wise/metric-wise data when appropriate.
103
- """),
 
 
 
 
 
 
 
104
  ("human", "{question}")
105
  ])
106
-
107
  # LLM setup
 
108
  if GOOGLE_API_KEY:
109
  llm = ChatGoogleGenerativeAI(api_key=GOOGLE_API_KEY, model="gemini-1.5-flash", temperature=1)
110
  parser = StrOutputParser()
111
- else:
112
- llm = None
113
- parser = None
114
 
115
  # Helper functions
116
  def format_docs(docs):
@@ -125,31 +119,32 @@ def retrieve_and_answer(question):
125
  result = (prompt | llm | parser).invoke(final_input)
126
  return result, docs
127
 
128
- # Streamlit UI - Query input
129
  st.subheader("πŸ” Ask a Financial Question")
130
  with st.form(key="query_form", clear_on_submit=True):
131
  query = st.text_input("Enter your question about ITC's financials:", placeholder="e.g., What was ITC's revenue in FY 2023?")
132
  submit_button = st.form_submit_button("Get Answer")
133
 
134
- if submit_button and query.strip() and GOOGLE_API_KEY:
135
- with st.spinner("Generating answer..."):
136
- try:
137
- answer, source_docs = retrieve_and_answer(query)
138
- st.markdown('<div class="answer-box">', unsafe_allow_html=True)
139
- st.markdown("### βœ… Answer")
140
- st.markdown(answer)
141
- st.markdown('</div>', unsafe_allow_html=True)
142
-
143
- with st.expander("πŸ“„ Source Documents", expanded=False):
144
- if source_docs:
145
- for doc in source_docs:
146
- st.markdown(f"- **Source**: {doc.metadata.get('source', 'Unknown document')}")
147
- st.markdown(f" **Content**: {doc.page_content}")
148
- else:
149
- st.write("No source documents found.")
150
- except Exception as e:
151
- st.error(f"Error processing query: {str(e)}")
152
- elif submit_button and not query.strip():
153
- st.warning("Please enter a valid question.")
154
- elif submit_button and not GOOGLE_API_KEY:
155
- st.error("Please set the 'GOOGLE_API_KEY' in Hugging Face Secrets to proceed.")
 
 
23
  </style>
24
  """, unsafe_allow_html=True)
25
 
 
 
26
  # Header
27
  with st.container():
28
  st.markdown('<div class="header">', unsafe_allow_html=True)
 
34
  with st.sidebar:
35
  st.header("βš™οΈ Settings")
36
 
37
+ # Load API key securely from Hugging Face secrets
38
+ GOOGLE_API_KEY = st.secrets.get("GOOGLE_API_KEY", None)
 
 
 
 
 
39
 
40
+ if GOOGLE_API_KEY:
41
+ st.success("βœ… Google API Key loaded successfully!")
42
+ else:
43
+ st.error("❌ Google API Key not found in Hugging Face Secrets. Please set 'GOOGLE_API_KEY'.")
44
+
45
  # Theme toggle
46
  theme = st.selectbox("Theme", ["Light", "Dark"], index=0)
47
  if theme == "Dark":
 
51
  @st.cache_resource
52
  def initialize_vectorstore(_api_key):
53
  embedding = GoogleGenerativeAIEmbeddings(model="models/embedding-001", google_api_key=_api_key)
 
 
54
  zip_path = "./chroma_db1.zip"
55
  extract_dir = "chroma_db2"
56
  if os.path.exists(zip_path):
 
59
  zip_ref.extractall(extract_dir)
60
  vectorstore = Chroma(persist_directory=extract_dir, embedding_function=embedding)
61
  vectorstore.persist()
62
+ if vectorstore._collection.count() > 0:
63
  return vectorstore
64
  else:
65
+ st.error("Chroma DB is empty after extraction.")
 
66
  except Exception as e:
67
+ st.error(f"Failed to load Chroma DB: {str(e)}")
 
68
  else:
69
+ st.error(f"`chroma_db1.zip` not found at {zip_path}")
70
+ return None
71
 
72
  # Initialize vectorstore and retriever
73
+ retriever = None
74
  if GOOGLE_API_KEY:
75
+ vectorstore = initialize_vectorstore(GOOGLE_API_KEY)
76
+ if vectorstore:
77
+ retriever = vectorstore.as_retriever(search_type="mmr", search_kwargs={"k": 3, "lambda_mult": 1})
 
 
 
 
 
78
 
79
  # Prompt template
80
  prompt = ChatPromptTemplate.from_messages([
81
  ("system",
82
+ """You are a domain-specific AI financial analyst focused on company-level performance evaluation.
83
+
84
+ Your task is to analyze and respond to user financial queries strictly based on the provided transcript data: {context}.
85
+
86
+ Rules:
87
+ 1. ONLY extract facts, figures, and insights that are explicitly available in the transcript.
88
+ 2. If data is missing or partially available, clearly state: "The required data is not available in the current transcript." Then provide a generic but relevant explanation based on standard financial principles.
89
+ 3. Maintain numerical accuracy and avoid interpretation beyond data boundaries.
90
+ 4. Prioritize answers relevant to ITC Ltd., but keep response format adaptable to other firms and fiscal years.
91
+ 5. Clearly present year-wise or metric-wise insights using bullet points or structured formats if applicable.
92
+
93
+ Your goals:
94
+ - Ensure 100% fidelity to source transcript.
95
+ - Do not assume or hallucinate missing numbers.
96
+ - Use clear, reproducible reasoning steps (e.g., show which line items support your conclusion).
97
+ - Output should be modular enough to scale across other companies and time periods.
98
+
99
+ Respond only to this question from the user."""),
100
+
101
  ("human", "{question}")
102
  ])
 
103
  # LLM setup
104
+ llm, parser = None, None
105
  if GOOGLE_API_KEY:
106
  llm = ChatGoogleGenerativeAI(api_key=GOOGLE_API_KEY, model="gemini-1.5-flash", temperature=1)
107
  parser = StrOutputParser()
 
 
 
108
 
109
  # Helper functions
110
  def format_docs(docs):
 
119
  result = (prompt | llm | parser).invoke(final_input)
120
  return result, docs
121
 
122
+ # Query input form
123
  st.subheader("πŸ” Ask a Financial Question")
124
  with st.form(key="query_form", clear_on_submit=True):
125
  query = st.text_input("Enter your question about ITC's financials:", placeholder="e.g., What was ITC's revenue in FY 2023?")
126
  submit_button = st.form_submit_button("Get Answer")
127
 
128
+ if submit_button:
129
+ if not query.strip():
130
+ st.warning("Please enter a valid question.")
131
+ elif not GOOGLE_API_KEY:
132
+ st.error("Google API Key not configured. Set it in Hugging Face Secrets to proceed.")
133
+ else:
134
+ with st.spinner("Generating answer..."):
135
+ try:
136
+ answer, source_docs = retrieve_and_answer(query)
137
+ st.markdown('<div class="answer-box">', unsafe_allow_html=True)
138
+ st.markdown("### βœ… Answer")
139
+ st.markdown(answer)
140
+ st.markdown('</div>', unsafe_allow_html=True)
141
+
142
+ with st.expander("πŸ“„ Source Documents", expanded=False):
143
+ if source_docs:
144
+ for doc in source_docs:
145
+ st.markdown(f"- **Source**: {doc.metadata.get('source', 'Unknown document')}")
146
+ st.markdown(f" **Content**: {doc.page_content}")
147
+ else:
148
+ st.write("No source documents found.")
149
+ except Exception as e:
150
+ st.error(f"Error processing query: {str(e)}")