Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import plotly.express as px | |
| import requests | |
| import os | |
| # Optional environment key | |
| API_KEY = os.getenv("FMP_API_KEY") | |
| # Page config | |
| st.set_page_config(page_title="Financial Growth Metrics", layout="wide") | |
| # ---------------------------- | |
| # Caching function with session_state | |
| # ---------------------------- | |
| def fetch_data(url, cache_key): | |
| """Load data from session_state if cached, else fetch from URL.""" | |
| if cache_key in st.session_state: | |
| return st.session_state[cache_key] | |
| try: | |
| resp = requests.get(url) | |
| resp.raise_for_status() | |
| data = resp.json() | |
| st.session_state[cache_key] = data | |
| return data | |
| except requests.exceptions.RequestException: | |
| st.session_state[cache_key] = [] | |
| return [] | |
| # ---------------------------- | |
| # Helper for interpretations | |
| # ---------------------------- | |
| def interpret_growth_metrics(df, metric_list, section_title): | |
| existing_cols = [m for m in metric_list if m in df.columns] | |
| if not existing_cols or df.empty: | |
| return f"**{section_title}**: Data not available." | |
| df_valid = df[['date'] + existing_cols].dropna(subset=existing_cols, how='all') | |
| if df_valid.empty: | |
| return f"**{section_title}**: No valid data entries." | |
| df_valid = df_valid.sort_values("date") | |
| latest_row = df_valid.iloc[-1] | |
| latest_date = latest_row['date'] | |
| if len(df_valid) > 1: | |
| prior_row = df_valid.iloc[-2] | |
| prior_date = prior_row['date'] | |
| else: | |
| prior_row = None | |
| prior_date = None | |
| # Basic stats | |
| values_only = df_valid[existing_cols].astype(float) | |
| mean_vals = values_only.mean() | |
| min_vals = values_only.min() | |
| max_vals = values_only.max() | |
| std_vals = values_only.std() | |
| text = f"##### {section_title}\n\n" | |
| text += "**Recent Data:**\n" | |
| text += f"- **Latest Record Date:** {latest_date.date()}\n" | |
| for col in existing_cols: | |
| latest_val = latest_row[col] | |
| if pd.isna(latest_val): | |
| text += f"- **{col}:** Missing in latest record.\n" | |
| else: | |
| text += f"- **{col}:** {latest_val:.2f}\n" | |
| if prior_row is not None: | |
| text += f"\n**Comparison with previous record ({prior_date.date()}):**\n" | |
| for col in existing_cols: | |
| latest_val = latest_row[col] | |
| prior_val = prior_row[col] | |
| if pd.isna(latest_val) or pd.isna(prior_val): | |
| text += f"- **{col}:** No comparison (missing data).\n" | |
| else: | |
| diff = latest_val - prior_val | |
| if diff > 0: | |
| text += f"- **{col}:** Increased by {diff:.2f}.\n" | |
| elif diff < 0: | |
| text += f"- **{col}:** Decreased by {abs(diff):.2f}.\n" | |
| else: | |
| text += f"- **{col}:** No change.\n" | |
| text += "\n**Historical Summary:**\n" | |
| for col in existing_cols: | |
| text += (f"- **{col}:** Mean={mean_vals[col]:.2f}, " | |
| f"Min={min_vals[col]:.2f}, Max={max_vals[col]:.2f}, " | |
| f"StdDev={std_vals[col]:.2f}\n") | |
| text += "\n**Final Interpretation:**\n" | |
| text += "- Track these changes over time.\n" | |
| return text | |
| # ---------------------------- | |
| # Page Functions | |
| # ---------------------------- | |
| def show_financial_growth(symbol, period): | |
| url = f"https://financialmodelingprep.com/api/v3/financial-growth/{symbol}?period={period}&apikey={API_KEY}" | |
| data = fetch_data(url, f"financial_growth_{symbol}_{period}") | |
| if not data: | |
| st.error("No data returned. Check symbol or period.") | |
| return | |
| df = pd.DataFrame(data) | |
| if "date" in df.columns: | |
| df["date"] = pd.to_datetime(df["date"], errors="coerce") | |
| df.sort_values("date", inplace=True) | |
| st.success("Data loaded successfully.") | |
| st.write("Below are key growth metrics. Expand each section for interpretation.") | |
| # 1. Profitability | |
| st.subheader("1. Profitability") | |
| profitability_vars = ["revenueGrowth", "grossProfitGrowth", "ebitgrowth", | |
| "operatingIncomeGrowth", "netIncomeGrowth"] | |
| try: | |
| fig1 = px.line(df, x="date", y=profitability_vars, title="Profitability Metrics") | |
| fig1.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric") | |
| st.plotly_chart(fig1, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Profitability Metrics.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, profitability_vars, "Profitability Metrics")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in profitability_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 2. EPS | |
| st.subheader("2. Earnings Per Share") | |
| eps_vars = ["epsgrowth", "epsdilutedGrowth"] | |
| try: | |
| fig2 = px.line(df, x="date", y=eps_vars, title="EPS Metrics") | |
| fig2.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric") | |
| st.plotly_chart(fig2, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot EPS Metrics.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, eps_vars, "EPS Metrics")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in eps_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 3. Share Count | |
| st.subheader("3. Share Count") | |
| share_vars = ["weightedAverageSharesGrowth", "weightedAverageSharesDilutedGrowth"] | |
| try: | |
| fig3 = px.line(df, x="date", y=share_vars, title="Share Count Adjustments") | |
| fig3.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric") | |
| st.plotly_chart(fig3, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Share Count.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, share_vars, "Share Count Adjustments")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in share_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 4. Dividend | |
| st.subheader("4. Dividend per Share") | |
| div_vars = ["dividendsperShareGrowth"] | |
| try: | |
| fig4 = px.line(df, x="date", y=div_vars, title="Dividend Growth") | |
| fig4.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric") | |
| st.plotly_chart(fig4, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Dividend Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, div_vars, "Dividend Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in div_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 5. Cash Flow | |
| st.subheader("5. Cash Flow") | |
| cashflow_vars = ["operatingCashFlowGrowth", "freeCashFlowGrowth"] | |
| try: | |
| fig5 = px.line(df, x="date", y=cashflow_vars, title="Cash Flow Metrics") | |
| fig5.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric") | |
| st.plotly_chart(fig5, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Cash Flow Metrics.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, cashflow_vars, "Cash Flow Metrics")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in cashflow_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 6. Multi-Year Growth (Per Share) | |
| st.subheader("6. Multi-Year Growth (Per Share)") | |
| multi_year_groups = { | |
| "Revenue Growth": [ | |
| "tenYRevenueGrowthPerShare", "fiveYRevenueGrowthPerShare", | |
| "threeYRevenueGrowthPerShare" | |
| ], | |
| "Operating Cash Flow Growth": [ | |
| "tenYOperatingCFGrowthPerShare", "fiveYOperatingCFGrowthPerShare", | |
| "threeYOperatingCFGrowthPerShare" | |
| ], | |
| "Net Income Growth": [ | |
| "tenYNetIncomeGrowthPerShare", "fiveYNetIncomeGrowthPerShare", | |
| "threeYNetIncomeGrowthPerShare" | |
| ], | |
| "Shareholders’ Equity Growth": [ | |
| "tenYShareholdersEquityGrowthPerShare", "fiveYShareholdersEquityGrowthPerShare", | |
| "threeYShareholdersEquityGrowthPerShare" | |
| ], | |
| "Dividend per Share Growth": [ | |
| "tenYDividendperShareGrowthPerShare", "fiveYDividendperShareGrowthPerShare", | |
| "threeYDividendperShareGrowthPerShare" | |
| ] | |
| } | |
| for subgroup, vars_list in multi_year_groups.items(): | |
| st.markdown(f"**{subgroup}**") | |
| try: | |
| fig = px.line(df, x="date", y=vars_list, title=subgroup) | |
| fig.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric") | |
| st.plotly_chart(fig, use_container_width=True) | |
| except Exception: | |
| st.error(f"Could not plot chart for {subgroup}.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, vars_list, subgroup)) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in vars_list if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 7. Balance Sheet | |
| st.subheader("7. Balance Sheet") | |
| balance_vars = ["receivablesGrowth", "inventoryGrowth", "assetGrowth", | |
| "bookValueperShareGrowth", "debtGrowth"] | |
| try: | |
| fig7 = px.line(df, x="date", y=balance_vars, title="Balance Sheet Metrics") | |
| fig7.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric") | |
| st.plotly_chart(fig7, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Balance Sheet Metrics.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, balance_vars, "Balance Sheet Metrics")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in balance_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 8. Expense | |
| st.subheader("8. Expense") | |
| expense_vars = ["rdexpenseGrowth", "sgaexpensesGrowth"] | |
| try: | |
| fig8 = px.line(df, x="date", y=expense_vars, title="Expense Metrics") | |
| fig8.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric") | |
| st.plotly_chart(fig8, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Expense Metrics.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, expense_vars, "Expense Metrics")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in expense_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| def show_balance_sheet_growth(symbol, period): | |
| url = f"https://financialmodelingprep.com/api/v3/balance-sheet-statement-growth/{symbol}?period={period}&apikey={API_KEY}" | |
| data = fetch_data(url, f"balance_sheet_growth_{symbol}_{period}") | |
| if not data: | |
| st.error("No data returned. Check symbol or period.") | |
| return | |
| df = pd.DataFrame(data) | |
| if "date" in df.columns: | |
| df["date"] = pd.to_datetime(df["date"], errors="coerce") | |
| df.sort_values("date", inplace=True) | |
| st.success("Data loaded successfully.") | |
| st.write("These sections show balance sheet growth metrics.") | |
| # 1. Asset Growth | |
| st.subheader("1. Asset Growth") | |
| asset_vars = [ | |
| "growthCashAndCashEquivalents", "growthShortTermInvestments", | |
| "growthCashAndShortTermInvestments", "growthNetReceivables", | |
| "growthInventory", "growthTotalCurrentAssets", | |
| "growthPropertyPlantEquipmentNet", "growthTotalNonCurrentAssets", | |
| "growthTotalAssets" | |
| ] | |
| try: | |
| fig_a = px.line(df, x="date", y=asset_vars, title="Asset Growth") | |
| fig_a.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_a, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Asset Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, asset_vars, "Asset Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in asset_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 2. Liability Growth | |
| st.subheader("2. Liability Growth") | |
| liability_vars = [ | |
| "growthAccountPayables", "growthShortTermDebt", "growthTaxPayables", | |
| "growthTotalCurrentLiabilities", "growthLongTermDebt", | |
| "growthTotalNonCurrentLiabilities", "growthTotalLiabilities" | |
| ] | |
| try: | |
| fig_l = px.line(df, x="date", y=liability_vars, title="Liability Growth") | |
| fig_l.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_l, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Liability Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, liability_vars, "Liability Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in liability_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 3. Equity Growth | |
| st.subheader("3. Equity Growth") | |
| equity_vars = [ | |
| "growthCommonStock", "growthRetainedEarnings", | |
| "growthAccumulatedOtherComprehensiveIncomeLoss", | |
| "growthTotalStockholdersEquity" | |
| ] | |
| try: | |
| fig_e = px.line(df, x="date", y=equity_vars, title="Equity Growth") | |
| fig_e.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_e, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Equity Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, equity_vars, "Equity Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in equity_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 4. Debt Metrics | |
| st.subheader("4. Debt Metrics") | |
| debt_vars = ["growthTotalDebt", "growthNetDebt"] | |
| try: | |
| fig_d = px.line(df, x="date", y=debt_vars, title="Debt Metrics") | |
| fig_d.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_d, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Debt Metrics.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, debt_vars, "Debt Metrics")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in debt_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| def show_income_growth(symbol, period): | |
| url = f"https://financialmodelingprep.com/api/v3/income-statement-growth/{symbol}?period={period}&apikey={API_KEY}" | |
| data = fetch_data(url, f"income_growth_{symbol}_{period}") | |
| if not data: | |
| st.error("No data returned. Check symbol or period.") | |
| return | |
| df = pd.DataFrame(data) | |
| if "date" in df.columns: | |
| df["date"] = pd.to_datetime(df["date"], errors="coerce") | |
| df.sort_values("date", inplace=True) | |
| st.success("Data loaded successfully.") | |
| st.write("These sections show income statement growth metrics.") | |
| # 1. Profitability | |
| st.subheader("1. Profitability") | |
| profitability_vars = [ | |
| "growthRevenue", "growthGrossProfit", "growthOperatingIncome", | |
| "growthNetIncome", "growthEBITDA" | |
| ] | |
| try: | |
| fig_p = px.line(df, x="date", y=profitability_vars, title="Profitability Growth") | |
| fig_p.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_p, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Profitability Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, profitability_vars, "Profitability Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in profitability_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 2. Expense | |
| st.subheader("2. Expense") | |
| expense_vars = [ | |
| "growthCostOfRevenue", "growthOperatingExpenses", | |
| "growthResearchAndDevelopmentExpenses", "growthSellingAndMarketingExpenses" | |
| ] | |
| try: | |
| fig_e = px.line(df, x="date", y=expense_vars, title="Expense Growth") | |
| fig_e.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_e, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Expense Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, expense_vars, "Expense Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in expense_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 3. Net and Tax Metrics | |
| st.subheader("3. Net and Tax Metrics") | |
| net_tax_vars = ["growthIncomeBeforeTax", "growthIncomeTaxExpense", | |
| "growthNetIncome", "growthNetIncomeRatio"] | |
| try: | |
| fig_n = px.line(df, x="date", y=net_tax_vars, title="Net Income and Tax Growth") | |
| fig_n.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_n, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Net Income/Tax Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, net_tax_vars, "Net Income/Tax Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in net_tax_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 4. EPS Growth | |
| st.subheader("4. EPS Growth") | |
| eps_vars = ["growthEPS", "growthEPSDiluted"] | |
| try: | |
| fig_eps = px.line(df, x="date", y=eps_vars, title="EPS Growth") | |
| fig_eps.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_eps, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot EPS Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, eps_vars, "EPS Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in eps_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| def show_cashflow_growth(symbol, period): | |
| url = f"https://financialmodelingprep.com/api/v3/cash-flow-statement-growth/{symbol}?period={period}&apikey={API_KEY}" | |
| data = fetch_data(url, f"cashflow_growth_{symbol}_{period}") | |
| if not data: | |
| st.error("No data returned. Check symbol or period.") | |
| return | |
| df = pd.DataFrame(data) | |
| if "date" in df.columns: | |
| df["date"] = pd.to_datetime(df["date"], errors="coerce") | |
| df.sort_values("date", inplace=True) | |
| st.success("Data loaded successfully.") | |
| st.write("These sections show cash flow statement growth metrics.") | |
| # 1. Operating Activities | |
| st.subheader("1. Operating Activities") | |
| operating_vars = [ | |
| "growthNetIncome", "growthDepreciationAndAmortization", | |
| "growthChangeInWorkingCapital", "growthNetCashProvidedByOperatingActivites", | |
| "growthOperatingCashFlow" | |
| ] | |
| try: | |
| fig_op = px.line(df, x="date", y=operating_vars, title="Operating Cash Flow Growth") | |
| fig_op.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_op, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Operating CF Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, operating_vars, "Operating CF Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in operating_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 2. Investing Activities | |
| st.subheader("2. Investing Activities") | |
| investing_vars = [ | |
| "growthInvestmentsInPropertyPlantAndEquipment", "growthAcquisitionsNet", | |
| "growthPurchasesOfInvestments", "growthSalesMaturitiesOfInvestments", | |
| "growthNetCashUsedForInvestingActivites" | |
| ] | |
| try: | |
| fig_inv = px.line(df, x="date", y=investing_vars, title="Investing Cash Flow Growth") | |
| fig_inv.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_inv, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Investing CF Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, investing_vars, "Investing CF Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in investing_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 3. Financing Activities | |
| st.subheader("3. Financing Activities") | |
| financing_vars = [ | |
| "growthDebtRepayment", "growthCommonStockRepurchased", | |
| "growthDividendsPaid", "growthNetCashUsedProvidedByFinancingActivities" | |
| ] | |
| try: | |
| fig_fin = px.line(df, x="date", y=financing_vars, title="Financing Cash Flow Growth") | |
| fig_fin.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_fin, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Financing CF Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, financing_vars, "Financing CF Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in financing_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # 4. Free Cash Flow | |
| st.subheader("4. Free Cash Flow") | |
| fcf_vars = ["growthFreeCashFlow"] | |
| try: | |
| fig_fcf = px.line(df, x="date", y=fcf_vars, title="Free Cash Flow Growth") | |
| fig_fcf.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric") | |
| st.plotly_chart(fig_fcf, use_container_width=True) | |
| except Exception: | |
| st.error("Could not plot Free Cash Flow Growth.") | |
| with st.expander("Interpretation"): | |
| st.markdown(interpret_growth_metrics(df, fcf_vars, "Free Cash Flow Growth")) | |
| with st.expander("DataFrame"): | |
| cols = ["date"] + [c for c in fcf_vars if c in df.columns] | |
| st.dataframe(df[cols]) | |
| # ---------------------------- | |
| # Main | |
| # ---------------------------- | |
| st.title("Financial Growth Metrics") | |
| st.markdown(""" | |
| This dashboard shows key financial growth metrics across balance sheet, | |
| income statement, and cash flow statement. | |
| Use the sidebar to set inputs, then press **Run Analysis**. | |
| After that, you can switch pages without re-running. | |
| """) | |
| # Sidebar Navigation | |
| st.sidebar.header("Navigation") | |
| page = st.sidebar.radio( | |
| "Select Page", | |
| ["Financial Growth", "Balance Sheet Growth", "Income Growth", "Cash Flow Growth"], | |
| index=0 | |
| ) | |
| st.sidebar.header("Inputs") | |
| symbol = st.sidebar.text_input("Company Symbol", value="AAPL") | |
| period = st.sidebar.selectbox("Period", options=["annual", "quarter"]) | |
| # Here is the run button | |
| run_button = st.sidebar.button("Run Analysis") | |
| # If user hasn't clicked "Run Analysis," do not load data | |
| if not run_button and f"{page.lower().replace(' ', '_')}_{symbol}_{period}" not in st.session_state: | |
| st.warning("Press 'Run Analysis' to fetch data and see the results.") | |
| else: | |
| # If user clicked "Run", or data is cached from a previous run, show the selected page | |
| if page == "Financial Growth": | |
| show_financial_growth(symbol, period) | |
| elif page == "Balance Sheet Growth": | |
| show_balance_sheet_growth(symbol, period) | |
| elif page == "Income Growth": | |
| show_income_growth(symbol, period) | |
| elif page == "Cash Flow Growth": | |
| show_cashflow_growth(symbol, period) | |
| # Hide Streamlit default style | |
| hide_streamlit_style = """ | |
| <style> | |
| #MainMenu {visibility: hidden;} | |
| footer {visibility: hidden;} | |
| </style> | |
| """ | |
| st.markdown(hide_streamlit_style, unsafe_allow_html=True) | |