CrisesLensApp / app.py
techatcreated's picture
Update app.py
af55ad1 verified
# ---------------- APP ----------------
# This is the main file to run the Gradio application.
# It imports logic from logic.py and configuration from config.py
import gradio as gr
# Import constants needed for the UI
from config import CRISIS_PERIODS, EXAMPLE_PORTFOLIOS, CRISIS_SUMMARY
# Import the main simulation function
from logic import run_crisis_simulation
# --- UI Helper Functions ---
def load_example(example_name):
"""Updates ticker and weight textboxes based on selection."""
portfolio = EXAMPLE_PORTFOLIOS.get(example_name, {"tickers": "", "weights": ""})
return gr.update(value=portfolio["tickers"]), gr.update(value=portfolio["weights"])
def update_crisis_summary(crisis_name):
"""Updates the crisis summary text when a crisis is selected."""
summary = CRISIS_SUMMARY.get(crisis_name, "")
if summary:
return f"**Crisis summary:** _{summary}_"
return ""
# ---------------- UI DEFINITION ----------------
with gr.Blocks(title="Crisis Lens (India)") as demo:
gr.Markdown(
"""
# ๐Ÿ‡ฎ๐Ÿ‡ณ Crisis Lens โ€” Indian Stock Stress Simulator
How would your portfolio have performed during a major market crisis?
Select a historical crisis and your portfolio to find out.
"""
)
with gr.Row():
with gr.Column(scale=2):
crisis_dd = gr.Dropdown(
list(CRISIS_PERIODS.keys()),
label="Select Crisis",
value="COVID-19 Crash (India)",
)
crisis_info = gr.Markdown(
f"**Crisis summary:** _{CRISIS_SUMMARY['COVID-19 Crash (India)']}_",
elem_classes="crisis-summary",
)
with gr.Column(scale=1):
example_loader_dd = gr.Dropdown(
list(EXAMPLE_PORTFOLIOS.keys()),
label="Load Example Portfolio",
value="Select Example...", # will be overridden by .load()
)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 1. Define Your Portfolio")
upload_csv = gr.File(
label="Upload Portfolio CSV (Ticker,Weight)",
file_types=[".csv"]
)
gr.Markdown("...or enter manually below:")
tickers_input = gr.Textbox(
label="Tickers (comma separated)",
value=""
)
weights_input = gr.Textbox(
label="Weights (comma separated)",
value=""
)
add_etf_cb = gr.Checkbox(
label="Add 5% NIFTYBEES.NS to portfolio (diversify)",
value=False
)
gr.Markdown("---")
gr.Markdown("### ๐Ÿค– 2. AI Insights (Optional)")
gemini_api_key_in = gr.Textbox(
label="Gemini API Key (optional, not stored)",
placeholder="Paste your Gemini API key here to get AI-generated insights",
type="password",
)
gemini_extra_prompt_in = gr.Textbox(
label="Extra instructions for AI (optional)",
placeholder="e.g., Focus more on risk, or write in simple language, etc.",
lines=2,
)
gr.Markdown("---")
run_btn = gr.Button("Run Simulation", variant="primary")
logs_txt = gr.Textbox(label="Status / Logs", interactive=False)
with gr.Column(scale=3):
gr.Markdown("### 3. Analyze the Results")
plot_performance = gr.Plot()
with gr.Row():
metrics_output = gr.Markdown()
pie_chart = gr.Plot()
with gr.Row():
sector_plot_output = gr.Plot()
insights_output = gr.Markdown()
gr.Markdown("### ๐Ÿค– AI-Generated Insights")
gemini_insights_md = gr.Markdown(
value="*AI insights will appear here after running simulation with a Gemini API key.*"
)
# ---------------- EVENT HANDLERS ----------------
crisis_dd.change(
fn=update_crisis_summary,
inputs=[crisis_dd],
outputs=[crisis_info],
)
example_loader_dd.change(
fn=load_example,
inputs=[example_loader_dd],
outputs=[tickers_input, weights_input],
)
run_btn.click(
run_crisis_simulation,
inputs=[
crisis_dd,
upload_csv,
tickers_input,
weights_input,
add_etf_cb,
gemini_api_key_in,
gemini_extra_prompt_in,
],
outputs=[
plot_performance,
metrics_output,
sector_plot_output,
insights_output,
pie_chart,
logs_txt,
gemini_insights_md,
],
)
def load_default_example():
default_name = "Large-Cap (Default)"
portfolio = EXAMPLE_PORTFOLIOS.get(default_name, {"tickers": "", "weights": ""})
summary = CRISIS_SUMMARY.get("COVID-19 Crash (India)", "")
return (
gr.update(value=default_name),
gr.update(value=portfolio["tickers"]),
gr.update(value=portfolio["weights"]),
f"**Crisis summary:** _{summary}_",
)
demo.load(
fn=load_default_example,
inputs=None,
outputs=[example_loader_dd, tickers_input, weights_input, crisis_info],
)
# ---------------- LAUNCH ----------------
if __name__ == "__main__":
demo.launch(share=True, debug=True)