QuantumLearner commited on
Commit
0a2ca25
·
verified ·
1 Parent(s): 625aab1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -9
app.py CHANGED
@@ -2,10 +2,12 @@ import os
2
  import nltk
3
  import requests
4
  import datetime
 
5
  nltk_data_dir = os.path.expanduser("~/.nltk_data")
6
  os.makedirs(nltk_data_dir, exist_ok=True)
7
  nltk.data.path.append(nltk_data_dir)
8
 
 
9
  nltk.download('punkt', download_dir=nltk_data_dir, quiet=True)
10
  import chainlit as cl
11
  from llama_index.core import VectorStoreIndex, Document
@@ -19,12 +21,15 @@ import pandas as pd
19
 
20
  load_dotenv()
21
 
 
22
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
23
  FMP_API_KEY = os.getenv("FMP_API_KEY")
24
 
 
25
  embed_model = HuggingFaceEmbedding(model_name="sentence-transformers/all-MiniLM-L6-v2")
26
  llm = Groq(model="llama3-70b-8192", api_key=GROQ_API_KEY)
27
 
 
28
  service_context = ServiceContext.from_defaults(
29
  llm=llm,
30
  embed_model=embed_model,
@@ -32,6 +37,13 @@ service_context = ServiceContext.from_defaults(
32
  )
33
 
34
  def fetch_annual_report_10k(symbol: str) -> str:
 
 
 
 
 
 
 
35
  current_year = datetime.datetime.now().year
36
  url = f"https://financialmodelingprep.com/api/v4/financial-reports-json?symbol={symbol}&year={current_year}&period=FY&apikey={FMP_API_KEY}"
37
  try:
@@ -45,6 +57,7 @@ def fetch_annual_report_10k(symbol: str) -> str:
45
  except Exception as err:
46
  return f"An unexpected error occurred: {err}"
47
 
 
48
  summary_prompt = (
49
  "You are a world-class financial analyst with extensive experience analyzing annual reports. "
50
  "Provide a comprehensive summary of the 10-K report. Focus on Strategic Insights, Key Financial Figures, and Risk Factors. "
@@ -60,51 +73,64 @@ question_prompt = (
60
 
61
  @cl.on_chat_start
62
  async def on_chat_start():
 
63
  ticker_response = await cl.AskUserMessage(
64
  content=(
65
  "This tool is designed to analyze 10-K annual reports for publicly traded companies. "
66
  "Provide the company's ticker symbol, and the tool will fetch the latest available 10-K report. "
67
- "It generates summaries and strategic due diligence. Ask your own questions afterwards. \n\n"
68
  "Please enter the ticker symbol for the company you want to analyze (e.g. MSFT):"
69
  )
70
  ).send()
71
 
72
- # Check if ticker_response is None or lacks 'content'
73
- #if ticker_response is None or 'content' not in ticker_response:
74
  if not ticker_response or 'content' not in ticker_response:
75
  await cl.Message(content="No ticker symbol provided. Please enter a valid ticker symbol to proceed.").send()
76
  return
77
 
 
78
  ticker_symbol = ticker_response['content'].upper()
79
 
80
  msg = cl.Message(content=f"Retrieving the latest 10-K report for {ticker_symbol}...")
81
  await msg.send()
82
 
83
  try:
 
84
  annual_report_text = fetch_annual_report_10k(ticker_symbol)
85
 
 
86
  if annual_report_text.startswith("HTTP error") or \
87
  annual_report_text.startswith("Request error") or \
88
  annual_report_text.startswith("An unexpected error occurred"):
89
  await cl.Message(content=annual_report_text).send()
90
  return
91
 
 
92
  document = Document(text=annual_report_text, metadata={"company": ticker_symbol})
93
 
 
94
  index = VectorStoreIndex.from_documents(
95
- [document], service_context=service_context
 
96
  )
97
 
 
98
  cl.user_session.set("index", index)
99
 
 
100
  query_engine = index.as_query_engine()
101
  summary_response = await cl.make_async(query_engine.query)(summary_prompt)
102
  await cl.Message(content=f"**Summary:**\n{summary_response}").send()
103
 
 
104
  questions_response = await cl.make_async(query_engine.query)(question_prompt)
105
  questions_format = str(questions_response).split('\n')
106
- relevant_questions = [question.strip() for question in questions_format if question.strip() and question.strip()[0].isdigit()]
 
 
 
107
 
 
108
  await cl.Message(content="Generated strategic questions and answers:").send()
109
  for question in relevant_questions:
110
  await cl.Message(content=f"**{question}**").send()
@@ -119,18 +145,20 @@ async def on_chat_start():
119
 
120
  @cl.on_message
121
  async def main(message: cl.Message):
 
122
  index = cl.user_session.get("index")
123
 
 
124
  if index is None:
125
  await cl.Message(content="Please provide a ticker symbol first before asking questions.").send()
126
  return
127
 
 
128
  query_engine = index.as_query_engine()
129
-
130
  response = await cl.make_async(query_engine.query)(message.content)
131
-
 
132
  response_message = cl.Message(content="")
133
  for token in str(response):
134
  await response_message.stream_token(token=token)
135
-
136
- await response_message.send()
 
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)
8
  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
 
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
  )
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:
 
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
 
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. "
80
  "Provide the company's ticker symbol, and the tool will fetch the latest available 10-K report. "
81
+ "It generates summaries and strategic due diligence. Ask your own questions afterwards.\n\n"
82
  "Please enter the ticker symbol for the company you want to analyze (e.g. MSFT):"
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()
 
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()