walaa2022 commited on
Commit
35acd3c
·
verified ·
1 Parent(s): 0ff54a0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +195 -124
app.py CHANGED
@@ -2,116 +2,172 @@ import gradio as gr
2
  import pandas as pd
3
  from transformers import pipeline
4
  import torch
5
- import PyPDF2
 
6
  import io
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  class FinancialAnalyzer:
9
  def __init__(self):
10
- """Initialize models"""
11
- # 1. Llama 2 for strategic analysis
12
- self.strategic_analyzer = pipeline(
13
- "text-generation",
14
- model="meta-llama/Llama-2-7b-chat-hf",
15
- device_map="auto"
16
- )
17
-
18
- # 2. FinBERT for financial sentiment
19
- self.financial_analyzer = pipeline(
20
- "text-classification",
21
- model="ProsusAI/finbert",
22
- return_all_scores=True
23
- )
24
-
25
- # 3. Falcon for recommendations
26
- self.recommendation_generator = pipeline(
27
- "text-generation",
28
- model="tiiuae/falcon-7b-instruct",
29
- device_map="auto"
30
- )
 
 
 
 
 
 
 
 
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  def extract_text_from_pdf(self, pdf_file):
33
- """Extract text from PDF file"""
 
 
 
 
34
  try:
35
- pdf_reader = PyPDF2.PdfReader(pdf_file)
 
 
36
  text = ""
37
  for page in pdf_reader.pages:
38
  text += page.extract_text() + "\n"
39
  return text
40
  except Exception as e:
41
- print(f"Error extracting PDF text: {str(e)}")
42
- return None
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  def generate_strategic_analysis(self, financial_data, kpi_data=None):
45
  """Generate strategic analysis using Llama 2"""
46
- # Include KPI data if available
47
- kpi_section = f"\nKPI Information:\n{kpi_data}" if kpi_data else ""
48
-
49
- prompt = f"""[INST] As a senior financial analyst, analyze these financial statements and KPIs:
 
50
 
51
- Financial Data:
52
- {financial_data}
53
- {kpi_section}
54
 
55
- Provide a comprehensive analysis including:
56
- 1. Business Health Assessment
57
- 2. Key Strategic Insights
58
- 3. Market Position Analysis
59
- 4. Growth Opportunities
60
- 5. Risk Factors
61
- 6. KPI Performance and Trends
62
- 7. Financial Ratio Analysis
63
- 8. Operational Efficiency Assessment [/INST]"""
64
-
65
- response = self.strategic_analyzer(
66
- prompt,
67
- max_length=1500, # Increased for more comprehensive analysis
68
- temperature=0.7
69
- )
70
- return response[0]['generated_text']
71
 
72
  def analyze_sentiment(self, text):
73
  """Analyze financial sentiment using FinBERT"""
74
- return self.financial_analyzer(text)
 
 
 
 
75
 
76
- def generate_recommendations(self, analysis, kpi_data=None):
77
  """Generate recommendations using Falcon"""
78
- kpi_context = f"\nKPI Context:\n{kpi_data}" if kpi_data else ""
79
-
80
- prompt = f"""Based on this financial analysis and KPI data:
81
- {analysis}
82
- {kpi_context}
83
-
84
- Provide specific, actionable recommendations covering:
85
- 1. Strategic Initiatives
86
- 2. Operational Improvements
87
- 3. Financial Management
88
- 4. Risk Mitigation
89
- 5. Growth Strategy
90
- 6. KPI Optimization
91
- 7. Performance Enhancement
92
- 8. Resource Allocation"""
93
-
94
- response = self.recommendation_generator(
95
- prompt,
96
- max_length=1000,
97
- temperature=0.6
98
- )
99
- return response[0]['generated_text']
100
 
101
  def analyze_financial_statements(income_statement, balance_sheet, kpi_pdf=None):
102
- """Main analysis function"""
103
  try:
104
- # Read financial statements
105
- income_df = pd.read_csv(income_statement.name)
106
- balance_df = pd.read_csv(balance_sheet.name)
107
-
108
  # Initialize analyzer
109
  analyzer = FinancialAnalyzer()
110
 
111
- # Extract KPI data if provided
112
- kpi_data = None
113
- if kpi_pdf:
114
- kpi_data = analyzer.extract_text_from_pdf(kpi_pdf.name)
115
 
116
  # Prepare financial data
