expensynth / app.py
Shankar
fix chatbot pos 4
4b2a563
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()