Update app.py
Browse files
app.py
CHANGED
|
@@ -671,8 +671,22 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 671 |
comparison_output = gr.Markdown()
|
| 672 |
|
| 673 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 674 |
recommend_btn.click(
|
| 675 |
-
fn=
|
| 676 |
inputs=[user_dropdown, merchant_dropdown, category_dropdown, amount_input],
|
| 677 |
outputs=[recommendation_output, recommendation_chart]
|
| 678 |
)
|
|
@@ -839,56 +853,47 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 839 |
def update_analytics_with_charts(user_id: str):
|
| 840 |
"""Fetch and format analytics with charts for selected user"""
|
| 841 |
|
| 842 |
-
# Show loading state first
|
| 843 |
-
empty_fig = create_empty_chart("⏳ Loading...")
|
| 844 |
-
loading_html = """
|
| 845 |
-
<div style="text-align: center; padding: 40px;">
|
| 846 |
-
<h2>⏳ Loading Analytics...</h2>
|
| 847 |
-
<p>Please wait while we fetch your data</p>
|
| 848 |
-
</div>
|
| 849 |
-
"""
|
| 850 |
-
|
| 851 |
-
yield (
|
| 852 |
-
loading_html,
|
| 853 |
-
empty_fig, empty_fig, empty_fig, empty_fig, empty_fig,
|
| 854 |
-
"⏳ Loading...",
|
| 855 |
-
"⏳ Loading...",
|
| 856 |
-
"⏳ Loading...",
|
| 857 |
-
"*Loading analytics...*"
|
| 858 |
-
)
|
| 859 |
-
|
| 860 |
try:
|
| 861 |
# Fetch analytics data from API
|
| 862 |
result = client.get_user_analytics(user_id)
|
| 863 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 864 |
# Check if request was successful
|
| 865 |
if not result.get('success'):
|
| 866 |
error_msg = result.get('error', 'Unknown error')
|
| 867 |
-
|
| 868 |
-
|
| 869 |
f"<p>❌ Error: {error_msg}</p>",
|
| 870 |
-
|
| 871 |
"Error loading data",
|
| 872 |
"Error loading data",
|
| 873 |
"Error loading data",
|
| 874 |
f"*Error: {error_msg}*"
|
| 875 |
)
|
| 876 |
-
return
|
| 877 |
|
| 878 |
-
# Extract the actual data
|
| 879 |
analytics_data = result.get('data', {})
|
| 880 |
|
|
|
|
| 881 |
if not analytics_data:
|
| 882 |
-
|
| 883 |
-
|
| 884 |
"<p>No data available</p>",
|
| 885 |
-
|
| 886 |
"No data",
|
| 887 |
"No data",
|
| 888 |
"No data",
|
| 889 |
"*No data available*"
|
| 890 |
)
|
| 891 |
-
return
|
| 892 |
|
| 893 |
# Import chart functions
|
| 894 |
from utils.formatters import (
|
|
@@ -900,10 +905,10 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 900 |
create_card_performance_chart
|
| 901 |
)
|
| 902 |
|
| 903 |
-
# Format text data
|
| 904 |
metrics_html, table_md, insights_md, forecast_md = format_analytics_metrics(analytics_data)
|
| 905 |
|
| 906 |
-
# Generate charts
|
| 907 |
spending_fig = create_spending_chart(analytics_data)
|
| 908 |
pie_fig = create_rewards_pie_chart(analytics_data)
|
| 909 |
gauge_fig = create_optimization_gauge(analytics_data)
|
|
@@ -914,17 +919,17 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 914 |
from datetime import datetime
|
| 915 |
status = f"*Analytics updated for {user_id} at {datetime.now().strftime('%I:%M %p')}*"
|
| 916 |
|
| 917 |
-
|
| 918 |
-
metrics_html,
|
| 919 |
-
spending_fig,
|
| 920 |
-
gauge_fig,
|
| 921 |
-
pie_fig,
|
| 922 |
-
performance_fig,
|
| 923 |
-
trend_fig,
|
| 924 |
-
table_md,
|
| 925 |
-
insights_md,
|
| 926 |
-
forecast_md,
|
| 927 |
-
status
|
| 928 |
)
|
| 929 |
|
| 930 |
except Exception as e:
|
|
@@ -934,11 +939,12 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 934 |
print(error_msg)
|
| 935 |
print(error_details)
|
| 936 |
|
| 937 |
-
|
|
|
|
| 938 |
|
| 939 |
-
|
| 940 |
f"<p>{error_msg}</p>",
|
| 941 |
-
|
| 942 |
"Error loading table",
|
| 943 |
"Error loading insights",
|
| 944 |
"Error loading forecast",
|
|
@@ -993,6 +999,7 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 993 |
]
|
| 994 |
)
|
| 995 |
# Tab 3: Chat (NEW!)
|
|
|
|
| 996 |
with gr.Tab("💬 Ask AI"):
|
| 997 |
gr.Markdown("## Chat with RewardPilot AI")
|
| 998 |
gr.Markdown("*Ask questions about credit cards, rewards, and your spending*")
|
|
@@ -1014,14 +1021,10 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 1014 |
)
|
| 1015 |
|
| 1016 |
def respond(message, chat_history, user_id):
|
| 1017 |
-
"""Handle chat responses with error handling
|
| 1018 |
if not message.strip():
|
| 1019 |
return "", chat_history
|
| 1020 |
|
| 1021 |
-
# Add loading message
|
| 1022 |
-
loading_history = chat_history + [(message, "⏳ Thinking...")]
|
| 1023 |
-
yield "", loading_history
|
| 1024 |
-
|
| 1025 |
# Get user context
|
| 1026 |
user_context = {}
|
| 1027 |
try:
|
|
@@ -1052,7 +1055,23 @@ Get AI-powered credit card recommendations that maximize your rewards based on:
|
|
| 1052 |
bot_response = f"I encountered an error. Please try asking your question differently."
|
| 1053 |
|
| 1054 |
chat_history.append((message, bot_response))
|
| 1055 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1056 |
# ========== Tab 3: About ==========
|
| 1057 |
with gr.Tab("ℹ️ About"):
|
| 1058 |
gr.Markdown(
|
|
|
|
| 671 |
comparison_output = gr.Markdown()
|
| 672 |
|
| 673 |
|
| 674 |
+
# recommend_btn.click(
|
| 675 |
+
# fn=get_recommendation_with_ai,
|
| 676 |
+
# inputs=[user_dropdown, merchant_dropdown, category_dropdown, amount_input],
|
| 677 |
+
# outputs=[recommendation_output, recommendation_chart]
|
| 678 |
+
# )
|
| 679 |
+
def get_recommendation_with_loading(user_id, merchant, category, amount):
|
| 680 |
+
"""Wrapper to show loading state"""
|
| 681 |
+
# Show loading first
|
| 682 |
+
yield "⏳ **Loading recommendation...** Please wait...", None
|
| 683 |
+
|
| 684 |
+
# Get actual result
|
| 685 |
+
result = get_recommendation_with_ai(user_id, merchant, category, amount)
|
| 686 |
+
yield result
|
| 687 |
+
|
| 688 |
recommend_btn.click(
|
| 689 |
+
fn=get_recommendation_with_loading,
|
| 690 |
inputs=[user_dropdown, merchant_dropdown, category_dropdown, amount_input],
|
| 691 |
outputs=[recommendation_output, recommendation_chart]
|
| 692 |
)
|
|
|
|
| 853 |
def update_analytics_with_charts(user_id: str):
|
| 854 |
"""Fetch and format analytics with charts for selected user"""
|
| 855 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 856 |
try:
|
| 857 |
# Fetch analytics data from API
|
| 858 |
result = client.get_user_analytics(user_id)
|
| 859 |
|
| 860 |
+
# DEBUG: Print what we received
|
| 861 |
+
print("=" * 60)
|
| 862 |
+
print(f"DEBUG: Analytics for {user_id}")
|
| 863 |
+
print(f"Success: {result.get('success')}")
|
| 864 |
+
if result.get('data'):
|
| 865 |
+
print(f"Data keys: {result['data'].keys()}")
|
| 866 |
+
print(f"Total spending: {result['data'].get('total_spending')}")
|
| 867 |
+
print(f"Total rewards: {result['data'].get('total_rewards')}")
|
| 868 |
+
print("=" * 60)
|
| 869 |
+
|
| 870 |
# Check if request was successful
|
| 871 |
if not result.get('success'):
|
| 872 |
error_msg = result.get('error', 'Unknown error')
|
| 873 |
+
empty_fig = create_empty_chart(f"Error: {error_msg}")
|
| 874 |
+
return (
|
| 875 |
f"<p>❌ Error: {error_msg}</p>",
|
| 876 |
+
empty_fig, empty_fig, empty_fig, empty_fig, empty_fig,
|
| 877 |
"Error loading data",
|
| 878 |
"Error loading data",
|
| 879 |
"Error loading data",
|
| 880 |
f"*Error: {error_msg}*"
|
| 881 |
)
|
|
|
|
| 882 |
|
| 883 |
+
# ✅ Extract the actual data
|
| 884 |
analytics_data = result.get('data', {})
|
| 885 |
|
| 886 |
+
# Verify we have data
|
| 887 |
if not analytics_data:
|
| 888 |
+
empty_fig = create_empty_chart("No analytics data available")
|
| 889 |
+
return (
|
| 890 |
"<p>No data available</p>",
|
| 891 |
+
empty_fig, empty_fig, empty_fig, empty_fig, empty_fig,
|
| 892 |
"No data",
|
| 893 |
"No data",
|
| 894 |
"No data",
|
| 895 |
"*No data available*"
|
| 896 |
)
|
|
|
|
| 897 |
|
| 898 |
# Import chart functions
|
| 899 |
from utils.formatters import (
|
|
|
|
| 905 |
create_card_performance_chart
|
| 906 |
)
|
| 907 |
|
| 908 |
+
# Format text data (pass unwrapped data)
|
| 909 |
metrics_html, table_md, insights_md, forecast_md = format_analytics_metrics(analytics_data)
|
| 910 |
|
| 911 |
+
# Generate charts (pass unwrapped data)
|
| 912 |
spending_fig = create_spending_chart(analytics_data)
|
| 913 |
pie_fig = create_rewards_pie_chart(analytics_data)
|
| 914 |
gauge_fig = create_optimization_gauge(analytics_data)
|
|
|
|
| 919 |
from datetime import datetime
|
| 920 |
status = f"*Analytics updated for {user_id} at {datetime.now().strftime('%I:%M %p')}*"
|
| 921 |
|
| 922 |
+
return (
|
| 923 |
+
metrics_html, # Metric cards
|
| 924 |
+
spending_fig, # Spending bar chart
|
| 925 |
+
gauge_fig, # Optimization gauge
|
| 926 |
+
pie_fig, # Rewards pie chart
|
| 927 |
+
performance_fig, # Card performance chart
|
| 928 |
+
trend_fig, # Trend line chart
|
| 929 |
+
table_md, # Spending table
|
| 930 |
+
insights_md, # Insights text
|
| 931 |
+
forecast_md, # Forecast text
|
| 932 |
+
status # Status message
|
| 933 |
)
|
| 934 |
|
| 935 |
except Exception as e:
|
|
|
|
| 939 |
print(error_msg)
|
| 940 |
print(error_details)
|
| 941 |
|
| 942 |
+
# Return empty/error states
|
| 943 |
+
empty_fig = create_empty_chart("Error loading chart")
|
| 944 |
|
| 945 |
+
return (
|
| 946 |
f"<p>{error_msg}</p>",
|
| 947 |
+
empty_fig, empty_fig, empty_fig, empty_fig, empty_fig,
|
| 948 |
"Error loading table",
|
| 949 |
"Error loading insights",
|
| 950 |
"Error loading forecast",
|
|
|
|
| 999 |
]
|
| 1000 |
)
|
| 1001 |
# Tab 3: Chat (NEW!)
|
| 1002 |
+
# Tab 3: Chat (NEW!)
|
| 1003 |
with gr.Tab("💬 Ask AI"):
|
| 1004 |
gr.Markdown("## Chat with RewardPilot AI")
|
| 1005 |
gr.Markdown("*Ask questions about credit cards, rewards, and your spending*")
|
|
|
|
| 1021 |
)
|
| 1022 |
|
| 1023 |
def respond(message, chat_history, user_id):
|
| 1024 |
+
"""Handle chat responses with error handling"""
|
| 1025 |
if not message.strip():
|
| 1026 |
return "", chat_history
|
| 1027 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1028 |
# Get user context
|
| 1029 |
user_context = {}
|
| 1030 |
try:
|
|
|
|
| 1055 |
bot_response = f"I encountered an error. Please try asking your question differently."
|
| 1056 |
|
| 1057 |
chat_history.append((message, bot_response))
|
| 1058 |
+
return "", chat_history
|
| 1059 |
+
|
| 1060 |
+
msg.submit(respond, [msg, chatbot, chat_user], [msg, chatbot])
|
| 1061 |
+
send_btn.click(respond, [msg, chatbot, chat_user], [msg, chatbot])
|
| 1062 |
+
|
| 1063 |
+
# ✅ RESTORED: Example questions
|
| 1064 |
+
gr.Markdown("### 💡 Try asking:")
|
| 1065 |
+
gr.Examples(
|
| 1066 |
+
examples=[
|
| 1067 |
+
["Which card should I use at Costco?"],
|
| 1068 |
+
["How can I maximize my grocery rewards?"],
|
| 1069 |
+
["What's the best travel card for international trips?"],
|
| 1070 |
+
["Tell me about the Amex Gold card"],
|
| 1071 |
+
["Am I close to any spending caps?"],
|
| 1072 |
+
],
|
| 1073 |
+
inputs=[msg]
|
| 1074 |
+
)
|
| 1075 |
# ========== Tab 3: About ==========
|
| 1076 |
with gr.Tab("ℹ️ About"):
|
| 1077 |
gr.Markdown(
|