n0v33n
Updated app.py and gradioapp.py
ddbcbee
import json
import os
import re
import pandas as pd
import random
from dotenv import load_dotenv
from langchain_tavily import TavilySearch
import google.generativeai as genai
import gradio as gr
load_dotenv()
TAVILY_API_KEY = os.getenv("TAVILY_API_KEY")
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
# User sessions for mock interviews
# user_sessions = {}
genai.configure(api_key=GOOGLE_API_KEY)
# Load LeetCode data
OUTPUT_FILE = "Interview-QA-Practice-Bot/leetcode_downloaded.xlsx"
LEETCODE_DATA = pd.read_excel(OUTPUT_FILE)
print(f"Loaded {len(LEETCODE_DATA)} LeetCode problems from local file.")
# β€”β€”β€” Tool 1: Get Daily Coding Question β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
def get_daily_coding_question(query=""):
"""Get 3 random coding questions (one from each difficulty level)"""
response = "Here are your coding challenges for today:\n\n"
problem_match = re.search(r'problem[\s_]*(\d+)', query, re.IGNORECASE)
if problem_match:
problem_no = int(problem_match.group(1))
specific_problem = LEETCODE_DATA[LEETCODE_DATA['problem_no'] == problem_no]
if not specific_problem.empty:
p = specific_problem.iloc[0]
response = f"**Problem {p['problem_no']}: {p['problem_statement']}**\n"
response += f"**Difficulty**: {p['problem_level']}\n"
response += f"**Link**: {p['problem_link']}\n\n"
response += "Good luck with this problem!"
return {"status": "success", "response": response}
else:
return {"status": "error", "response": "Problem not found. Try a different number!"}
easy = LEETCODE_DATA[LEETCODE_DATA['problem_level'] == 'Easy']
medium = LEETCODE_DATA[LEETCODE_DATA['problem_level'] == 'Medium']
hard = LEETCODE_DATA[LEETCODE_DATA['problem_level'] == 'Hard']
for label, df in [("🟒 Easy", easy), ("🟑 Medium", medium), ("πŸ”΄ Hard", hard)]:
if not df.empty:
q = df.sample(1).iloc[0]
response += f"**{label} Challenge**\n"
response += f"Problem {q['problem_no']}: {q['problem_statement']}\n"
response += f"Link: {q['problem_link']}\n\n"
response += "Choose one that matches your skill level and start coding!"
return {"status": "success", "response": response}
# β€”β€”β€” Tool 2: Fetch Interview Questions β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
def fetch_interview_questions(query):
if not TAVILY_API_KEY:
return {"status": "error", "response": "Tavily API key not configured."}
tavily = TavilySearch(api_key=TAVILY_API_KEY, max_results=3)
search_response = tavily.invoke(f"{query} interview questions")
# Extract the results list from the response dictionary
results = search_response.get("results", []) if isinstance(search_response, dict) else search_response
if not results:
return {"status": "success", "response": f"No results found for '{query}' interview questions."}
search_results = f"Here are the top 3 resources for {query} interview questions:\n\n"
for i, res in enumerate(results[:3], 1):
t = res.get('title', 'No title')
u = res.get('url', 'No URL')
c = res.get('content', '')
snippet = c[:200] + '...' if len(c) > 200 else c
search_results += f"**{i}. {t}**\nURL: {u}\nPreview: {snippet}\n\n"
model = genai.GenerativeModel('gemini-1.5-flash')
guidance = model.generate_content(f"""
Based on the topic '{query}', provide practical advice on how to prepare for and tackle interview questions in this area.
Include:
1. Key concepts to focus on
2. Common question types
3. How to structure answers
4. Tips for success
Keep it concise and actionable.
""").text
final = search_results + "\n**πŸ’‘ How to Tackle These Interviews:**\n\n" + guidance
return {"status": "success", "response": final}
# β€”β€”β€” Tool 3: Simulate Mock Interview β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
# Enhanced user session management
user_sessions = {}
def simulate_mock_interview(query, user_id="default"):
session_key = f"mock_{user_id}"
if session_key not in user_sessions:
user_sessions[session_key] = {
"stage": "tech_stack",
"tech_stack": "",
"questions_asked": [],
"answers_given": [],
"current_question": "",
"question_count": 0,
"difficulty": "medium", # Added difficulty level
"feedback_history": [] # Added feedback tracking
}
session = user_sessions[session_key]
model = genai.GenerativeModel('gemini-1.5-flash')
# Tech stack collection stage
if session["stage"] == "tech_stack":
session["stage"] = "waiting_tech_stack"
return {"status": "success", "response": (
"Welcome to your mock interview! 🎯\n\n"
"Please tell me about your tech stack (e.g., Python, React, multi-agent systems) "
"or the role you're preparing for (e.g., software engineer, ML engineer)."
)}
elif session["stage"] == "waiting_tech_stack":
session["tech_stack"] = query
session["stage"] = "interviewing"
difficulty_options = " (easy/medium/hard)"
q = model.generate_content(f"""
Generate a relevant interview question for tech stack: {query}
Ensure it tests technical knowledge and problem-solving.
Keep it concise and return only the question.
""").text.strip()
session.update({
"current_question": q,
"questions_asked": [q],
"question_count": 1
})
return {"status": "success", "response": (
f"Great! Based on your tech stack ({query}), let's start your mock interview.\n\n"
f"**Question 1:** {q}\n"
f"Set difficulty level{difficulty_options} or proceed. Type 'quit' to end and get your summary."
)}
elif session["stage"] == "interviewing":
if query.lower().strip() in ["easy", "medium", "hard"]:
session["difficulty"] = query.lower().strip()
return {"status": "success", "response": (
f"Difficulty set to {session['difficulty']}. Let's continue!\n\n"
f"**Question {session['question_count']}:** {session['current_question']}\n\n"
"Take your time to answer. Type 'quit' to end and get your summary."
)}
if query.lower().strip() == "quit":
return end_mock_interview(session_key)
# Store answer and provide feedback
session["answers_given"].append(query)
feedback = model.generate_content(f"""
Question: {session['current_question']}
Answer: {query}
Tech Stack: {session['tech_stack']}
Difficulty: {session['difficulty']}
Provide concise, constructive feedback:
- What went well
- Areas to improve
- Missing points or better approach
- Suggested follow-up topic
""").text.strip()
session["feedback_history"].append(feedback)
# Generate next question with context
next_q = model.generate_content(f"""
Tech stack: {session['tech_stack']}
Difficulty: {session['difficulty']}
Previous questions: {session['questions_asked']}
Follow-up topic suggestion: {feedback.split('\n')[-1] if feedback else ''}
Generate a new, relevant interview question unseen before.
Ensure it aligns with the tech stack and difficulty.
Return only the question.
""").text.strip()
session["questions_asked"].append(next_q)
session["current_question"] = next_q
session["question_count"] += 1
return {"status": "success", "response": (
f"**Feedback on your previous answer:**\n{feedback}\n\n"
f"**Question {session['question_count']}:** {next_q}\n\n"
"Type 'quit' to end the interview and get your summary, or set a new difficulty (easy/medium/hard)."
)}
def end_mock_interview(session_key):
session = user_sessions[session_key]
model = genai.GenerativeModel('gemini-1.5-flash')
summary = model.generate_content(f"""
Mock Interview Summary:
Tech Stack: {session['tech_stack']}
Difficulty: {session['difficulty']}
Questions Asked: {session['questions_asked']}
Answers Given: {session['answers_given']}
Feedback History: {session['feedback_history']}
Provide a concise overall assessment:
- Strengths
- Areas for improvement
- Key recommendations
- Common mistakes to avoid
""").text.strip()
del user_sessions[session_key]
return {"status": "success", "response": (
"🎯 **Mock Interview Complete!**\n\n"
f"**Interview Summary:**\n"
f"- Tech Stack: {session['tech_stack']}\n"
f"- Difficulty: {session['difficulty']}\n"
f"- Questions Asked: {len(session['questions_asked'])}\n\n"
"**Overall Assessment:**\n" + summary + "\n\n"
"Great jobβ€”use this feedback to level up! πŸ’ͺ"
)}
# β€”β€”β€” Main Agent Class β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
class InterviewPrepAgent:
def __init__(self):
self.model = genai.GenerativeModel('gemini-1.5-flash')
self.tools = {
"get_daily_coding_question": get_daily_coding_question,
"fetch_interview_questions": fetch_interview_questions,
"simulate_mock_interview": simulate_mock_interview
}
def classify_query(self, query):
prompt = f"""
Analyze this user query and determine which tool to use:
Query: "{query}"
Tools:
1. get_daily_coding_question – for coding problems, leetcode, daily challenges
2. fetch_interview_questions – for topic-specific interview question resources
3. simulate_mock_interview – for mock interview practice or behavioral interviews
Rules:
- If query mentions 'mock', 'interview', 'simulate', or 'practice', choose simulate_mock_interview
- If query mentions 'coding', 'leetcode', 'daily', 'problem', choose get_daily_coding_question
- If query asks for interview questions on a specific technology (like 'Python interview questions'), choose fetch_interview_questions
- If unclear, default to simulate_mock_interview
Respond with JSON
"""
resp = self.model.generate_content(prompt).text.strip()
if resp.startswith("```json"):
resp = resp.replace("```json", "").replace("```", "").strip()
j = json.loads(resp)
return j.get("tool"), j.get("args", {})
def process_query(self, query, user_id="default"):
tool, args = self.classify_query(query)
if tool not in self.tools:
return {"text": "Sorry, I didn't get that. Ask for coding practice, interview questions, or mock interview!"}
if tool == "simulate_mock_interview":
result = self.tools[tool](args.get("query", query), user_id)
else:
result = self.tools[tool](args.get("query", query))
return {"text": result["response"]}
# β€”β€”β€” Gradio Interface β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
agent = InterviewPrepAgent()
def chat_interface(message, history):
resp = agent.process_query(message, user_id="gradio_user")
return resp.get("text", "Something went wrong, try again.")
def create_examples():
return [
["Give me daily coding questions"],
["Start a mock interview"],
["Python interview questions"],
["React interview questions"],
["Show me problem 1"],
["Data structures interview questions"],
]
with gr.Blocks(title="Interview Prep Assistant", theme=gr.themes.Soft()) as interface:
gr.Markdown("# 🎯 Interview Prep Assistant\nYour AI-powered interview practice companion!")
chatbot = gr.ChatInterface(
fn=chat_interface,
examples=create_examples(),
chatbot=gr.Chatbot(height=500, show_label=False, container=True, type="messages"),
textbox=gr.Textbox(placeholder="Type your message here...")
)
gr.Markdown(f"\n---\n**System Status:**\n- βœ… Google API Configured\n- βœ… {len(LEETCODE_DATA)} LeetCode Problems Loaded\n- {'βœ…' if TAVILY_API_KEY else '❌'} Tavily Search Available")
if __name__ == "__main__":
interface.launch(server_port=8000, share=True, show_error=True, quiet=False)