Imsachinsingh00 commited on
Commit
07a35df
Β·
verified Β·
1 Parent(s): 43d2378

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -104
app.py CHANGED
@@ -7,129 +7,153 @@ import traceback
7
 
8
  # Load environment variables
9
  load_dotenv()
10
-
11
  hf_token = os.getenv("HUGGINGFACEHUB_API_TOKEN")
12
- client = InferenceClient(provider="auto", api_key=hf_token)
13
-
14
- # Streamlit configuration
15
- st.set_page_config(
16
- page_title="Interview Prep Bot",
17
- page_icon="🧠",
18
- layout="centered"
19
- )
20
  st.title("πŸŽ“ Interview Preparation Chatbot")
21
 
22
- # Initialize session state
23
- if "questions" not in st.session_state:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  st.session_state.questions = []
25
- if "topic" not in st.session_state:
26
- st.session_state.topic = "Machine Learning"
27
- if "score" not in st.session_state:
28
  st.session_state.score = 0
29
- if "correct_count" not in st.session_state:
 
30
  st.session_state.correct_count = 0
31
- if "incorrect_count" not in st.session_state:
 
32
  st.session_state.incorrect_count = 0
33
 
34
- # Sidebar: Topic selection and scoring
35
- st.sidebar.header("Practice Topic")
36
- st.session_state.topic = st.sidebar.selectbox(
37
- "Select a topic:",
38
- ["Machine Learning", "Data Structures", "Python", "Generative AI", "Computer Vision", "Deep Learning"],
39
- index=["Machine Learning", "Data Structures", "Python", "Generative AI", "Computer Vision", "Deep Learning"].index(st.session_state.topic)
40
- )
41
  st.sidebar.markdown("---")
42
- st.sidebar.header("Your Score")
43
- st.sidebar.markdown(f"**Total:** {len(st.session_state.questions)}")
44
  st.sidebar.markdown(f"**Correct:** {st.session_state.correct_count}")
45
  st.sidebar.markdown(f"**Incorrect:** {st.session_state.incorrect_count}")
46
  st.sidebar.markdown(f"**Points:** {st.session_state.score}")
47
 
48
- # Function to fetch an MCQ question with enhanced debug logging
49
-
50
- def fetch_question(topic):
51
- prompt = {
52
- "role": "system",
53
- "content": (
54
- f"You are an expert interviewer. Generate a multiple-choice question on the topic of {topic}. "
55
- "Respond ONLY with a valid JSON object: {\"question\": str, \"options\": [str,...], \"correct_index\": int}."
56
- )
57
- }
58
- try:
59
- response = client.chat.completions.create(
60
- model="mistralai/Mistral-7B-Instruct-v0.1",
61
- messages=[prompt]
62
- )
63
- # Debug: show full response for tracing
64
- st.write("**[DEBUG] Full response object:**")
65
- st.json(response.to_dict())
66
- content = response.choices[0].message.get("content", "").strip()
67
- st.write("**[DEBUG] Raw content:**")
68
- st.code(content)
69
- except Exception as e:
70
- st.error(f"Error during API call: {e}")
71
- st.text(traceback.format_exc())
72
- return None
73
- # Attempt JSON parsing
74
- try:
75
- data = json.loads(content)
76
- except json.JSONDecodeError as jde:
77
- st.error(f"JSON decode error: {jde}")
78
- st.write("**[DEBUG] Content that failed JSON parsing:**")
79
- st.code(content)
80
- return None
81
- except Exception as e:
82
- st.error(f"Unexpected parsing error: {e}")
83
- st.text(traceback.format_exc())
84
- return None
85
- # Validate structure
86
- question = data.get("question")
87
- options = data.get("options")
88
- correct_index = data.get("correct_index")
89
- if not question or not isinstance(options, list) or not isinstance(correct_index, int):
90
- st.error("Invalid question structure: missing keys or wrong types.")
91
- st.write("**[DEBUG] Parsed JSON:**")
92
- st.json(data)
93
- return None
94
- return {"question": question, "options": options, "correct_index": correct_index}
95
-
96
- # Buttons to get or advance questions
97
- if not st.session_state.questions:
98
- if st.button("Get Question"):
99
- q = fetch_question(st.session_state.topic)
100
- if q:
101
- st.session_state.questions.append({**q, "selected": None, "submitted": False})
 
 
 
 
 
