Update app.py
Browse files
app.py
CHANGED
|
@@ -5,13 +5,25 @@ import time
|
|
| 5 |
import requests
|
| 6 |
import boto3
|
| 7 |
import uuid
|
|
|
|
| 8 |
|
| 9 |
-
#
|
| 10 |
-
API_ENDPOINT = "https://oau6sljd4l.execute-api.ap-south-1.amazonaws.com/production/process"
|
| 11 |
|
| 12 |
# DynamoDB configuration for session tracking
|
| 13 |
-
DYNAMODB_REGION = "ap-south-1"
|
| 14 |
-
SESSION_TABLE = "SessionTracking"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
# Set page configuration
|
| 17 |
st.set_page_config(
|
|
@@ -97,11 +109,37 @@ st.markdown("""
|
|
| 97 |
border-color: var(--border-color);
|
| 98 |
}
|
| 99 |
|
| 100 |
-
/* Radio buttons */
|
| 101 |
.stRadio > div {
|
| 102 |
background-color: transparent;
|
| 103 |
}
|
| 104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
/* Spacing */
|
| 106 |
div.block-container {
|
| 107 |
padding-top: 2rem;
|
|
@@ -131,7 +169,9 @@ st.markdown("""
|
|
| 131 |
</style>
|
| 132 |
""", unsafe_allow_html=True)
|
| 133 |
|
| 134 |
-
# Initialize session state
|
|
|
|
|
|
|
| 135 |
if 'session_ids' not in st.session_state:
|
| 136 |
st.session_state.session_ids = []
|
| 137 |
|
|
@@ -146,17 +186,6 @@ Your personalized course will be generated based on the information you provide
|
|
| 146 |
|
| 147 |
# Main Form
|
| 148 |
with st.form("personalization_form", clear_on_submit=False):
|
| 149 |
-
# Course Information Section
|
| 150 |
-
st.markdown('<div class="section-header">π Course Information</div>', unsafe_allow_html=True)
|
| 151 |
-
|
| 152 |
-
col1, col2 = st.columns(2)
|
| 153 |
-
with col1:
|
| 154 |
-
course_id = st.number_input("Course ID", min_value=1, value=47, help="Enter the course ID")
|
| 155 |
-
user_id = st.number_input("User ID", min_value=1, value=30, help="Enter your user ID")
|
| 156 |
-
|
| 157 |
-
with col2:
|
| 158 |
-
personalization_id = st.number_input("Personalization ID", min_value=1, value=100, help="Enter personalization ID")
|
| 159 |
-
|
| 160 |
# Topics Section
|
| 161 |
st.markdown('<div class="section-header">π Topics Configuration</div>', unsafe_allow_html=True)
|
| 162 |
|
|
@@ -170,116 +199,24 @@ with st.form("personalization_form", clear_on_submit=False):
|
|
| 170 |
|
| 171 |
if topic_mode == "Single Topic":
|
| 172 |
st.subheader("Single Topic Details")
|
| 173 |
-
|
| 174 |
-
with col1:
|
| 175 |
-
single_topic_id = st.number_input("Topic ID", min_value=1, value=10834)
|
| 176 |
-
single_topic_title = st.text_input("Topic Title", value="Setting Up Flask Environment")
|
| 177 |
-
with col2:
|
| 178 |
-
single_chapter_id = st.number_input("Chapter ID", min_value=1, value=647)
|
| 179 |
-
single_chapter_title = st.text_input("Chapter Title", value="Introduction to Flask")
|
| 180 |
|
| 181 |
-
single_video_url = st.text_input(
|
| 182 |
-
"Video URL",
|
| 183 |
-
value="https://techlearn-dev.s3.ap-south-1.amazonaws.com/course_videos/47/647/1729064365.mp4"
|
| 184 |
-
)
|
| 185 |
-
col1, col2 = st.columns(2)
|
| 186 |
-
with col1:
|
| 187 |
-
single_video_duration = st.number_input("Video Duration (seconds)", min_value=1, value=462)
|
| 188 |
-
with col2:
|
| 189 |
-
single_sequence_number = st.number_input("Sequence Number", min_value=1, value=1)
|
| 190 |
-
|
| 191 |
else:
|
| 192 |
st.subheader("Multiple Topics")
|
| 193 |
-
num_topics = st.number_input("Number of Topics", min_value=1, max_value=10, value=3)
|
| 194 |
|
| 195 |
-
|
| 196 |
-
for i in
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
chapter_title = st.text_input(f"Chapter Title {i+1}", value="Introduction to Flask", key=f"chapter_title_{i}")
|
| 207 |
-
|
| 208 |
-
video_url = st.text_input(f"Video URL {i+1}",
|
| 209 |
-
value=f"https://techlearn-dev.s3.ap-south-1.amazonaws.com/course_videos/47/647/172906{4322+i*50}.mp4",
|
| 210 |
-
key=f"video_url_{i}")
|
| 211 |
-
col1, col2 = st.columns(2)
|
| 212 |
-
with col1:
|
| 213 |
-
video_duration = st.number_input(f"Video Duration {i+1} (seconds)", min_value=1, value=410+i*20, key=f"video_duration_{i}")
|
| 214 |
-
with col2:
|
| 215 |
-
sequence_number = st.number_input(f"Sequence Number {i+1}", min_value=1, value=i+1, key=f"sequence_number_{i}")
|
| 216 |
-
|
| 217 |
-
topics_data.append({
|
| 218 |
-
"topic_id": topic_id,
|
| 219 |
-
"topic_title": topic_title,
|
| 220 |
-
"chapter_id": chapter_id,
|
| 221 |
-
"chapter_title": chapter_title,
|
| 222 |
-
"video_url": video_url,
|
| 223 |
-
"video_duration": video_duration,
|
| 224 |
-
"sequence_number": sequence_number,
|
| 225 |
-
"course_id": course_id
|
| 226 |
-
})
|
| 227 |
-
|
| 228 |
-
# Personal Information Section
|
| 229 |
-
st.markdown('<div class="section-header">π€ User Profile</div>', unsafe_allow_html=True)
|
| 230 |
-
|
| 231 |
-
col1, col2 = st.columns(2)
|
| 232 |
-
with col1:
|
| 233 |
-
user_name = st.text_input("Full Name", placeholder="Enter your full name", value="John Doe")
|
| 234 |
-
user_age = st.number_input("Age", min_value=10, max_value=100, value=22)
|
| 235 |
-
user_gender = st.selectbox(
|
| 236 |
-
"Gender",
|
| 237 |
-
["male", "female", "other"],
|
| 238 |
-
index=0,
|
| 239 |
-
format_func=lambda x: x.capitalize()
|
| 240 |
-
)
|
| 241 |
-
|
| 242 |
-
with col2:
|
| 243 |
-
tech_knowledge = st.select_slider(
|
| 244 |
-
"Technical Knowledge",
|
| 245 |
-
options=["beginner", "intermediate", "advanced"],
|
| 246 |
-
value="beginner"
|
| 247 |
-
)
|
| 248 |
-
learning_style = st.radio(
|
| 249 |
-
"Learning Style",
|
| 250 |
-
["visual", "auditory", "kinesthetic"],
|
| 251 |
-
index=0,
|
| 252 |
-
horizontal=True,
|
| 253 |
-
format_func=lambda x: x.capitalize()
|
| 254 |
-
)
|
| 255 |
|
| 256 |
-
#
|
| 257 |
-
st.markdown('<div class="section-header">π― Preferences</div>', unsafe_allow_html=True)
|
| 258 |
-
col1, col2 = st.columns(2)
|
| 259 |
-
|
| 260 |
-
with col1:
|
| 261 |
-
preferred_activity = st.text_area(
|
| 262 |
-
"Preferred Activities",
|
| 263 |
-
placeholder="e.g., movies, painting, shopping",
|
| 264 |
-
value="movies, painting, shopping",
|
| 265 |
-
help="Enter activities separated by commas"
|
| 266 |
-
)
|
| 267 |
-
food = st.text_area(
|
| 268 |
-
"Food Preferences",
|
| 269 |
-
placeholder="e.g., vegetarian, paneer, pizza",
|
| 270 |
-
value="vegetarian, paneer, pizza",
|
| 271 |
-
help="Enter food items separated by commas"
|
| 272 |
-
)
|
| 273 |
-
|
| 274 |
-
with col2:
|
| 275 |
-
physical_activities = st.text_area(
|
| 276 |
-
"Physical Activities",
|
| 277 |
-
placeholder="e.g., badminton, cricket, yoga",
|
| 278 |
-
value="badminton, cricket, yoga",
|
| 279 |
-
help="Enter activities separated by commas"
|
| 280 |
-
)
|
| 281 |
-
|
| 282 |
-
# Language & Voice Settings Section
|
| 283 |
st.markdown('<div class="section-header">π£οΈ Language & Voice Settings</div>', unsafe_allow_html=True)
|
| 284 |
|
| 285 |
col1, col2, col3 = st.columns(3)
|
|
@@ -302,21 +239,15 @@ with st.form("personalization_form", clear_on_submit=False):
|
|
| 302 |
with col3:
|
| 303 |
tts_voice = st.selectbox(
|
| 304 |
"Voice Style",
|
| 305 |
-
["echo", "soprano", "alto", "robotic"
|
| 306 |
-
index=
|
| 307 |
format_func=lambda x: x.capitalize()
|
| 308 |
)
|
| 309 |
-
|
| 310 |
-
col1, col2 = st.columns(2)
|
| 311 |
-
with col1:
|
| 312 |
-
toggle_hinglish = st.toggle("Enable Hinglish", value=True, help="Mix of Hindi and English")
|
| 313 |
-
with col2:
|
| 314 |
-
run_visualization = st.toggle("Run Visualization", value=False, help="Enable visualization features")
|
| 315 |
|
| 316 |
# Technical Settings Section
|
| 317 |
st.markdown('<div class="section-header">π» Technical Settings</div>', unsafe_allow_html=True)
|
| 318 |
|
| 319 |
-
col1, col2
|
| 320 |
with col1:
|
| 321 |
programming_language = st.selectbox(
|
| 322 |
"Programming Language",
|
|
@@ -325,21 +256,7 @@ with st.form("personalization_form", clear_on_submit=False):
|
|
| 325 |
format_func=lambda x: x.capitalize()
|
| 326 |
)
|
| 327 |
with col2:
|
| 328 |
-
|
| 329 |
-
"Slide Color",
|
| 330 |
-
["blue", "red", "green", "purple", "orange"],
|
| 331 |
-
index=0,
|
| 332 |
-
format_func=lambda x: x.capitalize()
|
| 333 |
-
)
|
| 334 |
-
with col3:
|
| 335 |
-
video_type = st.selectbox(
|
| 336 |
-
"Video Type",
|
| 337 |
-
["personalised_video", "standard_video"],
|
| 338 |
-
index=0,
|
| 339 |
-
format_func=lambda x: x.replace('_', ' ').title()
|
| 340 |
-
)
|
| 341 |
-
|
| 342 |
-
subtitle = st.text_input("Subtitle", placeholder="Optional subtitle for the video", value="")
|
| 343 |
|
| 344 |
# Submit button
|
| 345 |
st.markdown("<br>", unsafe_allow_html=True)
|
|
@@ -347,36 +264,53 @@ with st.form("personalization_form", clear_on_submit=False):
|
|
| 347 |
with col2:
|
| 348 |
submitted = st.form_submit_button("Generate Personalized Course", use_container_width=True)
|
| 349 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 350 |
# Handle submission
|
| 351 |
if submitted:
|
| 352 |
# Validate inputs
|
| 353 |
-
if not
|
| 354 |
-
st.error("Please enter your name")
|
| 355 |
-
elif topic_mode == "Single Topic" and not single_topic_title:
|
| 356 |
st.error("Please enter a topic title")
|
|
|
|
|
|
|
| 357 |
else:
|
| 358 |
# Show loading state
|
| 359 |
with st.spinner("Generating your personalized course..."):
|
| 360 |
time.sleep(1.5) # Simulating API call delay
|
| 361 |
|
| 362 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 363 |
user_profile = {
|
| 364 |
"personalized": True,
|
| 365 |
-
"user_name":
|
| 366 |
-
"user_age":
|
| 367 |
-
"user_gender":
|
| 368 |
-
"user_tech_knowledge":
|
| 369 |
-
"user_preferred_activity":
|
| 370 |
-
"user_food": food,
|
| 371 |
-
"user_physical_activities":
|
| 372 |
-
"learning_style":
|
| 373 |
"target_language": target_language,
|
| 374 |
"tts_gender": tts_gender,
|
| 375 |
"tts_voice": tts_voice,
|
| 376 |
"toggle_hinglish": toggle_hinglish,
|
| 377 |
-
"run_visualization":
|
| 378 |
-
"subtitle":
|
| 379 |
-
"age_group": "18-25"
|
| 380 |
}
|
| 381 |
|
| 382 |
# Create settings
|
|
@@ -385,11 +319,11 @@ if submitted:
|
|
| 385 |
"tts_gender": tts_gender,
|
| 386 |
"tts_voice": tts_voice,
|
| 387 |
"toggle_hinglish": toggle_hinglish,
|
| 388 |
-
"run_visualization":
|
| 389 |
-
"subtitle":
|
| 390 |
"programming_language": programming_language,
|
| 391 |
-
"slide_colour":
|
| 392 |
-
"video_type":
|
| 393 |
}
|
| 394 |
|
| 395 |
# Create payload based on topic mode
|
|
@@ -399,17 +333,32 @@ if submitted:
|
|
| 399 |
"user_profile": user_profile,
|
| 400 |
"settings": settings,
|
| 401 |
"topic_data": {
|
| 402 |
-
"topic_id":
|
| 403 |
"topic_title": single_topic_title,
|
| 404 |
-
"chapter_id":
|
| 405 |
-
"chapter_title":
|
| 406 |
"course_id": course_id,
|
| 407 |
-
"video_url":
|
| 408 |
-
"video_duration":
|
| 409 |
-
"sequence_number":
|
| 410 |
}
|
| 411 |
}
|
| 412 |
else:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
payload = {
|
| 414 |
"personalization_id": personalization_id,
|
| 415 |
"user_id": user_id,
|
|
@@ -427,13 +376,13 @@ if submitted:
|
|
| 427 |
'Content-Type': 'application/json'
|
| 428 |
}
|
| 429 |
|
| 430 |
-
response = requests.post(API_ENDPOINT, json=payload, headers=headers, timeout=
|
| 431 |
|
| 432 |
if response.status_code == 200:
|
| 433 |
response_data = response.json()
|
| 434 |
session_ids = response_data.get("session_ids", [])
|
| 435 |
|
| 436 |
-
st.success(f"Course personalization started successfully
|
| 437 |
|
| 438 |
# Store session IDs in session state
|
| 439 |
st.session_state.session_ids.extend(session_ids)
|
|
@@ -441,12 +390,11 @@ if submitted:
|
|
| 441 |
# Display results in a clean format
|
| 442 |
st.markdown("### π Your personalized course generation has started!")
|
| 443 |
st.markdown(f"""
|
| 444 |
-
**User**: {user_name}
|
| 445 |
**Course ID**: {course_id}
|
| 446 |
**Programming Language**: {programming_language.capitalize()}
|
| 447 |
-
**
|
| 448 |
**Voice**: {tts_voice.capitalize()} ({tts_gender.capitalize()})
|
| 449 |
-
**Topics**: {len(
|
| 450 |
""")
|
| 451 |
|
| 452 |
# Display session IDs
|
|
@@ -496,13 +444,3 @@ if st.session_state.session_ids:
|
|
| 496 |
if st.button("Clear Session History"):
|
| 497 |
st.session_state.session_ids = []
|
| 498 |
st.rerun()
|
| 499 |
-
|
| 500 |
-
# Footer
|
| 501 |
-
st.markdown("---")
|
| 502 |
-
st.markdown(f"""
|
| 503 |
-
<div style="text-align: center; color: #888888;">
|
| 504 |
-
Β© 2025 Base Course Personalization | All Rights Reserved<br>
|
| 505 |
-
<small>API Endpoint: {API_ENDPOINT}</small><br>
|
| 506 |
-
<small>Session Tracking: {SESSION_TABLE} ({DYNAMODB_REGION})</small>
|
| 507 |
-
</div>
|
| 508 |
-
""", unsafe_allow_html=True)
|
|
|
|
| 5 |
import requests
|
| 6 |
import boto3
|
| 7 |
import uuid
|
| 8 |
+
import os
|
| 9 |
|
| 10 |
+
# Load configuration from environment variables (Hugging Face Spaces)
|
| 11 |
+
API_ENDPOINT = os.getenv("API_ENDPOINT", "https://oau6sljd4l.execute-api.ap-south-1.amazonaws.com/production/process")
|
| 12 |
|
| 13 |
# DynamoDB configuration for session tracking
|
| 14 |
+
DYNAMODB_REGION = os.getenv("DYNAMODB_REGION", "ap-south-1")
|
| 15 |
+
SESSION_TABLE = os.getenv("SESSION_TABLE", "SessionTracking")
|
| 16 |
+
|
| 17 |
+
# AWS Configuration
|
| 18 |
+
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
|
| 19 |
+
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
|
| 20 |
+
AWS_DEFAULT_REGION = os.getenv("AWS_DEFAULT_REGION", "ap-south-1")
|
| 21 |
+
|
| 22 |
+
# Default values
|
| 23 |
+
DEFAULT_COURSE_ID = int(os.getenv("DEFAULT_COURSE_ID", "47"))
|
| 24 |
+
DEFAULT_USER_ID = int(os.getenv("DEFAULT_USER_ID", "30"))
|
| 25 |
+
DEFAULT_PERSONALIZATION_ID = int(os.getenv("DEFAULT_PERSONALIZATION_ID", "100"))
|
| 26 |
+
API_TIMEOUT = int(os.getenv("API_TIMEOUT", "30"))
|
| 27 |
|
| 28 |
# Set page configuration
|
| 29 |
st.set_page_config(
|
|
|
|
| 109 |
border-color: var(--border-color);
|
| 110 |
}
|
| 111 |
|
| 112 |
+
/* Radio buttons - Fix visibility */
|
| 113 |
.stRadio > div {
|
| 114 |
background-color: transparent;
|
| 115 |
}
|
| 116 |
|
| 117 |
+
.stRadio > div > label > div {
|
| 118 |
+
color: var(--text-color) !important;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
/* Select box labels */
|
| 122 |
+
.stSelectbox > label {
|
| 123 |
+
color: var(--text-color) !important;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
/* All form labels */
|
| 127 |
+
div[data-testid="stForm"] label {
|
| 128 |
+
color: var(--text-color) !important;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
/* Radio button text */
|
| 132 |
+
.stRadio label {
|
| 133 |
+
color: var(--text-color) !important;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
/* Fix for all input labels */
|
| 137 |
+
.st-emotion-cache-1gulkj5,
|
| 138 |
+
.st-emotion-cache-1aumxhf,
|
| 139 |
+
.st-emotion-cache-16txtl3 {
|
| 140 |
+
color: var(--text-color) !important;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
/* Spacing */
|
| 144 |
div.block-container {
|
| 145 |
padding-top: 2rem;
|
|
|
|
| 169 |
</style>
|
| 170 |
""", unsafe_allow_html=True)
|
| 171 |
|
| 172 |
+
# Initialize session state for topics
|
| 173 |
+
if 'topics_list' not in st.session_state:
|
| 174 |
+
st.session_state.topics_list = [{"topic_title": "What is Flask"}]
|
| 175 |
if 'session_ids' not in st.session_state:
|
| 176 |
st.session_state.session_ids = []
|
| 177 |
|
|
|
|
| 186 |
|
| 187 |
# Main Form
|
| 188 |
with st.form("personalization_form", clear_on_submit=False):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
# Topics Section
|
| 190 |
st.markdown('<div class="section-header">π Topics Configuration</div>', unsafe_allow_html=True)
|
| 191 |
|
|
|
|
| 199 |
|
| 200 |
if topic_mode == "Single Topic":
|
| 201 |
st.subheader("Single Topic Details")
|
| 202 |
+
single_topic_title = st.text_input("Topic Title", value="What is Flask", help="Enter the topic title")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
else:
|
| 205 |
st.subheader("Multiple Topics")
|
|
|
|
| 206 |
|
| 207 |
+
# Display existing topics
|
| 208 |
+
for i, topic in enumerate(st.session_state.topics_list):
|
| 209 |
+
col1, col2 = st.columns([4, 1])
|
| 210 |
+
with col1:
|
| 211 |
+
topic_title = st.text_input(f"Topic {i+1}", value=topic["topic_title"], key=f"topic_{i}")
|
| 212 |
+
st.session_state.topics_list[i]["topic_title"] = topic_title
|
| 213 |
+
with col2:
|
| 214 |
+
if len(st.session_state.topics_list) > 1:
|
| 215 |
+
if st.button("ποΈ", key=f"remove_{i}", help="Remove topic"):
|
| 216 |
+
st.session_state.topics_list.pop(i)
|
| 217 |
+
st.rerun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
|
| 219 |
+
# Language & Voice Settings Section
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
st.markdown('<div class="section-header">π£οΈ Language & Voice Settings</div>', unsafe_allow_html=True)
|
| 221 |
|
| 222 |
col1, col2, col3 = st.columns(3)
|
|
|
|
| 239 |
with col3:
|
| 240 |
tts_voice = st.selectbox(
|
| 241 |
"Voice Style",
|
| 242 |
+
["onyx", "echo", "soprano", "alto", "robotic"],
|
| 243 |
+
index=0, # Default to "onyx"
|
| 244 |
format_func=lambda x: x.capitalize()
|
| 245 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
|
| 247 |
# Technical Settings Section
|
| 248 |
st.markdown('<div class="section-header">π» Technical Settings</div>', unsafe_allow_html=True)
|
| 249 |
|
| 250 |
+
col1, col2 = st.columns(2)
|
| 251 |
with col1:
|
| 252 |
programming_language = st.selectbox(
|
| 253 |
"Programming Language",
|
|
|
|
| 256 |
format_func=lambda x: x.capitalize()
|
| 257 |
)
|
| 258 |
with col2:
|
| 259 |
+
toggle_hinglish = st.toggle("Enable Hinglish", value=True, help="Mix of Hindi and English")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
|
| 261 |
# Submit button
|
| 262 |
st.markdown("<br>", unsafe_allow_html=True)
|
|
|
|
| 264 |
with col2:
|
| 265 |
submitted = st.form_submit_button("Generate Personalized Course", use_container_width=True)
|
| 266 |
|
| 267 |
+
# Add/Remove topic buttons outside the form (for multiple topics)
|
| 268 |
+
if topic_mode == "Multiple Topics":
|
| 269 |
+
col1, col2, col3 = st.columns([1, 1, 2])
|
| 270 |
+
with col1:
|
| 271 |
+
if st.button("β Add More Topic"):
|
| 272 |
+
st.session_state.topics_list.append({"topic_title": f"Topic {len(st.session_state.topics_list) + 1}"})
|
| 273 |
+
st.rerun()
|
| 274 |
+
with col2:
|
| 275 |
+
if st.button("π Reset Topics"):
|
| 276 |
+
st.session_state.topics_list = [{"topic_title": "What is Flask"}]
|
| 277 |
+
st.rerun()
|
| 278 |
+
|
| 279 |
# Handle submission
|
| 280 |
if submitted:
|
| 281 |
# Validate inputs
|
| 282 |
+
if topic_mode == "Single Topic" and not single_topic_title:
|
|
|
|
|
|
|
| 283 |
st.error("Please enter a topic title")
|
| 284 |
+
elif topic_mode == "Multiple Topics" and not any(topic["topic_title"] for topic in st.session_state.topics_list):
|
| 285 |
+
st.error("Please enter at least one topic title")
|
| 286 |
else:
|
| 287 |
# Show loading state
|
| 288 |
with st.spinner("Generating your personalized course..."):
|
| 289 |
time.sleep(1.5) # Simulating API call delay
|
| 290 |
|
| 291 |
+
# Hardcoded values
|
| 292 |
+
course_id = DEFAULT_COURSE_ID
|
| 293 |
+
user_id = DEFAULT_USER_ID
|
| 294 |
+
personalization_id = DEFAULT_PERSONALIZATION_ID
|
| 295 |
+
|
| 296 |
+
# Create user profile (hardcoded)
|
| 297 |
user_profile = {
|
| 298 |
"personalized": True,
|
| 299 |
+
"user_name": "System User",
|
| 300 |
+
"user_age": 25,
|
| 301 |
+
"user_gender": "male",
|
| 302 |
+
"user_tech_knowledge": "beginner",
|
| 303 |
+
"user_preferred_activity": "coding, learning, technology",
|
| 304 |
+
"user_food": "healthy food, vegetarian",
|
| 305 |
+
"user_physical_activities": "walking, yoga",
|
| 306 |
+
"learning_style": "visual",
|
| 307 |
"target_language": target_language,
|
| 308 |
"tts_gender": tts_gender,
|
| 309 |
"tts_voice": tts_voice,
|
| 310 |
"toggle_hinglish": toggle_hinglish,
|
| 311 |
+
"run_visualization": False,
|
| 312 |
+
"subtitle": "",
|
| 313 |
+
"age_group": "18-25"
|
| 314 |
}
|
| 315 |
|
| 316 |
# Create settings
|
|
|
|
| 319 |
"tts_gender": tts_gender,
|
| 320 |
"tts_voice": tts_voice,
|
| 321 |
"toggle_hinglish": toggle_hinglish,
|
| 322 |
+
"run_visualization": False,
|
| 323 |
+
"subtitle": "",
|
| 324 |
"programming_language": programming_language,
|
| 325 |
+
"slide_colour": "blue",
|
| 326 |
+
"video_type": "base_video"
|
| 327 |
}
|
| 328 |
|
| 329 |
# Create payload based on topic mode
|
|
|
|
| 333 |
"user_profile": user_profile,
|
| 334 |
"settings": settings,
|
| 335 |
"topic_data": {
|
| 336 |
+
"topic_id": 10834, # Hardcoded
|
| 337 |
"topic_title": single_topic_title,
|
| 338 |
+
"chapter_id": 647, # Hardcoded
|
| 339 |
+
"chapter_title": "Introduction to Flask", # Hardcoded
|
| 340 |
"course_id": course_id,
|
| 341 |
+
"video_url": "https://techlearn-dev.s3.ap-south-1.amazonaws.com/course_videos/47/647/1729064365.mp4", # Hardcoded
|
| 342 |
+
"video_duration": 462, # Hardcoded
|
| 343 |
+
"sequence_number": 1 # Hardcoded
|
| 344 |
}
|
| 345 |
}
|
| 346 |
else:
|
| 347 |
+
# Generate topics data with hardcoded values
|
| 348 |
+
topics_data = []
|
| 349 |
+
for i, topic in enumerate(st.session_state.topics_list):
|
| 350 |
+
if topic["topic_title"]: # Only include non-empty topics
|
| 351 |
+
topics_data.append({
|
| 352 |
+
"topic_id": 10834 + i, # Hardcoded with increment
|
| 353 |
+
"topic_title": topic["topic_title"],
|
| 354 |
+
"chapter_id": 647, # Hardcoded
|
| 355 |
+
"chapter_title": "Introduction to Flask", # Hardcoded
|
| 356 |
+
"course_id": course_id,
|
| 357 |
+
"video_url": f"https://techlearn-dev.s3.ap-south-1.amazonaws.com/course_videos/47/647/172906{4365+i*50}.mp4", # Hardcoded with variation
|
| 358 |
+
"video_duration": 462 + i*20, # Hardcoded with variation
|
| 359 |
+
"sequence_number": i + 1,
|
| 360 |
+
})
|
| 361 |
+
|
| 362 |
payload = {
|
| 363 |
"personalization_id": personalization_id,
|
| 364 |
"user_id": user_id,
|
|
|
|
| 376 |
'Content-Type': 'application/json'
|
| 377 |
}
|
| 378 |
|
| 379 |
+
response = requests.post(API_ENDPOINT, json=payload, headers=headers, timeout=API_TIMEOUT)
|
| 380 |
|
| 381 |
if response.status_code == 200:
|
| 382 |
response_data = response.json()
|
| 383 |
session_ids = response_data.get("session_ids", [])
|
| 384 |
|
| 385 |
+
st.success(f"Course personalization started successfully!")
|
| 386 |
|
| 387 |
# Store session IDs in session state
|
| 388 |
st.session_state.session_ids.extend(session_ids)
|
|
|
|
| 390 |
# Display results in a clean format
|
| 391 |
st.markdown("### π Your personalized course generation has started!")
|
| 392 |
st.markdown(f"""
|
|
|
|
| 393 |
**Course ID**: {course_id}
|
| 394 |
**Programming Language**: {programming_language.capitalize()}
|
| 395 |
+
**Target Language**: {target_language.capitalize()}
|
| 396 |
**Voice**: {tts_voice.capitalize()} ({tts_gender.capitalize()})
|
| 397 |
+
**Topics**: {len(st.session_state.topics_list) if topic_mode == "Multiple Topics" else 1}
|
| 398 |
""")
|
| 399 |
|
| 400 |
# Display session IDs
|
|
|
|
| 444 |
if st.button("Clear Session History"):
|
| 445 |
st.session_state.session_ids = []
|
| 446 |
st.rerun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|