Skip to content

Commit 5b9bb16

Browse files
committed
fix: ci failure due to JWT_EXPIRATION_HOURS missing exception
1 parent 8c7c09c commit 5b9bb16

File tree

2 files changed

+14
-37
lines changed

2 files changed

+14
-37
lines changed

.github/workflows/backend-ci-cd.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,15 @@ jobs:
5151
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
5252
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
5353
JWT_SECRET_KEY: ${{ secrets.JWT_SECRET_KEY }}
54-
JWT_ALGORITHM: ${{ secrets.JWT_ALGORITHM || 'HS256' }}
55-
JWT_EXPIRATION_HOURS: ${{ secrets.JWT_EXPIRATION_HOURS || '24' }}
54+
JWT_ALGORITHM: ${{ secrets.JWT_ALGORITHM }}
55+
JWT_EXPIRATION_HOURS: ${{ secrets.JWT_EXPIRATION_HOURS }}
5656
EMAIL_ENABLED: "true"
5757
DATABASE_URL: data/kcet_2024.db
5858
run: |
59+
# Robustly handle empty environment variables with Bash defaults
60+
export JWT_EXPIRATION_HOURS=${JWT_EXPIRATION_HOURS:-24}
61+
export JWT_ALGORITHM=${JWT_ALGORITHM:-HS256}
62+
export JWT_SECRET_KEY=${JWT_SECRET_KEY}
5963
pytest
6064
6165
deploy:

backend/app/ai/email_tools.py

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
All emails include a "Continue the Chat" button with the session ID for seamless conversation continuation.
66
"""
77

8+
import os
89
import re
910
from datetime import datetime
1011
from typing import Any, Dict, List, Optional
@@ -13,10 +14,10 @@
1314
from app.email.service import email_service
1415
from app.email.templates_manager import template_manager
1516

16-
# Base URL for frontend
17-
FRONTEND_BASE_URL = "http://collegepathfinder.vercel.app"
17+
FRONTEND_BASE_URL = os.getenv("FRONTEND_BASE_URL")
18+
if not FRONTEND_BASE_URL:
19+
raise ValueError("FRONTEND_BASE_URL is not set")
1820

19-
# Thread-safe session context (set by execute_tool before calling email functions)
2021
_current_session: Optional[ChatSession] = None
2122

2223

@@ -38,13 +39,8 @@ def _get_chat_url(session_id: str) -> str:
3839

3940
def _extract_name_from_email(email: str) -> str:
4041
"""Extract name from email address"""
41-
# Get part before @
4242
local_part = email.split("@")[0]
43-
44-
# Remove numbers and special chars
4543
name = re.sub(r"[0-9._-]", " ", local_part)
46-
47-
# Capitalize first letter of each word
4844
name = " ".join(word.capitalize() for word in name.split() if word)
4945

5046
return name if name else "Student"
@@ -60,29 +56,24 @@ def _analyze_conversation_history(session: ChatSession) -> Dict[str, Any]:
6056
"conversation_summary": [],
6157
}
6258

63-
# Analyze messages
6459
for msg in session.messages:
6560
content = msg.content.lower()
6661

67-
# Extract rank
6862
if "rank" in content:
6963
rank_match = re.search(r"\b(\d{1,6})\b", content)
7064
if rank_match and not analysis["rank"]:
7165
analysis["rank"] = int(rank_match.group(1))
7266

73-
# Extract category
7467
categories = ["gm", "sc", "st", "2a", "2b", "3a", "3b", "obc"]
7568
for cat in categories:
7669
if cat in content:
7770
analysis["category"] = cat.upper()
7871
break
7972

80-
# Track discussion points
8173
if msg.role == "user":
82-
if len(content) > 20: # Meaningful message
74+
if len(content) > 20:
8375
analysis["conversation_summary"].append(content[:100])
8476

85-
# Limit summary to 5 points
8677
analysis["conversation_summary"] = analysis["conversation_summary"][:5]
8778

8879
return analysis
@@ -120,11 +111,9 @@ def send_comprehensive_report_email(
120111
"""
121112
from app.services import CollegeService
122113

123-
# Try to get email from session context if not provided
124114
session = _get_session_context()
125115

126116
if not email and session:
127-
# Try to extract email from session user data
128117
if hasattr(session, "user_email") and session.user_email:
129118
email = session.user_email
130119

@@ -135,19 +124,16 @@ def send_comprehensive_report_email(
135124
"message": "Please provide an email address. Say 'email me' to use your account email, or provide a specific address like 'send to friend@email.com'",
136125
}
137126

138-
# Validate email
139127
if not _validate_email(email):
140128
return {
141129
"success": False,
142130
"error": "Invalid email format",
143131
"message": "Please provide a valid email address.",
144132
}
145133

