Upload app.py
Browse files
app.py
ADDED
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import os
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
|
5 |
+
# Import local modules
|
6 |
+
from src.pages import dashboard, decision_simulator, fund_monitoring, financial_advisor
|
7 |
+
from src.utils.data_processing import (
|
8 |
+
generate_sample_startup_data,
|
9 |
+
generate_sample_cash_flow_data,
|
10 |
+
generate_sample_transactions_data
|
11 |
+
)
|
12 |
+
|
13 |
+
# Load environment variables
|
14 |
+
load_dotenv()
|
15 |
+
|
16 |
+
# Constants
|
17 |
+
DEFAULT_GROWTH_RATE = 0.08 # 8% monthly growth
|
18 |
+
DEFAULT_BURN_RATE = 85000 # $85,000 monthly burn
|
19 |
+
ENGINEER_SALARY = 10000 # $10,000 monthly cost per engineer ($120K/year)
|
20 |
+
|
21 |
+
def main():
|
22 |
+
"""
|
23 |
+
Main application entry point for Startup Finance Pilot
|
24 |
+
"""
|
25 |
+
# App configuration
|
26 |
+
st.set_page_config(
|
27 |
+
page_title="StartupFinancePilot",
|
28 |
+
page_icon="💰",
|
29 |
+
layout="wide",
|
30 |
+
initial_sidebar_state="expanded"
|
31 |
+
)
|
32 |
+
|
33 |
+
# Custom CSS (you might want to move this to a separate file in a larger project)
|
34 |
+
st.markdown("""
|
35 |
+
<style>
|
36 |
+
/* Your existing CSS styles from previous implementation */
|
37 |
+
.main-header { font-size: 2.5rem; color: #0066cc; }
|
38 |
+
.sub-header { font-size: 1.5rem; color: #5c5c5c; }
|
39 |
+
/* Add more styles as needed */
|
40 |
+
</style>
|
41 |
+
""", unsafe_allow_html=True)
|
42 |
+
|
43 |
+
# Initialize session state
|
44 |
+
if 'startups' not in st.session_state:
|
45 |
+
st.session_state.startups = {}
|
46 |
+
|
47 |
+
if 'current_startup' not in st.session_state:
|
48 |
+
st.session_state.current_startup = None
|
49 |
+
|
50 |
+
if 'current_page' not in st.session_state:
|
51 |
+
st.session_state.current_page = 'upload'
|
52 |
+
|
53 |
+
if 'insights_cache' not in st.session_state:
|
54 |
+
st.session_state.insights_cache = {}
|
55 |
+
|
56 |
+
# Add sample data for demonstration
|
57 |
+
sample_startup = generate_sample_startup_data()
|
58 |
+
st.session_state.startups[sample_startup['name']] = {
|
59 |
+
'profile': sample_startup,
|
60 |
+
'cash_flow': generate_sample_cash_flow_data(),
|
61 |
+
'transactions': generate_sample_transactions_data()
|
62 |
+
}
|
63 |
+
st.session_state.current_startup = sample_startup['name']
|
64 |
+
|
65 |
+
# Sidebar navigation
|
66 |
+
with st.sidebar:
|
67 |
+
st.title("💰 StartupFinancePilot")
|
68 |
+
st.write("AI-powered financial assistant for startups")
|
69 |
+
|
70 |
+
# Startup selector
|
71 |
+
if st.session_state.startups:
|
72 |
+
startup_names = list(st.session_state.startups.keys())
|
73 |
+
selected_startup = st.selectbox(
|
74 |
+
"Choose Startup",
|
75 |
+
startup_names,
|
76 |
+
index=startup_names.index(st.session_state.current_startup)
|
77 |
+
)
|
78 |
+
|
79 |
+
st.session_state.current_startup = selected_startup
|
80 |
+
|
81 |
+
# Show basic startup info
|
82 |
+
startup_data = st.session_state.startups[selected_startup]['profile']
|
83 |
+
st.markdown(f"""
|
84 |
+
**Stage:** {startup_data['stage']}
|
85 |
+
**Cash:** ${startup_data['cash']:,}
|
86 |
+
**Monthly Burn:** ${startup_data['burn_rate']:,}
|
87 |
+
**Monthly Revenue:** ${startup_data['revenue']:,}
|
88 |
+
""")
|
89 |
+
|
90 |
+
# Navigation buttons
|
91 |
+
st.markdown("<hr>", unsafe_allow_html=True)
|
92 |
+
|
93 |
+
page_options = {
|
94 |
+
"📊 Financial Dashboard": "dashboard",
|
95 |
+
"🔮 Decision Simulator": "simulator",
|
96 |
+
"🕵️ Fund Monitoring": "monitoring",
|
97 |
+
"🤖 AI Financial Advisor": "advisor"
|
98 |
+
}
|
99 |
+
|
100 |
+
for label, page_key in page_options.items():
|
101 |
+
if st.button(label, use_container_width=True):
|
102 |
+
st.session_state.current_page = page_key
|
103 |
+
st.experimental_rerun()
|
104 |
+
|
105 |
+
# Render the correct page
|
106 |
+
if st.session_state.current_page == 'dashboard':
|
107 |
+
dashboard.render_financial_dashboard(
|
108 |
+
st.session_state.startups[st.session_state.current_startup]['profile'],
|
109 |
+
st.session_state.startups[st.session_state.current_startup]['cash_flow']
|
110 |
+
)
|
111 |
+
elif st.session_state.current_page == 'simulator':
|
112 |
+
decision_simulator.render_decision_simulator(
|
113 |
+
st.session_state.startups[st.session_state.current_startup]['profile']
|
114 |
+
)
|
115 |
+
elif st.session_state.current_page == 'monitoring':
|
116 |
+
fund_monitoring.render_fund_monitoring(
|
117 |
+
st.session_state.startups[st.session_state.current_startup]['transactions']
|
118 |
+
)
|
119 |
+
elif st.session_state.current_page == 'advisor':
|
120 |
+
financial_advisor.render_ai_financial_advisor(
|
121 |
+
st.session_state.startups[st.session_state.current_startup]['profile']
|
122 |
+
)
|
123 |
+
|
124 |
+
def validate_gemini_api_key():
|
125 |
+
"""
|
126 |
+
Validate the Google Generative AI API key
|
127 |
+
|
128 |
+
Returns:
|
129 |
+
bool: True if API key is valid, False otherwise
|
130 |
+
"""
|
131 |
+
try:
|
132 |
+
import google.generativeai as genai
|
133 |
+
api_key = os.getenv('GOOGLE_API_KEY')
|
134 |
+
|
135 |
+
if not api_key:
|
136 |
+
st.error("🚨 Google API Key not found. Please set GOOGLE_API_KEY in your .env file.")
|
137 |
+
return False
|
138 |
+
|
139 |
+
genai.configure(api_key=api_key)
|
140 |
+
model = genai.GenerativeModel('gemini-pro')
|
141 |
+
|
142 |
+
# Try a simple test generation
|
143 |
+
test_response = model.generate_content("Hello, can you confirm the API is working?")
|
144 |
+
return True
|
145 |
+
except Exception as e:
|
146 |
+
st.error(f"🚨 Error validating API key: {e}")
|
147 |
+
return False
|
148 |
+
|
149 |
+
if __name__ == "__main__":
|
150 |
+
# Check API key before running
|
151 |
+
if validate_gemini_api_key():
|
152 |
+
main()
|
153 |
+
else:
|
154 |
+
st.warning("Please set up your Google Generative AI API key to use the application.")
|