102
  else:
103
- if st.button("Next Question"):
104
- q = fetch_question(st.session_state.topic)
105
- if q:
106
- st.session_state.questions.append({**q, "selected": None, "submitted": False})
107
-
108
- # Display questions and capture answers
109
- for idx, q in enumerate(st.session_state.questions):
110
- st.markdown(f"### Question {idx+1}")
111
- st.write(q["question"])
112
- opts = q["options"]
113
- sel = st.radio(
114
- "Choose an answer:",
115
- options=list(range(len(opts))),
116
- format_func=lambda i: opts[i],
117
- index=q["selected"] if q["selected"] is not None else 0,
118
- key=f"radio_{idx}",
119
  disabled=q["submitted"]
120
  )
121
- st.session_state.questions[idx]["selected"] = sel
 
122
  if not q["submitted"]:
123
- if st.button("Submit Answer", key=f"submit_{idx}"):
124
- st.session_state.questions[idx]["submitted"] = True
125
- if sel == q["correct_index"]:
126
- st.success("Correct! +10 points")
127
  st.session_state.score += 10
128
  st.session_state.correct_count += 1
129
  else:
130
- st.error(f"Incorrect! Correct: {opts[q['correct_index']]} (-10 points)")
 
131
  st.session_state.score -= 10
132
  st.session_state.incorrect_count += 1
133
- # Footer
134
- st.markdown("---")
135
- st.markdown("*Correct: +10 pts | Incorrect: -10 pts*")
 
 
7
 
8
  # Load environment variables
9
  load_dotenv()
 
10
  hf_token = os.getenv("HUGGINGFACEHUB_API_TOKEN")
11
+
12
+ # Setup Streamlit
13
+ st.set_page_config(page_title="Interview Prep Bot", page_icon="🧠", layout="centered")
 
 
 
 
 
14
  st.title("πŸŽ“ Interview Preparation Chatbot")
15
 
16
+ # Token check
17
+ if not hf_token:
18
+ st.error("Token not found. Check your .env file.")
19
+ st.stop()
20
+
21
+ model_id = "mistralai/Mixtral-8x7B-Instruct-v0.1"
22
+ try:
23
+ client = InferenceClient(model=model_id, token=hf_token)
24
+ st.success("πŸ”— Connected to Hugging Face Inference API.")
25
+ except Exception as e:
26
+ st.error(f"Failed to initialize InferenceClient: {e}")
27
+ st.stop()
28
+
29
+ # Debug reset button (useful once to fix corrupted state)
30
+ if st.button("πŸ”„ Reset App"):
31
+ for key in list(st.session_state.keys()):
32
+ del st.session_state[key]
33
+ st.rerun()
34
+
35
+ # Sidebar topic & stats
36
+ topics = [
37
+ "Machine Learning",
38
+ "Data Structures",
39
+ "Python",
40
+ "Generative AI",
41
+ "Computer Vision",
42
+ "Deep Learning"
43
+ ]
44
+ st.sidebar.header("πŸ” Select Topic")
45
+ topic = st.sidebar.selectbox("Topic:", topics)
46
+
47
+ # Safely initialize session state
48
+ if "questions" not in st.session_state or not isinstance(st.session_state.questions, list):
49
  st.session_state.questions = []
50
+
51
+ if "score" not in st.session_state or not isinstance(st.session_state.score, int):
 
52
  st.session_state.score = 0
53
+
54
+ if "correct_count" not in st.session_state or not isinstance(st.session_state.correct_count, int):
55
  st.session_state.correct_count = 0
56
+
57
+ if "incorrect_count" not in st.session_state or not isinstance(st.session_state.incorrect_count, int):
58
  st.session_state.incorrect_count = 0
