File size: 5,027 Bytes
b7e8018
 
 
8bbf3cf
b7e8018
 
8bbf3cf
b7e8018
f95647d
b7e8018
 
8bbf3cf
 
 
 
 
 
 
 
 
 
 
 
 
 
b7e8018
 
 
8bbf3cf
 
b7e8018
 
 
 
 
8bbf3cf
b7e8018
8bbf3cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b7e8018
8bbf3cf
 
 
b7e8018
8bbf3cf
 
 
 
 
 
 
 
 
 
 
 
 
 
b7e8018
8bbf3cf
 
 
 
 
b7e8018
8bbf3cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b7e8018
 
8bbf3cf
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#Gradio app
# app.py
# app.py - Original approach with profile object
# app.py
import gradio as gr
import requests
import json

MODAL_URL = "https://devsam2898--personal-investment-strategist-optimized-web.modal.run/strategy"

def get_investment_strategy(age_group, income, expenses, risk_profile, goal, timeframe):
    """
    Get investment strategy from Modal backend
    """
    # Input validation
    if not all([age_group, income, expenses, risk_profile, goal, timeframe]):
        return "❌ Please fill in all fields to get a personalized strategy."
    
    # Convert income and expenses to numbers if they're strings
    try:
        income_val = float(income.replace('$', '').replace(',', '')) if isinstance(income, str) else float(income)
        expenses_val = float(expenses.replace('$', '').replace(',', '')) if isinstance(expenses, str) else float(expenses)
    except ValueError:
        return "❌ Please enter valid numbers for income and expenses."
    
    payload = {
        "profile": {
            "age_group": age_group,
            "income": income_val,
            "expenses": expenses_val,
            "risk_profile": risk_profile,
            "goal": goal,
            "timeframe": timeframe
        }
    }
    
    try:
        print(f"Sending request to: {MODAL_URL}")
        print(f"Payload: {json.dumps(payload, indent=2)}")
        
        response = requests.post(
            MODAL_URL, 
            json=payload,
            headers={
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            timeout=30  # Add timeout
        )
        
        print(f"Response status: {response.status_code}")
        print(f"Response headers: {dict(response.headers)}")
        
        if response.status_code == 200:
            result = response.json()
            strategy = result.get("strategy", "No strategy returned.")
            return f"## πŸ“Š Your Personalized Investment Strategy\n\n{strategy}"
        else:
            error_msg = f"❌ **Error {response.status_code}**\n\n"
            try:
                error_detail = response.json()
                error_msg += f"Details: {error_detail}"
            except:
                error_msg += f"Response: {response.text}"
            return error_msg
            
    except requests.exceptions.Timeout:
        return "❌ **Request Timeout**: The service is taking too long to respond. Please try again."
    except requests.exceptions.ConnectionError:
        return "❌ **Connection Error**: Unable to connect to the backend service. Please check if the Modal service is running."
    except requests.exceptions.RequestException as e:
        return f"❌ **Network Error**: {str(e)}"
    except Exception as e:
        return f"❌ **Unexpected Error**: {str(e)}"

# Test function to verify the function works
def test_function():
    return "βœ… Function is working correctly!"

# Create the interface
with gr.Blocks(theme="soft", title="πŸ“ˆ Personal Finance Strategist") as interface:
    gr.Markdown(
        """
        # πŸ“ˆ Personal Finance Strategist
        **Powered by LlamaIndex + Nebius Qwen3**
        
        Get personalized investment strategies based on your life stage and financial goals.
        """
    )
    
    with gr.Row():
        with gr.Column(scale=1):
            age_group = gr.Dropdown(
                choices=["20s", "30s", "40s", "50s+"], 
                label="Age Group",
                value="30s"
            )
            income = gr.Textbox(
                label="Monthly Income ($)", 
                value="6000",
                placeholder="e.g., 6000"
            )
            expenses = gr.Textbox(
                label="Monthly Expenses ($)", 
                value="4000",
                placeholder="e.g., 4000"
            )
            
        with gr.Column(scale=1):
            risk_profile = gr.Radio(
                choices=["Conservative", "Moderate", "Aggressive"], 
                label="Risk Tolerance",
                value="Moderate"
            )
            goal = gr.Textbox(
                label="Financial Goal", 
                placeholder="e.g., buy a house, retirement, emergency fund"
            )
            timeframe = gr.Textbox(
                label="Timeframe", 
                placeholder="e.g., 5 years, 10 years"
            )
    
    with gr.Row():
        submit_btn = gr.Button("Get Investment Strategy", variant="primary")
        test_btn = gr.Button("Test Connection", variant="secondary")
    
    output = gr.Markdown(label="Investment Strategy")
    
    # Event handlers
    submit_btn.click(
        fn=get_investment_strategy,
        inputs=[age_group, income, expenses, risk_profile, goal, timeframe],
        outputs=output
    )
    
    test_btn.click(
        fn=test_function,
        outputs=output
    )

if __name__ == "__main__":
    interface.launch(
        server_name="0.0.0.0",
        server_port=7860,
        share=False
    )