walaa2022 commited on
Commit
36d5387
·
verified ·
1 Parent(s): 623e602

Delete pages/app.py

Browse files
Files changed (1) hide show
  1. pages/app.py +0 -439
pages/app.py DELETED
@@ -1,439 +0,0 @@
1
- import streamlit as st
2
- import pandas as pd
3
- import numpy as np
4
- import plotly.express as px
5
- import plotly.graph_objects as go
6
- import os
7
- from datetime import datetime, timedelta, date
8
- import time
9
- import json
10
- import google.generativeai as genai
11
- from google.generativeai.types import HarmCategory, HarmBlockThreshold
12
-
13
- # Initialize page configuration
14
- st.set_page_config(
15
- page_title="StartupFinancePilot",
16
- page_icon="💰",
17
- layout="wide",
18
- initial_sidebar_state="expanded"
19
- )
20
-
21
- # Custom CSS
22
- st.markdown("""
23
- <style>
24
- .main-header {
25
- font-size: 2.5rem;
26
- color: #0066cc;
27
- margin-bottom: 0.5rem;
28
- }
29
- .sub-header {
30
- font-size: 1.5rem;
31
- color: #5c5c5c;
32
- margin-bottom: 1.5rem;
33
- }
34
- .metric-card {
35
- background-color: #f8f9fa;
36
- border-radius: 10px;
37
- padding: 20px;
38
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
39
- }
40
- .metric-label {
41
- font-size: 1rem;
42
- color: #5c5c5c;
43
- }
44
- .metric-value {
45
- font-size: 1.8rem;
46
- color: #0066cc;
47
- font-weight: bold;
48
- }
49
- .good-metric {
50
- color: #28a745;
51
- }
52
- .warning-metric {
53
- color: #ffc107;
54
- }
55
- .danger-metric {
56
- color: #dc3545;
57
- }
58
- .advisor-card {
59
- background-color: #f0f7ff;
60
- border-radius: 10px;
61
- padding: 20px;
62
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
63
- margin-bottom: 20px;
64
- }
65
- .advice-text {
66
- font-size: 1.1rem;
67
- line-height: 1.6;
68
- color: #333;
69
- }
70
- .insight-card {
71
- background-color: #f0f8ff;
72
- border-left: 4px solid #0066cc;
73
- padding: 15px;
74
- margin-bottom: 15px;
75
- border-radius: 4px;
76
- }
77
- .ai-badge {
78
- background-color: #0066cc;
79
- color: white;
80
- padding: 3px 10px;
81
- border-radius: 10px;
82
- font-size: 0.8rem;
83
- margin-bottom: 10px;
84
- display: inline-block;
85
- }
86
- .booking-card {
87
- background-color: white;
88
- border-radius: 10px;
89
- padding: 20px;
90
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
91
- margin-bottom: 20px;
92
- }
93
- .session-type {
94
- font-size: 1.2rem;
95
- font-weight: bold;
96
- color: #0066cc;
97
- }
98
- .session-duration {
99
- color: #5c5c5c;
100
- font-size: 0.9rem;
101
- }
102
- .session-price {
103
- font-size: 1.1rem;
104
- font-weight: bold;
105
- color: #28a745;
106
- }
107
- </style>
108
- """, unsafe_allow_html=True)
109
-
110
- # Constants
111
- DEFAULT_GROWTH_RATE = 0.08 # 8% monthly growth
112
- DEFAULT_BURN_RATE = 85000 # $85,000 monthly burn
113
- ENGINEER_SALARY = 10000 # $10,000 monthly cost per engineer ($120K/year)
114
- DEFAULT_MARKETING_BUDGET = 10000 # $10,000 monthly marketing budget
115
-
116
- # Initialize session state variables
117
- if 'booked_sessions' not in st.session_state:
118
- st.session_state.booked_sessions = []
119
- if 'chat_history' not in st.session_state:
120
- st.session_state.chat_history = []
121
- if 'audio_response' not in st.session_state:
122
- st.session_state.audio_response = None
123
- if 'insights_cache' not in st.session_state:
124
- st.session_state.insights_cache = {}
125
- if 'gemini_model' not in st.session_state:
126
- st.session_state.gemini_model = None
127
-
128
- # Sample data
129
- @st.cache_data
130
- def load_sample_data():
131
- # TechHealth AI data
132
- startup_data = {
133
- "name": "TechHealth AI",
134
- "stage": "Seed",
135
- "founded": "18 months ago",
136
- "employees": 12,
137
- "last_funding": "$1.2M seed round 10 months ago",
138
- "cash": 320000,
139
- "burn_rate": 85000,
140
- "revenue": 15000,
141
- "growth_rate": 0.08
142
- }
143
-
144
- # Cash flow history
145
- cash_flow_data = {
146
- "Month": [f"Month {i}" for i in range(1, 11)],
147
- "Revenue": [8000, 8500, 9200, 10000, 10800, 11700, 12600, 13600, 14700, 15800],
148
- "Payroll": [60000, 60000, 62000, 62000, 65000, 65000, 70000, 70000, 75000, 75000],
149
- "Marketing": [8000, 9000, 10000, 12000, 15000, 18000, 15000, 12000, 10000, 8000],
150
- "Office": [5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000],
151
- "Software": [3000, 3200, 3500, 3800, 4000, 4200, 4500, 4800, 5000, 5200],
152
- "Travel": [2000, 1800, 2500, 3000, 4000, 4500, 3500, 3000, 2500, 2000],
153
- "Legal": [1500, 1000, 800, 1200, 800, 2000, 1500, 1000, 3000, 1200],
154
- "Misc": [1000, 1200, 1300, 1500, 1700, 1800, 2000, 2200, 2500, 2800]
155
- }
156
-
157
- # Add calculated fields
158
- df = pd.DataFrame(cash_flow_data)
159
- df["Total_Expenses"] = df[["Payroll", "Marketing", "Office", "Software", "Travel", "Legal", "Misc"]].sum(axis=1)
160
- df["Net_Burn"] = df["Total_Expenses"] - df["Revenue"]
161
-
162
- # Transaction data
163
- transactions = pd.DataFrame([
164
- {"Date": "2023-11-05", "Category": "Travel", "Vendor": "Caribbean Cruises", "Amount": 8500, "Description": "Team Retreat Planning", "Flag": "Suspicious"},
165
- {"Date": "2023-11-12", "Category": "Marketing", "Vendor": "LuxuryGifts Inc", "Amount": 4200, "Description": "Client Appreciation", "Flag": "Suspicious"},
166
- {"Date": "2023-11-22", "Category": "Office", "Vendor": "Premium Furniture", "Amount": 12000, "Description": "Office Upgrades", "Flag": "Suspicious"},
167
- {"Date": "2023-11-28", "Category": "Consulting", "Vendor": "Strategic Vision LLC", "Amount": 7500, "Description": "Strategy Consulting", "Flag": "Suspicious"},
168
- {"Date": "2023-12-05", "Category": "Software", "Vendor": "Personal Apple Store", "Amount": 3200, "Description": "Development Tools", "Flag": "Suspicious"},
169
- {"Date": "2023-12-12", "Category": "Legal", "Vendor": "Anderson Brothers", "Amount": 5800, "Description": "Legal Services", "Flag": "Normal"},
170
- {"Date": "2023-12-20", "Category": "Payroll", "Vendor": "November Payroll", "Amount": 75000, "Description": "Monthly Payroll", "Flag": "Normal"},
171
- {"Date": "2023-12-22", "Category": "Marketing", "Vendor": "Google Ads", "Amount": 8000, "Description": "Ad Campaign", "Flag": "Normal"},
172
- {"Date": "2023-12-25", "Category": "Office", "Vendor": "WeWork", "Amount": 5000, "Description": "Monthly Rent", "Flag": "Normal"},
173
- {"Date": "2023-12-28", "Category": "Software", "Vendor": "AWS", "Amount": 5200, "Description": "Cloud Services", "Flag": "Normal"},
174
- {"Date": "2024-01-05", "Category": "Travel", "Vendor": "Delta Airlines", "Amount": 1200, "Description": "Client Meeting Travel", "Flag": "Normal"},
175
- {"Date": "2024-01-10", "Category": "Marketing", "Vendor": "Facebook Ads", "Amount": 4500, "Description": "Social Media Campaign", "Flag": "Normal"},
176
- {"Date": "2024-01-15", "Category": "Software", "Vendor": "Atlassian", "Amount": 2800, "Description": "Development Tools", "Flag": "Normal"},
177
- {"Date": "2024-01-20", "Category": "Payroll", "Vendor": "January Payroll", "Amount": 75000, "Description": "Monthly Payroll", "Flag": "Normal"},
178
- {"Date": "2024-01-25", "Category": "Office", "Vendor": "WeWork", "Amount": 5000, "Description": "Monthly Rent", "Flag": "Normal"}
179
- ])
180
-
181
- return startup_data, df, transactions
182
-
183
- # Setup AI Services
184
- def setup_genai():
185
- """Initialize and configure Google's Generative AI and list available models"""
186
- try:
187
- if 'GOOGLE_API_KEY' in st.secrets:
188
- genai.configure(api_key=st.secrets['GOOGLE_API_KEY'])
189
-
190
- # Get available models and select one for text generation
191
- models = genai.list_models()
192
- text_models = [m.name for m in models if 'generateContent' in m.supported_generation_methods]
193
-
194
- if text_models:
195
- # Use first available text generation model
196
- model_name = text_models[0]
197
- st.session_state.gemini_model = model_name
198
- return True
199
- else:
200
- st.warning("No appropriate generative AI models available")
201
- # Use a fallback model name for demonstration
202
- st.session_state.gemini_model = "gemini-1.5-pro"
203
- return False
204
- else:
205
- st.warning("Google API key not found in secrets. Using simulated AI responses.")
206
- st.session_state.gemini_model = "gemini-1.5-pro"
207
- return False
208
- except Exception as e:
209
- st.warning(f"Failed to initialize Gemini: {e}. Using simulated AI responses.")
210
- st.session_state.gemini_model = "gemini-1.5-pro"
211
- return False
212
-
213
- def generate_ai_response(prompt, simulate=False):
214
- """Generate response from Gemini or simulate one if the API is unavailable"""
215
- if simulate:
216
- # Simulate AI response with predefined text based on keywords in prompt
217
- time.sleep(1) # Simulate processing time
218
-
219
- if "runway" in prompt.lower():
220
- return "Based on your current spend rate of $85K/month and revenue growth of 8%, your runway is approximately 3.8 months. I recommend reducing non-essential expenses to extend runway to at least 6 months before your next fundraising round."
221
- elif "hire" in prompt.lower() or "hiring" in prompt.lower():
222
- return "Adding new hires at this stage would reduce your runway significantly. Consider contracting talent first or postponing hiring until after securing additional funding. Each new engineer costs $10K/month, reducing runway by approximately 3 weeks per hire."
223
- elif "marketing" in prompt.lower():
224
- return "Your current CAC to LTV ratio doesn't justify increasing marketing spend. Focus on optimizing current channels and improving conversion rates. Once unit economics improve, gradually increase marketing budget by no more than 20% per month."
225
- elif "fundraising" in prompt.lower() or "investor" in prompt.lower():
226
- return "With less than 4 months of runway, you should begin fundraising preparations immediately. Focus on demonstrating product-market fit and improving key metrics like MRR growth, user retention, and unit economics before approaching investors."
227
- elif "suspicious" in prompt.lower() or "transaction" in prompt.lower():
228
- return "I've identified several concerning transactions including a $8,500 travel expense and $12,000 in office upgrades. These discretionary expenses represent over 25% of a month's burn and should be reviewed with your finance team immediately."
229
- else:
230
- return "Based on your financial data, I recommend prioritizing runway extension and focusing on core metrics that demonstrate product-market fit. Consider reducing non-essential expenses by 15-20% to add 1-2 months to your runway before beginning fundraising conversations."
231
- else:
232
- try:
233
- # Use the actual Gemini model
234
- model = genai.GenerativeModel(st.session_state.gemini_model)
235
-
236
- generation_config = {
237
- "temperature": 0.7,
238
- "top_p": 0.95,
239
- "top_k": 40,
240
- "max_output_tokens": 1024,
241
- }
242
-
243
- safety_settings = {
244
- HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
245
- HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
246
- HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,
247
- HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_NONE
248
- }
249
-
250
- response = model.generate_content(
251
- prompt,
252
- generation_config=generation_config,
253
- safety_settings=safety_settings
254
- )
255
-
256
- return response.text
257
- except Exception as e:
258
- st.warning(f"Error generating AI response: {e}")
259
- # Fall back to simulated response
260
- return generate_ai_response(prompt, simulate=True)
261
-
262
- # Financial modeling functions
263
- def calculate_runway(initial_cash, monthly_burn, monthly_revenue, growth_rate, months=24):
264
- """Calculate runway based on current burn rate and revenue growth."""
265
- dates = [datetime.now() + timedelta(days=30*i) for i in range(months)]
266
- df = pd.DataFrame(index=dates, columns=['Cash', 'Revenue', 'Expenses', 'Net_Burn', 'Cumulative_Cash'])
267
-
268
- current_cash = initial_cash
269
- current_revenue = monthly_revenue
270
- df.iloc[0, df.columns.get_loc('Cash')] = current_cash
271
- df.iloc[0, df.columns.get_loc('Revenue')] = current_revenue
272
- df.iloc[0, df.columns.get_loc('Expenses')] = monthly_burn
273
- df.iloc[0, df.columns.get_loc('Net_Burn')] = monthly_burn - current_revenue
274
- df.iloc[0, df.columns.get_loc('Cumulative_Cash')] = current_cash
275
-
276
- runway_months = months
277
- for i in range(1, months):
278
- current_revenue = current_revenue * (1 + growth_rate)
279
- net_burn = monthly_burn - current_revenue
280
- current_cash = current_cash - net_burn
281
-
282
- df.iloc[i, df.columns.get_loc('Cash')] = current_cash
283
- df.iloc[i, df.columns.get_loc('Revenue')] = current_revenue
284
- df.iloc[i, df.columns.get_loc('Expenses')] = monthly_burn
285
- df.iloc[i, df.columns.get_loc('Net_Burn')] = net_burn
286
- df.iloc[i, df.columns.get_loc('Cumulative_Cash')] = current_cash
287
-
288
- if current_cash <= 0:
289
- runway_months = i
290
- break
291
-
292
- return runway_months, df
293
-
294
- def simulate_decision(initial_cash, monthly_burn, monthly_revenue, growth_rate,
295
- new_expenses=0, new_hires=0, new_marketing=0, growth_impact=0):
296
- """Simulate the impact of a business decision on runway."""
297
- # Calculate current runway
298
- current_runway, current_df = calculate_runway(initial_cash, monthly_burn, monthly_revenue, growth_rate)
299
-
300
- # Calculate additional expenses
301
- additional_expenses = new_expenses + (new_hires * ENGINEER_SALARY) + new_marketing
302
-
303
- # Calculate new runway
304
- new_runway, new_df = calculate_runway(
305
- initial_cash,
306
- monthly_burn + additional_expenses,
307
- monthly_revenue,
308
- growth_rate + growth_impact
309
- )
310
-
311
- return current_runway, new_runway, current_df, new_df
312
-
313
- def detect_suspicious_transactions(transactions_df):
314
- """AI-enhanced suspicious transaction detection."""
315
- df = transactions_df.copy()
316
-
317
- # Define thresholds for each category
318
- category_thresholds = {
319
- "Travel": 3000,
320
- "Marketing": 10000,
321
- "Office": 7000,
322
- "Software": 6000,
323
- "Consulting": 5000,
324
- "Legal": 6000
325
- }
326
-
327
- # Define suspicious terms
328
- suspicious_terms = ['luxury', 'cruise', 'premium', 'personal', 'gift']
329
-
330
- # Add suspicious column
331
- df['Suspicious'] = False
332
- df['Reason'] = ""
333
- df['Risk_Score'] = 0
334
-
335
- # Check for suspicious patterns
336
- for idx, row in df.iterrows():
337
- reasons = []
338
- risk_score = 0
339
-
340
- # Check if amount exceeds category threshold
341
- if row['Category'] in category_thresholds:
342
- if row['Amount'] > category_thresholds[row['Category']]:
343
- reasons.append(f"Amount exceeds typical spending for {row['Category']}")
344
- risk_score += 30
345
-
346
- # Higher risk for significantly exceeding threshold
347
- excess_percentage = (row['Amount'] - category_thresholds[row['Category']]) / category_thresholds[row['Category']] * 100
348
- if excess_percentage > 100: # More than double the threshold
349
- risk_score += 20
350
-
351
- # Check for suspicious vendors or descriptions
352
- if any(term in str(row['Vendor']).lower() for term in suspicious_terms):
353
- reasons.append(f"Vendor name contains suspicious term")
354
- risk_score += 25
355
-
356
- if any(term in str(row['Description']).lower() for term in suspicious_terms):
357
- reasons.append(f"Description contains suspicious term")
358
- risk_score += 20
359
-
360
- # Check for rounded amounts (potential indicator of estimation/fabrication)
361
- if row['Amount'] % 1000 == 0 and row['Amount'] > 3000:
362
- reasons.append(f"Suspiciously round amount")
363
- risk_score += 15
364
-
365
- # Mark as suspicious if risk score is high enough
366
- if risk_score >= 30:
367
- df.at[idx, 'Suspicious'] = True
368
- df.at[idx, 'Reason'] = "; ".join(reasons)
369
- df.at[idx, 'Risk_Score'] = risk_score
370
-
371
- # Sort by risk score
372
- df = df.sort_values(by='Risk_Score', ascending=False)
373
-
374
- return df
375
-
376
- # Import page functions
377
- from dashboard_page import render_financial_dashboard, get_runway_analysis, get_fundraising_readiness_analysis
378
- from decision_simulator import render_decision_simulator, get_decision_analysis
379
- from fund_monitoring import render_fund_monitoring, get_fraud_analysis
380
- from financial_advisor import render_ai_financial_advisor, get_advisory_guidance, generate_voice_response
381
- from book_session import render_book_session
382
-
383
- # UI Components
384
- def create_sidebar():
385
- """Create sidebar with company profile and filters."""
386
- st.sidebar.title("StartupFinancePilot")
387
- st.sidebar.image("https://img.freepik.com/premium-vector/business-finance-analytics-logo-design-vector-template_67715-552.jpg", width=150)
388
-
389
- # Company profile
390
- startup_data, _, _ = load_sample_data()
391
-
392
- st.sidebar.header("Company Profile")
393
- st.sidebar.write(f"**{startup_data['name']}**")
394
- st.sidebar.write(f"Stage: {startup_data['stage']}")
395
- st.sidebar.write(f"Founded: {startup_data['founded']}")
396
- st.sidebar.write(f"Employees: {startup_data['employees']}")
397
- st.sidebar.write(f"Last Funding: {startup_data['last_funding']}")
398
-
399
- # AI Status
400
- has_api = setup_genai()
401
- ai_status = "🟢 Connected" if has_api else "🟡 Demo Mode"
402
- st.sidebar.write(f"AI Status: {ai_status}")
403
- if not has_api:
404
- st.sidebar.info("Running in demo mode with simulated AI responses. Add GOOGLE_API_KEY to secrets for full functionality.")
405
-
406
- # App navigation
407
- st.sidebar.header("Navigation")
408
- page = st.sidebar.radio("Go to", [
409
- "Financial Dashboard",
410
- "Decision Simulator",
411
- "Fund Monitoring",
412
- "AI Financial Advisor",
413
- "Book a Session"
414
- ])
415
-
416
- return page
417
-
418
- # Main application
419
- def main():
420
- # Load sample data
421
- startup_data, cash_flow_df, transactions_df = load_sample_data()
422
-
423
- # Create sidebar and get selected page
424
- page = create_sidebar()
425
-
426
- # Render selected page
427
- if page == "Financial Dashboard":
428
- render_financial_dashboard(startup_data, cash_flow_df)
429
- elif page == "Decision Simulator":
430
- render_decision_simulator(startup_data)
431
- elif page == "Fund Monitoring":
432
- render_fund_monitoring(transactions_df)
433
- elif page == "AI Financial Advisor":
434
- render_ai_financial_advisor(startup_data)
435
- elif page == "Book a Session":
436
- render_book_session()
437
-
438
- if __name__ == "__main__":
439
- main()