Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import requests | |
| import os | |
| from hashlib import sha256 | |
| import random | |
| # ========== CONFIG ========== | |
| GROQ_API_KEY = "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" # Replace with your actual key | |
| GROQ_MODEL = "llama3-8b-8192" # Recommended current Groq model | |
| # ========== STATE ========== | |
| if "last_result" not in st.session_state: | |
| st.session_state.last_result = None | |
| if "last_candidate" not in st.session_state: | |
| st.session_state.last_candidate = None | |
| # ========== GROQ HELPERS ========== | |
| def generate_questions(domain: str, round_type: str): | |
| prompt = f""" | |
| Generate 3 {round_type} interview questions for a candidate in the domain of {domain}. | |
| Questions should be clear, concise, and assess relevant skills. | |
| """ | |
| headers = {"Authorization": f"Bearer {GROQ_API_KEY}", "Content-Type": "application/json"} | |
| data = { | |
| "model": GROQ_MODEL, | |
| "messages": [{"role": "user", "content": prompt}], | |
| "temperature": 0.7, | |
| "max_tokens": 400, | |
| } | |
| response = requests.post("https://api.groq.com/openai/v1/chat/completions", headers=headers, json=data) | |
| try: | |
| res_json = response.json() | |
| return [q.strip("- ").strip() for q in res_json['choices'][0]['message']['content'].split("\n") if q.strip()] | |
| except Exception as e: | |
| st.error(f"Groq API Error: {e}") | |
| st.json(response.json()) | |
| return ["Question 1", "Question 2", "Question 3"] | |
| def generate_programming_question(domain: str, language: str): | |
| prompt = f""" | |
| Generate 1 beginner-to-intermediate level programming interview question in {language} for a candidate applying in the domain of {domain}. | |
| Provide only the question without solution or explanation. | |
| """ | |
| headers = {"Authorization": f"Bearer {GROQ_API_KEY}", "Content-Type": "application/json"} | |
| data = { | |
| "model": GROQ_MODEL, | |
| "messages": [{"role": "user", "content": prompt}], | |
| "temperature": 0.7, | |
| "max_tokens": 300, | |
| } | |
| response = requests.post("https://api.groq.com/openai/v1/chat/completions", headers=headers, json=data) | |
| try: | |
| return response.json()['choices'][0]['message']['content'] | |
| except Exception as e: | |
| st.error(f"Groq API Error: {e}") | |
| st.json(response.json()) | |
| return "Write a function to reverse a string." | |
| # ========== CORE FUNCTIONALITY ========== | |
| def check_resume_originality(uploaded_file): | |
| content = uploaded_file.read() | |
| resume_hash = sha256(content).hexdigest() | |
| existing_hashes = ["abc123", "def456"] # Dummy hashes - replace with real hashes database | |
| return 20 if resume_hash in existing_hashes else 95 | |
| def save_to_crm(name, domain, result): | |
| # Placeholder for CRM integration - replace with real CRM API calls | |
| print(f"[CRM] Candidate: {name}, Domain: {domain}, Result: {result}") | |
| def show_dashboard(): | |
| st.title("π Dashboard") | |
| if st.session_state.last_result: | |
| st.subheader("Latest Candidate Summary") | |
| total_score = sum(st.session_state.last_result.values()) / len(st.session_state.last_result) | |
| st.metric("Overall Score", f"{total_score:.2f}%") | |
| st.progress(int(total_score)) | |
| for k, v in st.session_state.last_result.items(): | |
| st.write(f"**{k.replace('_', ' ').title()}**: {v:.2f}%") | |
| st.info(f"Last candidate: {st.session_state.last_candidate}") | |
| else: | |
| st.warning("No interview data available yet.") | |
| def start_interview(domain, language): | |
| result = {} | |
| st.subheader("π’ Round 1: Aptitude") | |
| aptitude_qs = generate_questions(domain, "aptitude") | |
| aptitude_score = 0 | |
| for i, q in enumerate(aptitude_qs): | |
| ans = st.text_input(f"Aptitude Q{i+1}: {q}", key=f"apt{i}") | |
| if ans: | |
| aptitude_score += 1 | |
| result['aptitude_score'] = (aptitude_score / len(aptitude_qs)) * 100 | |
| st.subheader(f"π» Round 2: Programming in {language}") | |
| prog_q = generate_programming_question(domain, language) | |
| st.markdown(f"**Problem:** {prog_q}") | |
| code_ans = st.text_area(f"Write your solution in {language}", key="code") | |
| result['code_score'] = 90 if ("def" in code_ans or "class" in code_ans) and len(code_ans) > 20 else 40 | |
| st.subheader("π¬ Round 3: HR Interview") | |
| hr_qs = generate_questions(domain, "HR") | |
| hr_score = 0 | |
| for i, q in enumerate(hr_qs): | |
| ans = st.text_area(f"HR Q{i+1}: {q}", key=f"hr{i}") | |
| hr_score += len(ans.split()) > 15 | |
| result['hr_score'] = (hr_score / len(hr_qs)) * 100 | |
| st.subheader("π£οΈ Round 4: Communication") | |
| result['communication_score'] = random.randint(70, 90) | |
| # --- Show final marks summary --- | |
| st.markdown("---") | |
| st.header("π Interview Summary") | |
| rounds = { | |
| "Aptitude": result['aptitude_score'], | |
| "Programming": result['code_score'], | |
| "HR Interview": result['hr_score'], | |
| "Communication": result['communication_score'], | |
| } | |
| total = sum(rounds.values()) / len(rounds) | |
| for round_name, score in rounds.items(): | |
| st.write(f"**{round_name}:** {score:.2f}%") | |
| st.write(f"### Overall Score: {total:.2f}%") | |
| st.progress(int(total)) | |
| return result | |
| # ========== MAIN APP ========== | |
| st.set_page_config(page_title="AI Interview System", layout="centered") | |
| page = st.sidebar.radio("π Navigate", ["Interview", "Dashboard"]) | |
| if page == "Interview": | |
| st.title("π§ AI Interview System") | |
| uploaded_resume = st.file_uploader("π Upload Resume (PDF/DOCX)", type=['pdf', 'docx']) | |
| domain = st.selectbox("π― Select your domain", ["Software", "Data Science", "Networking", "AI/ML"]) | |
| language = st.selectbox("π» Select programming language", ["Python", "Java", "C++", "JavaScript"]) | |
| if uploaded_resume and domain and language: | |
| with st.expander("π Step 1: Resume Originality Check"): | |
| score = check_resume_originality(uploaded_resume) | |
| st.info(f"Resume Originality Score: **{score}%**") | |
| if st.button("π Start Interview"): | |
| result = start_interview(domain, language) | |
| st.success("β Interview Completed!") | |
| st.session_state.last_result = result | |
| st.session_state.last_candidate = uploaded_resume.name | |
| save_to_crm(uploaded_resume.name, domain, result) | |
| elif page == "Dashboard": | |
| show_dashboard() | |