146-
# Extract name from email if not provided
147134
if not student_name:
148135
student_name = _extract_name_from_email(email)
149136

150-
# Analyze conversation history if session available in context
151137
conversation_data = {}
152138
session = _get_session_context()
153139
if session:
@@ -157,16 +143,13 @@ def send_comprehensive_report_email(
157143
if not category:
158144
category = conversation_data.get("category", "GM")
159145

160-
# Default values
161146
rank = rank or 50000
162147
category = category or "GM"
163148

164-
# Create conversation summary
165149
conversation_summary = " ".join(conversation_data.get("conversation_summary", []))
166150
if not conversation_summary:
167151
conversation_summary = f"Analysis for rank {rank} in {category} category"
168152

169-
# EXECUTE ACTUAL TOOLS TO GET REAL DATA
170153
round1_colleges = []
171154
round2_colleges = []
172155
stats = {
@@ -177,7 +160,6 @@ def send_comprehensive_report_email(
177160
}
178161

179162
try:
180-
# Get Round 1 colleges (top 15) - NOTE: CollegeService doesn't accept 'category' param
181163
print(f"[EMAIL DEBUG] Fetching Round 1 colleges for rank {rank}")
182164
try:
183165
colleges_r1_raw = CollegeService.get_colleges_by_rank(
@@ -192,7 +174,6 @@ def send_comprehensive_report_email(
192174

193175
if colleges_r1_raw and len(colleges_r1_raw) > 0:
194176
for college in colleges_r1_raw:
195-
# Calculate admission chance
196177
cutoff = college.get("cutoff_rank", rank)
197178
if rank <= cutoff:
198179
admission_chance = "High"
@@ -211,7 +192,6 @@ def send_comprehensive_report_email(
211192
else:
212193
print("[EMAIL DEBUG] No Round 1 colleges found")
213194

214-
# Get Round 2 colleges (top 15)
215195
print(f"[EMAIL DEBUG] Fetching Round 2 colleges for rank {rank}")
216196
try:
217197
colleges_r2_raw = CollegeService.get_colleges_by_rank(
@@ -226,7 +206,6 @@ def send_comprehensive_report_email(
226206

227207
if colleges_r2_raw and len(colleges_r2_raw) > 0:
228208
for college in colleges_r2_raw:
229-
# Calculate admission chance
230209
cutoff = college.get("cutoff_rank", rank)
231210
if rank <= cutoff:
232211
admission_chance = "High"
@@ -245,7 +224,6 @@ def send_comprehensive_report_email(
245224
else:
246225
print("[EMAIL DEBUG] No Round 2 colleges found")
247226

248-
# Calculate total stats
249227
stats["total_colleges"] = stats["round1_colleges"] + stats["round2_colleges"]
250228
all_branches = set()
251229
for college in round1_colleges + round2_colleges:
@@ -258,13 +236,11 @@ def send_comprehensive_report_email(
258236
)
259237

260238
except Exception as e:
261-
# Log error but continue with empty data
262239
print(f"[EMAIL ERROR] Error fetching college data: {e}")
263240
import traceback
264241

265242
traceback.print_exc()
266243

267-
# Prepare context for template
268244
context = {
269245
"student_name": student_name,
270246
"rank": rank,
@@ -336,15 +312,13 @@ def send_prediction_summary_email(
336312
Returns:
337313
Dict with success status and message
338314
"""
339-
# Validate email format
340315
if not _validate_email(email):
341316
return {
342317
"success": False,
343318
"error": "Invalid email format",
344319
"message": "Please provide a valid email address.",
345320
}
346321

347-
# Prepare context
348322
context = {
349323
"student_name": student_name,
350324
"rank": rank,
@@ -354,7 +328,7 @@ def send_prediction_summary_email(
354328
"rank_year": "2024",
355329
"analysis_date": datetime.now(),
356330
"total_colleges": len(colleges),
357-
"colleges": colleges[:10], # Top 10 for email
331+
"colleges": colleges[:30],
358332
"chat_url": _get_chat_url(session_id),
359333
}
360334

@@ -370,8 +344,8 @@ def send_prediction_summary_email(
370344
if success:
371345
return {
372346
"success": True,
373-
"message": f"Prediction summary sent to {email}! Check your inbox.",
374-
"colleges_sent": len(colleges[:10]),
347+
"message": f"Prediction summary sent to {email}! Check your inbox.",
348+
"colleges_sent": len(colleges[:30]),
375349
}
376350
else:
377351
return {
@@ -421,7 +395,6 @@ def send_detailed_analysis_email(
421395
"message": "Please provide a valid email address.",
422396
}
423397

424-
# Calculate statistics
425398
high_chance = sum(1 for c in colleges if c.get("admission_chance") == "High")
426399
branches = set(c.get("branch", "") for c in colleges)
427400

0 commit comments

Comments
 (0)