117
  financial_data = f"""
@@ -122,47 +178,61 @@ def analyze_financial_statements(income_statement, balance_sheet, kpi_pdf=None):
122
  {balance_df.to_string()}
123
  """
124
 
125
- # Generate strategic analysis
126
- strategic_analysis = analyzer.generate_strategic_analysis(financial_data, kpi_data)
 
 
 
127
 
128
- # Analyze sentiment
 
 
129
  sentiment = analyzer.analyze_sentiment(strategic_analysis)
130
-
131
- # Generate recommendations
132
- recommendations = analyzer.generate_recommendations(strategic_analysis, kpi_data)
133
 
134
  # Format output
135
- output = format_results(strategic_analysis, sentiment, recommendations, kpi_data)
136
-
137
- return output
138
 
139
  except Exception as e:
140
- return f"Error analyzing files: {str(e)}"
 
 
 
 
 
 
 
 
141
 
142
  def format_results(analysis, sentiment, recommendations, kpi_data=None):
143
  """Format analysis results"""
144
- output = "# Financial Analysis Report\n\n"
145
-
146
- # Strategic Analysis
147
- output += "## Strategic Analysis\n\n"
148
- output += analysis.split('[/INST]')[-1].strip() + "\n\n"
149
-
150
- # KPI Analysis (if available)
151
- if kpi_data:
152
- output += "## KPI Analysis\n\n"
153
- output += "Analysis includes KPI data from provided documentation.\n\n"
154
-
155
- # Sentiment Analysis
156
- output += "## Market Sentiment\n\n"
157
- for score in sentiment[0]:
158
- output += f"- {score['label']}: {score['score']:.2%}\n"
159
- output += "\n"
160
-
161
- # Recommendations
162
- output += "## Strategic Recommendations\n\n"
163
- output += recommendations
164
-
165
- return output
 
 
 
 
166
 
167
  # Create Gradio interface
