QuantumLearner commited on
Commit
2cbe35b
·
verified ·
1 Parent(s): 0a2ca25

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -34
app.py CHANGED
@@ -2,6 +2,7 @@ import os
2
  import nltk
3
  import requests
4
  import datetime
 
5
  # Use a directory within the user's home directory
6
  nltk_data_dir = os.path.expanduser("~/.nltk_data")
7
  os.makedirs(nltk_data_dir, exist_ok=True)
@@ -9,6 +10,7 @@ nltk.data.path.append(nltk_data_dir)
9
 
10
  # Download NLTK data
11
  nltk.download('punkt', download_dir=nltk_data_dir, quiet=True)
 
12
  import chainlit as cl
13
  from llama_index.core import VectorStoreIndex, Document
14
  from llama_index.embeddings.huggingface import HuggingFaceEmbedding
@@ -21,15 +23,15 @@ import pandas as pd
21
 
22
  load_dotenv()
23
 
24
- # Fetch the API keys from environment variables
25
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
26
  FMP_API_KEY = os.getenv("FMP_API_KEY")
27
 
28
- # Initialize models
 
 
29
  embed_model = HuggingFaceEmbedding(model_name="sentence-transformers/all-MiniLM-L6-v2")
30
  llm = Groq(model="llama3-70b-8192", api_key=GROQ_API_KEY)
31
 
