saiganesh2004 commited on
Commit
5b2a369
Β·
verified Β·
1 Parent(s): e94b56c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +268 -155
app.py CHANGED
@@ -1,7 +1,7 @@
1
  import streamlit as st
2
  from datetime import datetime
3
- from prompt_builder import build_prompt, bmi_category # Import from prompt_builder
4
- from model_api import query_model # Import the model API
5
 
6
  st.set_page_config(
7
  page_title="FIT Plan AI - Milestone 1",
@@ -12,161 +12,140 @@ st.set_page_config(
12
  st.title("πŸ’ͺ FIT Plan AI – Personalized Fitness Profile")
13
  st.markdown("---")
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  # Initialize session state
16
  if "form_submitted" not in st.session_state:
17
  st.session_state.form_submitted = False
18
  if "workout_plan" not in st.session_state:
19
  st.session_state.workout_plan = None
 
 
20
 
21
- with st.form("fitness_profile_form"):
22
- st.header("πŸ“‹ Your Fitness Profile")
23
- st.subheader("πŸ‘€ Personal Information")
24
-
25
- col1, col2 = st.columns(2)
26
-
27
- with col1:
28
- name = st.text_input("Full Name *")
29
- height = st.number_input("Height (cm) *", min_value=1.0, max_value=300.0, value=170.0)
30
-
31
- with col2:
32
- age = st.number_input("Age", min_value=10, max_value=120, value=25)
33
- weight = st.number_input("Weight (kg) *", min_value=1.0, max_value=500.0, value=70.0)
34
-
35
- gender = st.selectbox("Gender", ["Male", "Female", "Other"])
36
-
37
- st.subheader("🎯 Fitness Details")
38
-
39
- goal = st.selectbox(
40
- "Fitness Goal *",
41
- ["Weight Loss", "Build Muscle", "Strength Gain", "Abs Building", "Flexibility"]
42
- )
43
-
44
- equipment = st.multiselect(
45
- "Available Equipment *",
46
- [
47
- "Dumbbells",
48
- "Resistance Bands",
49
- "Barbell",
50
- "Pull-up Bar",
51
- "Treadmill",
52
- "Kettlebells",
53
- "Jump Rope",
54
- "Yoga Mat",
55
- "No Equipment (Bodyweight only)"
56
- ],
57
- default=["No Equipment (Bodyweight only)"]
58
- )
59
-
60
- fitness_level = st.select_slider(
61
- "Fitness Level *",
62
- options=["Beginner", "Intermediate", "Advanced"],
63
- value="Beginner"
64
- )
65
-
66
- st.markdown("---")
67
- submit = st.form_submit_button("Submit Profile", use_container_width=True)
68
-
69
- if submit:
70
- if not name:
71
- st.error("Please enter your name.")
72
- st.stop()
73
-
74
- if not equipment:
75
- st.error("Please select at least one equipment option.")
76
- st.stop()
77
-
78
- # Build prompt using the imported function
79
- prompt, bmi, bmi_status = build_prompt(
80
- name=name,
81
- gender=gender,
82
- height=height,
83
- weight=weight,
84
- goal=goal,
85
- fitness_level=fitness_level,
86
- equipment=equipment
87
- )
88
-
89
- st.success("βœ… Profile Submitted Successfully!")
90
-
91
- st.session_state.update({
92
- "form_submitted": True,
93
- "name": name,
94
- "bmi": bmi,
95
- "bmi_status": bmi_status,
96
- "age": age,
97
- "goal": goal,
98
- "equipment": equipment,
99
- "fitness_level": fitness_level,
100
- "height": height,
101
- "weight": weight,
102
- "gender": gender,
103
- "prompt": prompt # Store the generated prompt
104
- })
105
-
106
- if st.session_state.form_submitted:
107
- st.markdown("---")
108
- st.success(f"Welcome, **{st.session_state.name}**!")
109
-
110
- col1, col2, col3 = st.columns(3)
111
- col1.metric("πŸ“Š BMI", f"{st.session_state.bmi:.2f}")
112
- col2.metric("🏷 Category", st.session_state.bmi_status)
113
- col3.metric("πŸ‹οΈ Level", st.session_state.fitness_level)
114
-
115
- # Generate Workout Plan Button
116
- st.markdown("---")
117
- st.subheader("πŸ‹οΈ Generate Your Personalized Workout Plan")
118
-
119
- if st.button("Generate Workout Plan", type="primary", use_container_width=True):
120
- with st.spinner("Creating your personalized workout plan... This may take a moment."):
121
- # Call the model API
122
- workout_plan = query_model(st.session_state.prompt)
123
- st.session_state.workout_plan = workout_plan
124
-
125
- # Display workout plan if generated
126
- if st.session_state.workout_plan:
127
- st.markdown("---")
128
- st.subheader("πŸ“‹ Your 5-Day Workout Plan")
129
-
130
- with st.container():
131
- st.markdown(st.session_state.workout_plan)
132
-
133
- # Download button for workout plan
134
- workout_text = f"""
135
- FIT PLAN AI - PERSONALIZED WORKOUT PLAN
136
- Generated for: {st.session_state.name}
137
- Date: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
138
 
139
- Profile Summary:
140
- - BMI: {st.session_state.bmi:.2f} ({st.session_state.bmi_status})
141
- - Goal: {st.session_state.goal}
142
- - Level: {st.session_state.fitness_level}
143
- - Equipment: {', '.join(st.session_state.equipment)}
144
-
145
- {st.session_state.workout_plan}
146
 
147
- ---
148
- Stay consistent and trust the process!
149
- """
150
-
151
  col1, col2 = st.columns(2)
 
152
  with col1:
153
- st.download_button(
154
- "πŸ“₯ Download Workout Plan",
155
- data=workout_text,
156
- file_name=f"FITPlanAI_{st.session_state.name}_Workout.txt",
157
- mime="text/plain",
158
- use_container_width=True
159
- )
160
-
161
  with col2:
162
- if st.button("Generate New Plan", use_container_width=True):
163
- st.session_state.workout_plan = None
164
- st.rerun()
165
-
166
- # Profile Report Section
167
- st.markdown("---")
168
- with st.expander("πŸ“„ View Profile Report"):
169
- report_text = f"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  FIT PLAN AI - PROFILE REPORT
171
  Generated on: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
172
 
@@ -183,16 +162,150 @@ Goal: {st.session_state.goal}
183
  Level: {st.session_state.fitness_level}
184
  Equipment: {', '.join(st.session_state.equipment)}
185
 
186
- Stay consistent and trust the process!
187
  """
188
 
189
- st.download_button(
190
- "πŸ“₯ Download Profile Report",
191
- data=report_text,
192
- file_name=f"FITPlanAI_{st.session_state.name}_Profile.txt",
193
- mime="text/plain",
194
- use_container_width=True
195
- )
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  st.markdown("---")
198
- st.caption("FIT Plan AI - Milestone 1 | Powered by Mistral-7B")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  from datetime import datetime
3
+ from prompt_builder import build_prompt
4
+ from model_api import query_model, test_api_connection
5
 
6
  st.set_page_config(
7
  page_title="FIT Plan AI - Milestone 1",
 
12
  st.title("πŸ’ͺ FIT Plan AI – Personalized Fitness Profile")
13
  st.markdown("---")
14
 
15
+ # Test API connection on startup (optional)
16
+ if "api_status" not in st.session_state:
17
+ with st.spinner("Checking API connection..."):
18
+ api_ok, api_message = test_api_connection()
19
+ st.session_state.api_status = api_ok
20
+ st.session_state.api_message = api_message
21
+
22
+ # Show API status in sidebar
23
+ with st.sidebar:
24
+ st.header("πŸ”§ System Status")
25
+ if st.session_state.get("api_status", False):
26
+ st.success("βœ… API Connected")
27
+ else:
28
+ st.error(f"❌ API Error: {st.session_state.get('api_message', 'Unknown error')}")
29
+ st.info("Please set your HF_TOKEN environment variable")
30
+
31
  # Initialize session state
32
  if "form_submitted" not in st.session_state:
33
  st.session_state.form_submitted = False
34
  if "workout_plan" not in st.session_state:
35
  st.session_state.workout_plan = None
36
+ if "active_tab" not in st.session_state:
37
+ st.session_state.active_tab = "Profile"
38
 
39
+ # Create tabs for different sections
40
+ tab1, tab2 = st.tabs(["πŸ“‹ Profile Setup", "πŸ‹οΈ Workout Plan"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ # Tab 1: Profile Setup
43
+ with tab1:
44
+ with st.form("fitness_profile_form"):
45
+ st.header("Your Fitness Profile")
46
+ st.subheader("πŸ‘€ Personal Information")
 
 
47
 
 
 
 
 
48
  col1, col2 = st.columns(2)
49
+
50
  with col1:
51
+ name = st.text_input("Full Name *")
52
+ height = st.number_input("Height (cm) *", min_value=1.0, max_value=300.0, value=170.0)
53
+
 
 
 
 
 
54
  with col2:
55
+ age = st.number_input("Age *", min_value=10, max_value=120, value=25)
56
+ weight = st.number_input("Weight (kg) *", min_value=1.0, max_value=500.0, value=70.0)
57
+
58
+ gender = st.selectbox("Gender", ["Male", "Female", "Other"])
59
+
60
+ st.subheader("🎯 Fitness Details")
61
+
62
+ goal = st.selectbox(
63
+ "Fitness Goal *",
64
+ ["Weight Loss", "Build Muscle", "Strength Gain", "Abs Building", "Flexibility"]
65
+ )
66
+
67
+ equipment = st.multiselect(
68
+ "Available Equipment *",
69
+ [
70
+ "Dumbbells",
71
+ "Resistance Bands",
72
+ "Barbell",
73
+ "Pull-up Bar",
74
+ "Treadmill",
75
+ "Kettlebells",
76
+ "Jump Rope",
77
+ "Yoga Mat",
78
+ "No Equipment (Bodyweight only)"
79
+ ],
80
+ default=["No Equipment (Bodyweight only)"]
81
+ )
82
+
83
+ fitness_level = st.select_slider(
84
+ "Fitness Level *",
85
+ options=["Beginner", "Intermediate", "Advanced"],
86
+ value="Beginner"
87
+ )
88
+
89
+ st.markdown("---")
90
+ submit = st.form_submit_button("Save Profile", use_container_width=True)
91
+
92
+ if submit:
93
+ if not name:
94
+ st.error("Please enter your name.")
95
+ st.stop()
96
+
97
+ if not equipment:
98
+ st.error("Please select at least one equipment option.")
99
+ st.stop()
100
+
101
+ # Build prompt using the imported function
102
+ prompt, bmi, bmi_status = build_prompt(
103
+ name=name,
104
+ age=age,
105
+ gender=gender,
106
+ height=height,
107
+ weight=weight,
108
+ goal=goal,
109
+ fitness_level=fitness_level,
110
+ equipment=equipment
111
+ )
112
+
113
+ st.success("βœ… Profile Saved Successfully!")
114
+
115
+ st.session_state.update({
116
+ "form_submitted": True,
117
+ "name": name,
118
+ "bmi": bmi,
119
+ "bmi_status": bmi_status,
120
+ "age": age,
121
+ "goal": goal,
122
+ "equipment": equipment,
123
+ "fitness_level": fitness_level,
124
+ "height": height,
125
+ "weight": weight,
126
+ "gender": gender,
127
+ "prompt": prompt
128
+ })
129
+
130
+ # Show profile summary if form is submitted
131
+ if st.session_state.form_submitted:
132
+ st.markdown("---")
133
+ st.success(f"Welcome, **{st.session_state.name}**!")
134
+
135
+ col1, col2, col3 = st.columns(3)
136
+ col1.metric("πŸ“Š BMI", f"{st.session_state.bmi:.2f}")
137
+ col2.metric("🏷 Category", st.session_state.bmi_status)
138
+ col3.metric("πŸ‹οΈ Level", st.session_state.fitness_level)
139
+
140
+ # Quick action button to switch to workout plan tab
141
+ if st.button("πŸ‘‰ Go to Workout Plan Tab", type="primary", use_container_width=True):
142
+ st.session_state.active_tab = "Workout Plan"
143
+ st.rerun()
144
+
145
+ # Profile Report Section
146
+ st.markdown("---")
147
+ with st.expander("πŸ“„ View Profile Report"):
148
+ report_text = f"""
149
  FIT PLAN AI - PROFILE REPORT
150
  Generated on: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
151
 
 
162
  Level: {st.session_state.fitness_level}
163
  Equipment: {', '.join(st.session_state.equipment)}
164
 
165
+ Go to the Workout Plan tab to generate your personalized 5-day workout plan!
166
  """
167
 
168
+ st.download_button(
169
+ "πŸ“₯ Download Profile Report",
170
+ data=report_text,
171
+ file_name=f"FITPlanAI_{st.session_state.name}_Profile.txt",
172
+ mime="text/plain",
173
+ use_container_width=True
174
+ )
175
 
176
+ # Tab 2: Workout Plan
177
+ with tab2:
178
+ st.header("πŸ‹οΈ Your Personalized Workout Plan")
179
+
180
+ # Check if profile is submitted
181
+ if not st.session_state.form_submitted:
182
+ st.warning("⚠️ Please set up your profile first in the 'Profile Setup' tab!")
183
+ if st.button("Go to Profile Setup"):
184
+ st.session_state.active_tab = "Profile"
185
+ st.rerun()
186
+ else:
187
+ # Check API status
188
+ if not st.session_state.get("api_status", False):
189
+ st.error("⚠️ API is not connected. Please check your HF_TOKEN environment variable.")
190
+ st.stop()
191
+
192
+ # Show profile summary
193
+ with st.container():
194
+ st.markdown("### Profile Summary")
195
+ col1, col2, col3, col4 = st.columns(4)
196
+ col1.metric("Name", st.session_state.name)
197
+ col2.metric("Age", st.session_state.age)
198
+ col3.metric("BMI", f"{st.session_state.bmi:.1f}")
199
+ col4.metric("Goal", st.session_state.goal)
200
+
201
+ st.markdown("---")
202
+
203
+ # Generate Workout Plan Button
204
+ st.subheader("Generate Your 5-Day Workout Plan")
205
+
206
+ col1, col2, col3 = st.columns([1, 2, 1])
207
+ with col2:
208
+ if st.button("πŸš€ Generate Workout Plan", type="primary", use_container_width=True):
209
+ with st.spinner("Creating your personalized workout plan... This may take a moment."):
210
+ # Call the model API from model_api.py
211
+ workout_plan = query_model(st.session_state.prompt)
212
+ st.session_state.workout_plan = workout_plan
213
+
214
+ # Display workout plan if generated
215
+ if st.session_state.workout_plan:
216
+ st.markdown("---")
217
+ st.subheader("πŸ“‹ Your 5-Day Workout Plan")
218
+
219
+ # Check if plan is complete
220
+ is_complete, message = verify_workout_plan(st.session_state.workout_plan)
221
+ if not is_complete:
222
+ st.warning(f"⚠️ {message}. You can regenerate the plan if needed.")
223
+
224
+ # Display the workout plan
225
+ with st.container():
226
+ st.markdown(st.session_state.workout_plan)
227
+
228
+ st.markdown("---")
229
+
230
+ # Action buttons
231
+ col1, col2, col3 = st.columns(3)
232
+
233
+ with col1:
234
+ # Download button for workout plan
235
+ workout_text = f"""
236
+ FIT PLAN AI - PERSONALIZED WORKOUT PLAN
237
+ Generated for: {st.session_state.name}
238
+ Date: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
239
+
240
+ PROFILE SUMMARY:
241
+ - Age: {st.session_state.age}
242
+ - BMI: {st.session_state.bmi:.2f} ({st.session_state.bmi_status})
243
+ - Goal: {st.session_state.goal}
244
+ - Level: {st.session_state.fitness_level}
245
+ - Equipment: {', '.join(st.session_state.equipment)}
246
+
247
+ {st.session_state.workout_plan}
248
+
249
+ ---
250
+ Stay consistent and trust the process!
251
+ Generated by FIT Plan AI
252
+ """
253
+
254
+ st.download_button(
255
+ "πŸ“₯ Download Plan",
256
+ data=workout_text,
257
+ file_name=f"FITPlanAI_{st.session_state.name}_Workout.txt",
258
+ mime="text/plain",
259
+ use_container_width=True
260
+ )
261
+
262
+ with col2:
263
+ if st.button("πŸ”„ Regenerate Plan", use_container_width=True):
264
+ with st.spinner("Regenerating your workout plan..."):
265
+ workout_plan = query_model(st.session_state.prompt)
266
+ st.session_state.workout_plan = workout_plan
267
+ st.rerun()
268
+
269
+ with col3:
270
+ if st.button("✏️ Edit Profile", use_container_width=True):
271
+ st.session_state.active_tab = "Profile"
272
+ st.rerun()
273
+
274
+ # Tips section
275
+ with st.expander("πŸ’‘ Workout Tips & Guidelines"):
276
+ st.markdown("""
277
+ ### πŸ“Œ Tips for Best Results:
278
+ 1. **Warm-up** before each workout (5-10 minutes of light cardio and dynamic stretches)
279
+ 2. **Stay hydrated** during your workout
280
+ 3. **Maintain proper form** over lifting heavy weights
281
+ 4. **Rest adequately** between sets as specified
282
+ 5. **Cool down** and stretch after each session
283
+ 6. **Be consistent** - follow the plan regularly
284
+ 7. **Listen to your body** and adjust intensity if needed
285
+
286
+ ### ⚠️ Safety First:
287
+ - Consult with a healthcare professional before starting any new exercise program
288
+ - Stop immediately if you feel sharp pain or discomfort
289
+ - Start with lighter weights to master the form
290
+ """)
291
+
292
+ # Footer
293
  st.markdown("---")
294
+ st.caption("FIT Plan AI - Milestone 1 | Powered by Mistral-7B")
295
+
296
+ # Helper function to verify workout plan
297
+ def verify_workout_plan(plan_text):
298
+ """Check if the workout plan contains all 5 days"""
299
+ if not plan_text or plan_text.startswith("Error"):
300
+ return False, "No valid plan generated"
301
+
302
+ days_present = []
303
+ for i in range(1, 6):
304
+ if f"Day {i}" in plan_text:
305
+ days_present.append(i)
306
+
307
+ if len(days_present) == 5:
308
+ return True, "Complete 5-day plan"
309
+ else:
310
+ missing_days = set(range(1,6)) - set(days_present)
311
+ return False, f"Missing day(s): {', '.join(map(str, missing_days))}"