168
  iface = gr.Interface(
@@ -170,28 +240,29 @@ iface = gr.Interface(
170
  inputs=[
171
  gr.File(label="Income Statement (CSV)"),
172
  gr.File(label="Balance Sheet (CSV)"),
173
- gr.File(label="KPI Documentation (PDF, Optional)", file_types=[".pdf"])
 
 
174
  ],
175
  outputs=gr.Markdown(),
176
  title="AI-Powered Financial Statement Analysis",
177
- description="""Upload your financial statements and optional KPI documentation for comprehensive analysis using:
178
  - Llama 2: Strategic Analysis
179
  - FinBERT: Financial Sentiment Analysis
180
- - Falcon: Strategic Recommendations
181
-
182
- Supports:
183
- - Income Statement (CSV)
184
- - Balance Sheet (CSV)
185
- - KPI Documentation (PDF)""",
186
  examples=[
187
  [
188
  "OFINTECH-Income Statement-template.csv",
189
  "OFINTECH Balance Sheet template.csv",
190
- None # Optional KPI PDF
191
  ]
192
  ]
193
  )
194
 
195
  # Launch the interface
196
  if __name__ == "__main__":
197
- iface.launch()
 
 
 
 
 
2
  import pandas as pd
3
  from transformers import pipeline
4
  import torch
5
+ import sys
6
+ import logging
7
  import io
8
 
9
+ # Setup logging
10
+ logging.basicConfig(level=logging.INFO)
11
+ logger = logging.getLogger(__name__)
12
+
13
+ # Try importing PyPDF2
14
+ try:
15
+ import PyPDF2
16
+ logger.info("PyPDF2 imported successfully")
17
+ except ImportError as e:
18
+ logger.error(f"Error importing PyPDF2: {str(e)}")
19
+ logger.info("Falling back to text-only mode")
20
+ PyPDF2 = None
21
+
22
  class FinancialAnalyzer:
23
  def __init__(self):
24
+ """Initialize models with error handling"""
25
+ try:
26
+ # 1. Llama 2 for strategic analysis
27
+ self.strategic_analyzer = pipeline(
28
+ "text-generation",
29
+ model="meta-llama/Llama-2-7b-chat-hf",
30
+ device_map="auto"
31
+ )
32
+ logger.info("Llama 2 initialized successfully")
33
+
34
+ # 2. FinBERT for financial sentiment
35
+ self.financial_analyzer = pipeline(
36
+ "text-classification",
37
+ model="ProsusAI/finbert",
38
+ return_all_scores=True
39
+ )
40
+ logger.info("FinBERT initialized successfully")
41
+
42
+ # 3. Falcon for recommendations
43
+ self.recommendation_generator = pipeline(
44
+ "text-generation",
45
+ model="tiiuae/falcon-7b-instruct",
46
+ device_map="auto"
47
+ )
48
+ logger.info("Falcon initialized successfully")
49
+
50
+ except Exception as e:
51
+ logger.error(f"Error initializing models: {str(e)}")
52
+ raise
53
 
54
+ def read_file(self, file_obj):
55
+ """Safely read file content"""
56
+ try:
57
+ # If file_obj is a string (file path)
58
+ if isinstance(file_obj, str):
59
+ return open(file_obj, 'rb')
60
+ # If file_obj is bytes
61
+ elif isinstance(file_obj, bytes):
62
+ return io.BytesIO(file_obj)
63
+ # If file_obj is already a file object
64
+ elif hasattr(file_obj, 'read'):
65
+ return file_obj
66
+ else:
67
+ raise ValueError(f"Unsupported file object type: {type(file_obj)}")
68
+ except Exception as e:
69
+ logger.error(f"Error reading file: {str(e)}")
70
+ raise
71
+
72
  def extract_text_from_pdf(self, pdf_file):
73
+ """Extract text from PDF file with fallback"""
74
+ if PyPDF2 is None:
75
+ logger.warning("PyPDF2 not available, skipping PDF processing")
76
+ return "PDF processing not available"
77
+
78
  try:
79
+ # Handle the file object properly
80
+ pdf_file_obj = self.read_file(pdf_file)
81
+ pdf_reader = PyPDF2.PdfReader(pdf_file_obj)
82
  text = ""
83
  for page in pdf_reader.pages:
84
  text += page.extract_text() + "\n"
85
  return text
86
  except Exception as e:
87
+ logger.error(f"Error extracting PDF text: {str(e)}")
88
+ return "Error processing PDF"
89
+
90
+ def read_csv_file(self, file_obj):
91
+ """Safely read CSV file"""
92
+ try:
93
+ # Handle the file object properly
94
+ if isinstance(file_obj, (str, bytes)):
95
+ return pd.read_csv(self.read_file(file_obj))
96
+ return pd.read_csv(file_obj)
97
+ except Exception as e:
98
+ logger.error(f"Error reading CSV file: {str(e)}")
99
+ raise
100
 
101
  def generate_strategic_analysis(self, financial_data, kpi_data=None):
102
  """Generate strategic analysis using Llama 2"""
103
+ try:
104
+ # Include KPI data if available
105
+ kpi_section = f"\nKPI Information:\n{kpi_data}" if kpi_data else ""
106
+
107
+ prompt = f"""[INST] As a senior financial analyst, analyze these financial statements:
108
 
109
+ Financial Data:
110
+ {financial_data}
111
+ {kpi_section}
112
 
113
+ Provide:
114
+ 1. Business Health Assessment
115
+ 2. Key Strategic Insights
116
+ 3. Market Position Analysis
117
+ 4. Growth Opportunities
118
+ 5. Risk Factors [/INST]"""
119
+
120
+ response = self.strategic_analyzer(
121
+ prompt,
122
+ max_length=1000,
123
+ temperature=0.7
124
+ )
125
+ return response[0]['generated_text']
126
+ except Exception as e:
127
+ logger.error(f"Error in strategic analysis: {str(e)}")
128
+ return "Error generating strategic analysis"
129
 
130
  def analyze_sentiment(self, text):
131
  """Analyze financial sentiment using FinBERT"""
132
+ try:
133
+ return self.financial_analyzer(text)
134
+ except Exception as e:
135
+ logger.error(f"Error in sentiment analysis: {str(e)}")
136
+ return [{"label": "error", "score": 1.0}]
137
 
138
+ def generate_recommendations(self, analysis):
139
  """Generate recommendations using Falcon"""
140
+ try:
141
+ prompt = f"""Based on this financial analysis:
142
+ {analysis}
143
+
144
+ Provide specific, actionable recommendations covering:
145
+ 1. Strategic Initiatives
146
+ 2. Operational Improvements
147
+ 3. Financial Management
148
+ 4. Risk Mitigation
149
+ 5. Growth Strategy"""
150
+
151
+ response = self.recommendation_generator(
152
+ prompt,
153
+ max_length=800,
154
+ temperature=0.6
155
+ )
156
+ return response[0]['generated_text']
157
+ except Exception as e:
158
+ logger.error(f"Error generating recommendations: {str(e)}")
159
+ return "Error generating recommendations"
 
 
160
 
161
  def analyze_financial_statements(income_statement, balance_sheet, kpi_pdf=None):
162
+ """Main analysis function with error handling"""
163
  try:
 
 
 
 
164
  # Initialize analyzer
165
  analyzer = FinancialAnalyzer()
166
 
167
+ # Read CSV files safely
168
+ logger.info("Reading input files...")
169
+ income_df = analyzer.read_csv_file(income_statement)
170
+ balance_df = analyzer.read_csv_file(balance_sheet)
171
 
172
  # Prepare financial data
173
  financial_data = f"""
 
178
  {balance_df.to_string()}
179
  """
180
 
181
+ # Process KPI PDF if provided
182
+ kpi_data = None
183
+ if kpi_pdf is not None:
184
+ logger.info("Processing KPI PDF...")
185
+ kpi_data = analyzer.extract_text_from_pdf(kpi_pdf)
186
 
187
+ # Generate analyses
188
+ logger.info("Generating analysis...")
189
+ strategic_analysis = analyzer.generate_strategic_analysis(financial_data, kpi_data)
190
  sentiment = analyzer.analyze_sentiment(strategic_analysis)
191
+ recommendations = analyzer.generate_recommendations(strategic_analysis)
 
 
192
 
193
  # Format output
194
+ logger.info("Formatting results...")
195
+ return format_results(strategic_analysis, sentiment, recommendations, kpi_data)
 
196
 
197
  except Exception as e:
198
+ logger.error(f"Error in analysis: {str(e)}")
199
+ return f"""Error analyzing files: {str(e)}
200
+
201
+ Please check:
202
+ 1. Files are in correct format (CSV for financial statements, PDF for KPI)
203
+ 2. Files are not corrupted
204
+ 3. Files contain the expected data
205
+
206
+ If the problem persists, try uploading the files again."""
207
 
208
  def format_results(analysis, sentiment, recommendations, kpi_data=None):
209
  """Format analysis results"""
210
+ try:
211
+ output = "# Financial Analysis Report\n\n"
212
+
213
+ # Strategic Analysis
214
+ output += "## Strategic Analysis\n\n"
215
+ output += analysis + "\n\n"
216
+
217
+ # Sentiment Analysis
218
+ output += "## Market Sentiment\n\n"
219
+ for score in sentiment[0]:
220
+ output += f"- {score['label']}: {score['score']:.2%}\n"
221
+ output += "\n"
222
+
223
+ # Recommendations
224
+ output += "## Strategic Recommendations\n\n"
225
+ output += recommendations
226
+
227
+ # KPI Analysis (if available)
228
+ if kpi_data:
229
+ output += "\n\n## KPI Analysis\n\n"
230
+ output += "KPI data was included in the analysis.\n"
231
+
232
+ return output
233
+ except Exception as e:
234
+ logger.error(f"Error formatting results: {str(e)}")
235
+ return "Error formatting analysis results"
236
 
237
  # Create Gradio interface
238
  iface = gr.Interface(
 
240
  inputs=[
241
  gr.File(label="Income Statement (CSV)"),
242
  gr.File(label="Balance Sheet (CSV)"),
243
+ gr.File(label="KPI Documentation (PDF, Optional)",
244
+ file_types=[".pdf"],
245
+ optional=True)
246
  ],
247
  outputs=gr.Markdown(),
248
  title="AI-Powered Financial Statement Analysis",
249
+ description="""Upload your financial statements for comprehensive analysis using:
250
  - Llama 2: Strategic Analysis
251
  - FinBERT: Financial Sentiment Analysis
252
+ - Falcon: Strategic Recommendations""",
 
 
 
 
 
253
  examples=[
254
  [
255
  "OFINTECH-Income Statement-template.csv",
256
  "OFINTECH Balance Sheet template.csv",
257
+ None
258
  ]
259
  ]
260
  )
261
 
262
  # Launch the interface
263
  if __name__ == "__main__":
264
+ try:
265
+ iface.launch()
266
+ except Exception as e:
267
+ logger.error(f"Error launching application: {str(e)}")
268
+ sys.exit(1)