Interview_Bot / app.py
Imsachinsingh00's picture
Update app.py
07a35df verified
import os
import json
import streamlit as st
from huggingface_hub import InferenceClient
from dotenv import load_dotenv
import traceback
# Load environment variables
load_dotenv()
hf_token = os.getenv("HUGGINGFACEHUB_API_TOKEN")
# Setup Streamlit
st.set_page_config(page_title="Interview Prep Bot", page_icon="🧠", layout="centered")
st.title("πŸŽ“ Interview Preparation Chatbot")
# Token check
if not hf_token:
st.error("Token not found. Check your .env file.")
st.stop()
model_id = "mistralai/Mixtral-8x7B-Instruct-v0.1"
try:
client = InferenceClient(model=model_id, token=hf_token)
st.success("πŸ”— Connected to Hugging Face Inference API.")
except Exception as e:
st.error(f"Failed to initialize InferenceClient: {e}")
st.stop()
# Debug reset button (useful once to fix corrupted state)
if st.button("πŸ”„ Reset App"):
for key in list(st.session_state.keys()):
del st.session_state[key]
st.rerun()
# Sidebar topic & stats
topics = [
"Machine Learning",
"Data Structures",
"Python",
"Generative AI",
"Computer Vision",
"Deep Learning"
]
st.sidebar.header("πŸ” Select Topic")
topic = st.sidebar.selectbox("Topic:", topics)
# Safely initialize session state
if "questions" not in st.session_state or not isinstance(st.session_state.questions, list):
st.session_state.questions = []
if "score" not in st.session_state or not isinstance(st.session_state.score, int):
st.session_state.score = 0
if "correct_count" not in st.session_state or not isinstance(st.session_state.correct_count, int):
st.session_state.correct_count = 0
if "incorrect_count" not in st.session_state or not isinstance(st.session_state.incorrect_count, int):
st.session_state.incorrect_count = 0
if "active_question" not in st.session_state:
st.session_state.active_question = None
if "last_action" not in st.session_state:
st.session_state.last_action = ""
st.sidebar.markdown("---")
st.sidebar.header("πŸ“Š Your Score")
st.sidebar.markdown(f"**Questions:** {len(st.session_state.questions)}")
st.sidebar.markdown(f"**Correct:** {st.session_state.correct_count}")
st.sidebar.markdown(f"**Incorrect:** {st.session_state.incorrect_count}")
st.sidebar.markdown(f"**Points:** {st.session_state.score}")
# Fetch unique MCQ
def fetch_mcq(topic, past_questions=None, max_retries=3):
if past_questions is None:
past_questions = set(q["question"] for q in st.session_state.questions)
prompt_template = (
f"Generate a multiple-choice question about {topic}. "
"Return only JSON with keys: question (string), options (4 strings), correct_index (0-based integer). "
"Make the question unique and different from this list:\n" +
json.dumps(list(past_questions))
)
for _ in range(max_retries):
try:
response = client.chat_completion(
model=model_id,
messages=[
{"role": "system", "content": "You are a helpful MCQ bot that returns JSON only."},
{"role": "user", "content": prompt_template}
]
)
content = response.choices[0].message.get("content", "").strip()
data = json.loads(content)
new_question = data.get("question", "").strip()
if new_question in past_questions:
continue
return {
"question": new_question,
"options": data["options"],
"correct_index": data["correct_index"],
"selected": None,
"submitted": False
}
except Exception as e:
st.error("❌ Error fetching MCQ")
st.text(traceback.format_exc())
return None
st.warning("⚠️ Couldn't generate a unique question after several tries.")
return None
# Handle logic based on last action
if st.session_state.last_action == "submit":
new_q = fetch_mcq(topic)
if new_q:
st.session_state.active_question = new_q
st.session_state.last_action = ""
# Render active question or show start button
q = st.session_state.active_question
if not q:
if st.button("🧠 Start Interview"):
new_q = fetch_mcq(topic)
if new_q:
st.session_state.active_question = new_q
else:
st.markdown(f"### ❓ {q['question']}")
choice = st.radio(
"Choose your answer:",
range(4),
format_func=lambda i: q["options"][i],
index=q.get("selected", 0),
key="answer",
disabled=q["submitted"]
)
st.session_state.active_question["selected"] = choice
if not q["submitted"]:
if st.button("βœ… Submit Answer"):
q["submitted"] = True
if choice == q["correct_index"]:
st.success("βœ… Correct! +10 points")
st.session_state.score += 10
st.session_state.correct_count += 1
else:
correct_ans = q["options"][q["correct_index"]]
st.error(f"❌ Incorrect. Correct answer: {correct_ans} (-10 points)")
st.session_state.score -= 10
st.session_state.incorrect_count += 1
st.session_state.questions.append(q)
st.session_state.last_action = "submit"
st.rerun() # <== Force rerun after submission