32
- # Create service context
33
  service_context = ServiceContext.from_defaults(
34
  llm=llm,
35
  embed_model=embed_model,
@@ -37,27 +39,26 @@ service_context = ServiceContext.from_defaults(
37
  )
38
 
39
  def fetch_annual_report_10k(symbol: str) -> str:
40
- """
41
- Fetch the latest annual report on Form 10-K for a specific company.
42
- Args:
43
- - symbol (str): The stock ticker symbol (e.g., 'AAPL').
44
- Returns:
45
- - str: The entire JSON response as a string or an error message.
46
- """
47
  current_year = datetime.datetime.now().year
48
  url = f"https://financialmodelingprep.com/api/v4/financial-reports-json?symbol={symbol}&year={current_year}&period=FY&apikey={FMP_API_KEY}"
 
49
  try:
50
  response = requests.get(url, timeout=10)
51
  response.raise_for_status()
52
- return response.text
 
 
53
  except requests.exceptions.HTTPError as http_err:
 
54
  return f"HTTP error occurred: {http_err}"
55
  except requests.exceptions.RequestException as req_err:
 
56
  return f"Request error occurred: {req_err}"
57
  except Exception as err:
 
58
  return f"An unexpected error occurred: {err}"
59
 
60
- # Prompts
61
  summary_prompt = (
62
  "You are a world-class financial analyst with extensive experience analyzing annual reports. "
63
  "Provide a comprehensive summary of the 10-K report. Focus on Strategic Insights, Key Financial Figures, and Risk Factors. "
@@ -73,7 +74,6 @@ question_prompt = (
73
 
74
  @cl.on_chat_start
75
  async def on_chat_start():
76
- # Ask user for the ticker symbol
77
  ticker_response = await cl.AskUserMessage(
78
  content=(
79
  "This tool is designed to analyze 10-K annual reports for publicly traded companies. "
@@ -83,82 +83,83 @@ async def on_chat_start():
83
  )
84
  ).send()
85
 
86
- # Check user input
 
87
  if not ticker_response or 'content' not in ticker_response:
88
  await cl.Message(content="No ticker symbol provided. Please enter a valid ticker symbol to proceed.").send()
89
  return
90
 
91
- # Process user ticker
92
  ticker_symbol = ticker_response['content'].upper()
 
93
 
94
  msg = cl.Message(content=f"Retrieving the latest 10-K report for {ticker_symbol}...")
95
  await msg.send()
96
 
97
  try:
98
- # Fetch the 10-K report
99
  annual_report_text = fetch_annual_report_10k(ticker_symbol)
 
100
 
101
- # Check if an error or empty result is returned
102
  if annual_report_text.startswith("HTTP error") or \
103
  annual_report_text.startswith("Request error") or \
104
  annual_report_text.startswith("An unexpected error occurred"):
105
  await cl.Message(content=annual_report_text).send()
106
  return
107
 
108
- # Create a Document object with the raw JSON response
109
  document = Document(text=annual_report_text, metadata={"company": ticker_symbol})
 
110
 
111
- # Build the index
112
- index = VectorStoreIndex.from_documents(
113
- [document],
114
- service_context=service_context
115
- )
116
 
117
- # Store the index in the user session
118
  cl.user_session.set("index", index)
119
-
120
- # Run summary prompt
121
  query_engine = index.as_query_engine()
 
122
  summary_response = await cl.make_async(query_engine.query)(summary_prompt)
 
 
123
  await cl.Message(content=f"**Summary:**\n{summary_response}").send()
124
 
125
- # Run questions prompt
126
  questions_response = await cl.make_async(query_engine.query)(question_prompt)
 
 
127
  questions_format = str(questions_response).split('\n')
128
  relevant_questions = [
129
  question.strip() for question in questions_format
130
  if question.strip() and question.strip()[0].isdigit()
131
  ]
132
 
133
- # Display and answer each generated question
134
  await cl.Message(content="Generated strategic questions and answers:").send()
135
  for question in relevant_questions:
136
  await cl.Message(content=f"**{question}**").send()
137
  answer = await cl.make_async(query_engine.query)(question)
 
138
  await cl.Message(content=f"**Answer:**\n{answer}").send()
139
 
140
  msg.content = "Processing done. You can now ask more questions about the 10-K report!"
141
  await msg.update()
142
 
143
  except Exception as e:
 
144
  await cl.Message(content=f"An error occurred during processing: {str(e)}").send()
145
 
146
  @cl.on_message
147
  async def main(message: cl.Message):
148
- # Retrieve the index from user session
149
  index = cl.user_session.get("index")
150
-
151
- # If there's no index, the user hasn't entered a ticker yet
152
  if index is None:
153
  await cl.Message(content="Please provide a ticker symbol first before asking questions.").send()
154
  return
155
 
156
- # Query the index
157
  query_engine = index.as_query_engine()
158
- response = await cl.make_async(query_engine.query)(message.content)
 
 
 
 
159
 
160
- # Stream back the response
161
  response_message = cl.Message(content="")
162
  for token in str(response):
163
  await response_message.stream_token(token=token)
 
164
  await response_message.send()
 
2
  import nltk
3
  import requests
4
  import datetime
5
+
6
  # Use a directory within the user's home directory
7
  nltk_data_dir = os.path.expanduser("~/.nltk_data")
8
  os.makedirs(nltk_data_dir, exist_ok=True)
 
10
 
11
  # Download NLTK data
12
  nltk.download('punkt', download_dir=nltk_data_dir, quiet=True)
13
+
14
  import chainlit as cl
15
  from llama_index.core import VectorStoreIndex, Document
16
  from llama_index.embeddings.huggingface import HuggingFaceEmbedding
 
23
 
24
  load_dotenv()
25
 
 
26
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
27
  FMP_API_KEY = os.getenv("FMP_API_KEY")
28
 
29
+ print("DEBUG: GROQ_API_KEY ->", GROQ_API_KEY)
30
+ print("DEBUG: FMP_API_KEY ->", FMP_API_KEY)
31
+
32
  embed_model = HuggingFaceEmbedding(model_name="sentence-transformers/all-MiniLM-L6-v2")
33
  llm = Groq(model="llama3-70b-8192", api_key=GROQ_API_KEY)
34
 
 
35
  service_context = ServiceContext.from_defaults(
36
  llm=llm,
37
  embed_model=embed_model,
 
39
  )
40
 
41
  def fetch_annual_report_10k(symbol: str) -> str:
42
+ print("DEBUG: fetch_annual_report_10k called with symbol:", symbol)
 
 
 
 
 
 
43
  current_year = datetime.datetime.now().year
44
  url = f"https://financialmodelingprep.com/api/v4/financial-reports-json?symbol={symbol}&year={current_year}&period=FY&apikey={FMP_API_KEY}"
45
+ print("DEBUG: URL ->", url)
46
  try:
47
  response = requests.get(url, timeout=10)
48
  response.raise_for_status()
49
+ text_data = response.text
50
+ print("DEBUG: 10-K API response length ->", len(text_data))
51
+ return text_data
52
  except requests.exceptions.HTTPError as http_err:
53
+ print("DEBUG: HTTPError ->", http_err)
54
  return f"HTTP error occurred: {http_err}"
55
  except requests.exceptions.RequestException as req_err:
56
+ print("DEBUG: RequestError ->", req_err)
57
  return f"Request error occurred: {req_err}"
58
  except Exception as err:
59
+ print("DEBUG: UnexpectedError ->", err)
60
  return f"An unexpected error occurred: {err}"
61
 
 
62
  summary_prompt = (
63
  "You are a world-class financial analyst with extensive experience analyzing annual reports. "
64
  "Provide a comprehensive summary of the 10-K report. Focus on Strategic Insights, Key Financial Figures, and Risk Factors. "
 
74
 
75
  @cl.on_chat_start
76
  async def on_chat_start():
 
77
  ticker_response = await cl.AskUserMessage(
78
  content=(
79
  "This tool is designed to analyze 10-K annual reports for publicly traded companies. "
 
83
  )
84
  ).send()
85
 
86
+ print("DEBUG: ticker_response ->", ticker_response)
87
+
88
  if not ticker_response or 'content' not in ticker_response:
89
  await cl.Message(content="No ticker symbol provided. Please enter a valid ticker symbol to proceed.").send()
90
  return
91
 
 
92
  ticker_symbol = ticker_response['content'].upper()
93
+ print("DEBUG: ticker_symbol ->", ticker_symbol)
94
 
95
  msg = cl.Message(content=f"Retrieving the latest 10-K report for {ticker_symbol}...")
96
  await msg.send()
97
 
98
  try:
 
99
  annual_report_text = fetch_annual_report_10k(ticker_symbol)
100
+ print("DEBUG: annual_report_text snippet ->", annual_report_text[:200])
101
 
 
102
  if annual_report_text.startswith("HTTP error") or \
103
  annual_report_text.startswith("Request error") or \
104
  annual_report_text.startswith("An unexpected error occurred"):
105
  await cl.Message(content=annual_report_text).send()
106
  return
107
 
 
108
  document = Document(text=annual_report_text, metadata={"company": ticker_symbol})
109
+ print("DEBUG: Document created for ticker:", ticker_symbol)
110
 
111
+ index = VectorStoreIndex.from_documents([document], service_context=service_context)
112
+ print("DEBUG: Index built for ticker:", ticker_symbol)
 
 
 
113
 
 
114
  cl.user_session.set("index", index)
 
 
115
  query_engine = index.as_query_engine()
116
+
117
  summary_response = await cl.make_async(query_engine.query)(summary_prompt)
118
+ print("DEBUG: summary_response snippet ->", summary_response[:200])
119
+
120
  await cl.Message(content=f"**Summary:**\n{summary_response}").send()
121
 
 
122
  questions_response = await cl.make_async(query_engine.query)(question_prompt)
123
+ print("DEBUG: questions_response snippet ->", questions_response[:200])
124
+
125
  questions_format = str(questions_response).split('\n')
126
  relevant_questions = [
127
  question.strip() for question in questions_format
128
  if question.strip() and question.strip()[0].isdigit()
129
  ]
130
 
 
131
  await cl.Message(content="Generated strategic questions and answers:").send()
132
  for question in relevant_questions:
133
  await cl.Message(content=f"**{question}**").send()
134
  answer = await cl.make_async(query_engine.query)(question)
135
+ print(f"DEBUG: Answer for '{question[:30]}' snippet ->", answer[:200])
136
  await cl.Message(content=f"**Answer:**\n{answer}").send()
137
 
138
  msg.content = "Processing done. You can now ask more questions about the 10-K report!"
139
  await msg.update()
140
 
141
  except Exception as e:
142
+ print("DEBUG: Exception ->", str(e))
143
  await cl.Message(content=f"An error occurred during processing: {str(e)}").send()
144
 
145
  @cl.on_message
146
  async def main(message: cl.Message):
 
147
  index = cl.user_session.get("index")
148
+ print("DEBUG: user_session index ->", bool(index))
149
+
150
  if index is None:
151
  await cl.Message(content="Please provide a ticker symbol first before asking questions.").send()
152
  return
153
 
 
154
  query_engine = index.as_query_engine()
155
+ user_query = message.content
156
+ print("DEBUG: user_query ->", user_query)
157
+
158
+ response = await cl.make_async(query_engine.query)(user_query)
159
+ print("DEBUG: response snippet ->", str(response)[:200])
160
 
 
161
  response_message = cl.Message(content="")
162
  for token in str(response):
163
  await response_message.stream_token(token=token)
164
+
165
  await response_message.send()