Spaces:
Sleeping
Sleeping
| 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( | |
| # '<div id="profile-pic-wrapper"><img id="profile-icon" src="assets/profile_pic.png" /></div>' | |
| # ) | |
| gr.Markdown("<h1>Financial Health Dashboard</h1>", 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() | |