import gradio as gr from gradio.themes import Default import pandas as pd import plotly.express as px import requests def get_financial_summary(): try: response = requests.get("http://localhost:8000/api/financial_summary") response.raise_for_status() data = response.json() except Exception: data = {"revenue": 1000, "expenses": 500, "savings": 500} return data def display_financial_charts(): df = pd.DataFrame( { "Month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"], "Credit": [1000, 1200, 900, 1300, 1500, 1700], "Expenses": [400, 600, 500, 700, 800, 900], } ) df["Savings"] = df["Credit"] - df["Expenses"] # fig1 = px.line(df, x="Month", y="Credit", title="Monthly Credit") fig2 = px.bar(df, x="Month", y="Expenses", title="Monthly Expenses") fig3 = px.area(df, x="Month", y="Savings", title="Monthly Savings") latest = df.iloc[-1] fig4 = px.pie( names=["Food", "Retail", "Others"], values=[latest["Credit"], latest["Expenses"], latest["Savings"]], title="Latest Financial Distribution", ) return fig2, fig3, fig4 def chatbot_respond(user_message, history): history = history or [] if user_message: history.append({"role": "user", "content": user_message}) try: response = requests.post( "https://green-smoke-labs-dev--green-smoke-labs-expensynth-api-server.modal.run/bot/query", json={"messages": history}, ) response.raise_for_status() bot_reply = ( response.json().get("data", {}).get("raw", "Sorry, I didn't understand.") ) except Exception: bot_reply = "Server unavailable. This is a mocked reply." history.append({"role": "assistant", "content": bot_reply}) return "", history, history def reset_chat(): """Reset chat history and clear the chatbot text box.""" return "", [], [] def minimize_chat(): return gr.update(visible=False), gr.update(visible=True) def restore_chat(): return gr.update(visible=True), gr.update(visible=False) # Frontend with gr.Blocks( theme=Default(), css=""" #profile-pic-wrapper { width: 100px; height: 100px; border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px auto; background: #fff; } #profile-icon { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; margin: 0; } .header h1 { margin: 0; font-family: 'Arial', sans-serif; color: #333; } .left-navbar { background-color: #fff; padding: 20px; border-right: 1px solid #ddd; min-height: 80vh; } .chat-panel { position: fixed; top: 20px; right: 20px; left: auto; width: 350px; height: 620px; background: #fff; border: 1px solid #ddd; box-shadow: 2px 2px 10px rgba(0,0,0,0.1); border-radius: 8px; padding: 10px; overflow: visible; z-index: 1001; } #open-chat-btn { position: fixed; bottom: 20px; right: 20px; left: auto; z-index: 1000; } #chatbot-input { height: 150px; } """, ) as demo: chat_panel = gr.Column(visible=True, elem_classes="chat-panel") with chat_panel: gr.Markdown("### Financial Agent", height=200) chatbot_state = gr.State([]) chatbot_ui = gr.Chatbot(type="messages") chatbot_input = gr.Textbox( placeholder="Type your message...", label="Your Message", elem_id="chatbot-input", ) with gr.Row(): send_btn = gr.Button("Send") reset_btn = gr.Button("Reset Chat") minimize_btn = gr.Button("Minimize", elem_id="minimize-chat-btn") with gr.Row(): # gr.HTML( # '
' # ) gr.Markdown("

Financial Health Dashboard

", elem_classes="header") with gr.Row(): # with gr.Column(scale=1, elem_classes="left-navbar"): # gr.Markdown("## Navigation") # for nav in ["Dashboard", "Reports", "Analytics", "Settings"]: # gr.Button(nav) with gr.Column(scale=3): with gr.Tabs(): with gr.TabItem("Charts"): fig2, fig3, fig4 = display_financial_charts() # gr.Plot(fig1) gr.Plot(fig2) gr.Plot(fig3) gr.Plot(fig4) with gr.TabItem("Overview"): # summary = get_financial_summary() summary = chatbot_respond("What is the financial summary?", [])[-1][ -1 ]["content"] advice = chatbot_respond( "What financial advice can you give? Give general advice, do not give anything specific to my transactions", [], )[-1][-1]["content"] gr.Markdown( f"""### Summary\n{summary}\n\n### Financial Advice\n{advice}""" ) minimized_state = gr.State(False) open_btn = gr.Button("Open Chat", elem_id="open-chat-btn", visible=False) chatbot_input.submit( fn=chatbot_respond, inputs=[chatbot_input, chatbot_state], outputs=[chatbot_input, chatbot_state, chatbot_ui], queue=False, ) send_btn.click( fn=chatbot_respond, inputs=[chatbot_input, chatbot_state], outputs=[chatbot_input, chatbot_state, chatbot_ui], queue=False, ) reset_btn.click( fn=reset_chat, inputs=None, outputs=[chatbot_input, chatbot_state, chatbot_ui], queue=False, ) minimize_btn.click( fn=minimize_chat, inputs=None, outputs=[chat_panel, open_btn], queue=False, ) open_btn.click( fn=restore_chat, inputs=None, outputs=[chat_panel, open_btn], queue=False, ) demo.launch()