59
 
60
+ if "active_question" not in st.session_state:
61
+ st.session_state.active_question = None
62
+
63
+ if "last_action" not in st.session_state:
64
+ st.session_state.last_action = ""
65
+
 
66
  st.sidebar.markdown("---")
67
+ st.sidebar.header("πŸ“Š Your Score")
68
+ st.sidebar.markdown(f"**Questions:** {len(st.session_state.questions)}")
69
  st.sidebar.markdown(f"**Correct:** {st.session_state.correct_count}")
70
  st.sidebar.markdown(f"**Incorrect:** {st.session_state.incorrect_count}")
71
  st.sidebar.markdown(f"**Points:** {st.session_state.score}")
72
 
73
+ # Fetch unique MCQ
74
+ def fetch_mcq(topic, past_questions=None, max_retries=3):
75
+ if past_questions is None:
76
+ past_questions = set(q["question"] for q in st.session_state.questions)
77
+
78
+ prompt_template = (
79
+ f"Generate a multiple-choice question about {topic}. "
80
+ "Return only JSON with keys: question (string), options (4 strings), correct_index (0-based integer). "
81
+ "Make the question unique and different from this list:\n" +
82
+ json.dumps(list(past_questions))
83
+ )
84
+
85
+ for _ in range(max_retries):
86
+ try:
87
+ response = client.chat_completion(
88
+ model=model_id,
89
+ messages=[
90
+ {"role": "system", "content": "You are a helpful MCQ bot that returns JSON only."},
91
+ {"role": "user", "content": prompt_template}
92
+ ]
93
+ )
94
+ content = response.choices[0].message.get("content", "").strip()
95
+ data = json.loads(content)
96
+
97
+ new_question = data.get("question", "").strip()
98
+ if new_question in past_questions:
99
+ continue
100
+
101
+ return {
102
+ "question": new_question,
103
+ "options": data["options"],
104
+ "correct_index": data["correct_index"],
105
+ "selected": None,
106
+ "submitted": False
107
+ }
108
+
109
+ except Exception as e:
110
+ st.error("❌ Error fetching MCQ")
111
+ st.text(traceback.format_exc())
112
+ return None
113
+
114
+ st.warning("⚠️ Couldn't generate a unique question after several tries.")
115
+ return None
116
+
117
+ # Handle logic based on last action
118
+ if st.session_state.last_action == "submit":
119
+ new_q = fetch_mcq(topic)
120
+ if new_q:
121
+ st.session_state.active_question = new_q
122
+ st.session_state.last_action = ""
123
+
124
+ # Render active question or show start button
125
+ q = st.session_state.active_question
126
+
127
+ if not q:
128
+ if st.button("🧠 Start Interview"):
129
+ new_q = fetch_mcq(topic)
130
+ if new_q:
131
+ st.session_state.active_question = new_q
132
  else:
133
+ st.markdown(f"### ❓ {q['question']}")
134
+ choice = st.radio(
135
+ "Choose your answer:",
136
+ range(4),
137
+ format_func=lambda i: q["options"][i],
138
+ index=q.get("selected", 0),
139
+ key="answer",
 
 
 
 
 
 
 
 
 
140
  disabled=q["submitted"]
141
  )
142
+ st.session_state.active_question["selected"] = choice
143
+
144
  if not q["submitted"]:
145
+ if st.button("βœ… Submit Answer"):
146
+ q["submitted"] = True
147
+ if choice == q["correct_index"]:
148
+ st.success("βœ… Correct! +10 points")
149
  st.session_state.score += 10
150
  st.session_state.correct_count += 1
151
  else:
152
+ correct_ans = q["options"][q["correct_index"]]
153
+ st.error(f"❌ Incorrect. Correct answer: {correct_ans} (-10 points)")
154
  st.session_state.score -= 10
155
  st.session_state.incorrect_count += 1
156
+
157
+ st.session_state.questions.append(q)
158
+ st.session_state.last_action = "submit"
159
+ st.rerun() # <== Force rerun after submission