Spaces:
Running
Running
Delete app.py
Browse files
app.py
DELETED
@@ -1,143 +0,0 @@
|
|
1 |
-
import streamlit as st
|
2 |
-
from utils.cv_processor import evaluate_cv
|
3 |
-
from utils.interview_agent import InterviewAgent
|
4 |
-
from utils.report_generator import generate_report
|
5 |
-
import os
|
6 |
-
from datetime import datetime
|
7 |
-
|
8 |
-
def main():
|
9 |
-
st.set_page_config(page_title="AI Interview Agent", layout="wide")
|
10 |
-
|
11 |
-
st.title("AI Interview Agent")
|
12 |
-
st.write("Upload your CV and start your interview for the desired position.")
|
13 |
-
|
14 |
-
# Initialize session state
|
15 |
-
if 'interview_started' not in st.session_state:
|
16 |
-
st.session_state.interview_started = False
|
17 |
-
if 'current_question' not in st.session_state:
|
18 |
-
st.session_state.current_question = 0
|
19 |
-
if 'answers' not in st.session_state:
|
20 |
-
st.session_state.answers = []
|
21 |
-
if 'cv_evaluated' not in st.session_state:
|
22 |
-
st.session_state.cv_evaluated = False
|
23 |
-
if 'cv_rejected' not in st.session_state:
|
24 |
-
st.session_state.cv_rejected = False
|
25 |
-
|
26 |
-
# Step 1: Job Role and CV Upload
|
27 |
-
if not st.session_state.cv_evaluated:
|
28 |
-
with st.form("candidate_info"):
|
29 |
-
job_role = st.selectbox(
|
30 |
-
"Select the job role you're applying for:",
|
31 |
-
["Software Engineer", "Data Scientist", "Product Manager", "UX Designer", "DevOps Engineer"]
|
32 |
-
)
|
33 |
-
cv_file = st.file_uploader("Upload your CV (PDF or DOCX)", type=["pdf", "docx"])
|
34 |
-
submitted = st.form_submit_button("Submit")
|
35 |
-
|
36 |
-
if submitted and cv_file:
|
37 |
-
with st.spinner("Evaluating your CV..."):
|
38 |
-
# Save the uploaded file
|
39 |
-
file_path = f"data/temp_cv.{'pdf' if cv_file.type == 'application/pdf' else 'docx'}"
|
40 |
-
with open(file_path, "wb") as f:
|
41 |
-
f.write(cv_file.getbuffer())
|
42 |
-
|
43 |
-
# Evaluate CV
|
44 |
-
evaluation = evaluate_cv(file_path, job_role)
|
45 |
-
|
46 |
-
if evaluation["is_qualified"]:
|
47 |
-
st.session_state.cv_evaluated = True
|
48 |
-
st.session_state.job_role = job_role
|
49 |
-
st.session_state.cv_evaluation = evaluation
|
50 |
-
st.success("CV evaluation complete! You meet the basic requirements.")
|
51 |
-
else:
|
52 |
-
st.session_state.cv_rejected = True
|
53 |
-
st.session_state.rejection_reasons = evaluation["rejection_reasons"]
|
54 |
-
st.error("Your CV doesn't meet the requirements for this role.")
|
55 |
-
|
56 |
-
# Step 2: Interview Process
|
57 |
-
if st.session_state.cv_evaluated and not st.session_state.interview_started:
|
58 |
-
if st.button("Start Interview"):
|
59 |
-
st.session_state.interview_started = True
|
60 |
-
st.session_state.interview_agent = InterviewAgent(job_role, st.session_state.cv_evaluation["cv_summary"])
|
61 |
-
st.session_state.questions = st.session_state.interview_agent.get_questions()
|
62 |
-
st.experimental_rerun()
|
63 |
-
|
64 |
-
if st.session_state.interview_started:
|
65 |
-
interview_ui()
|
66 |
-
|
67 |
-
# Step 3: Show rejection if CV was rejected
|
68 |
-
if st.session_state.cv_rejected:
|
69 |
-
st.error("Unfortunately, your CV doesn't meet the requirements for this role.")
|
70 |
-
st.write("Reasons for rejection:")
|
71 |
-
for reason in st.session_state.rejection_reasons:
|
72 |
-
st.write(f"- {reason}")
|
73 |
-
if st.button("Try a different role"):
|
74 |
-
st.session_state.cv_rejected = False
|
75 |
-
st.session_state.cv_evaluated = False
|
76 |
-
st.experimental_rerun()
|
77 |
-
|
78 |
-
def interview_ui():
|
79 |
-
agent = st.session_state.interview_agent
|
80 |
-
questions = st.session_state.questions
|
81 |
-
|
82 |
-
# Show current question or completion
|
83 |
-
if st.session_state.current_question < len(questions):
|
84 |
-
question = questions[st.session_state.current_question]
|
85 |
-
|
86 |
-
st.subheader(f"Question {st.session_state.current_question + 1}/{len(questions)}")
|
87 |
-
st.write(question["text"])
|
88 |
-
|
89 |
-
# Answer input
|
90 |
-
answer = st.text_area("Your answer:", key=f"answer_{st.session_state.current_question}")
|
91 |
-
|
92 |
-
if st.button("Submit Answer"):
|
93 |
-
evaluation = agent.evaluate_answer(question, answer)
|
94 |
-
st.session_state.answers.append({
|
95 |
-
"question": question,
|
96 |
-
"answer": answer,
|
97 |
-
"evaluation": evaluation
|
98 |
-
})
|
99 |
-
st.session_state.current_question += 1
|
100 |
-
st.experimental_rerun()
|
101 |
-
else:
|
102 |
-
# Interview complete
|
103 |
-
st.success("Interview completed!")
|
104 |
-
final_evaluation = agent.final_evaluation(st.session_state.answers)
|
105 |
-
|
106 |
-
# Display results
|
107 |
-
st.subheader("Interview Results")
|
108 |
-
st.write(f"Overall Score: {final_evaluation['score']}/10")
|
109 |
-
st.write(f"Band: {final_evaluation['band']}")
|
110 |
-
|
111 |
-
st.subheader("Detailed Feedback")
|
112 |
-
for i, answer in enumerate(st.session_state.answers):
|
113 |
-
st.write(f"**Question {i+1}:** {answer['question']['text']}")
|
114 |
-
st.write(f"**Your Answer:** {answer['answer']}")
|
115 |
-
st.write(f"**Feedback:** {answer['evaluation']['feedback']}")
|
116 |
-
st.write("---")
|
117 |
-
|
118 |
-
# Generate and download report
|
119 |
-
report_path = generate_report(
|
120 |
-
st.session_state.job_role,
|
121 |
-
st.session_state.cv_evaluation["cv_summary"],
|
122 |
-
st.session_state.answers,
|
123 |
-
final_evaluation
|
124 |
-
)
|
125 |
-
|
126 |
-
with open(report_path, "rb") as f:
|
127 |
-
st.download_button(
|
128 |
-
"Download Interview Report",
|
129 |
-
f,
|
130 |
-
file_name=f"Interview_Report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf",
|
131 |
-
mime="application/pdf"
|
132 |
-
)
|
133 |
-
|
134 |
-
if st.button("Start New Interview"):
|
135 |
-
reset_session()
|
136 |
-
|
137 |
-
def reset_session():
|
138 |
-
for key in list(st.session_state.keys()):
|
139 |
-
del st.session_state[key]
|
140 |
-
st.experimental_rerun()
|
141 |
-
|
142 |
-
if __name__ == "__main__":
|
143 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|