SamitF commited on
Commit
e74c9ea
Β·
verified Β·
1 Parent(s): fffbbd4

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +155 -0
  2. requirements.txt +3 -0
app.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import json
4
+ import PyPDF2
5
+ from io import BytesIO
6
+ import os
7
+
8
+ # Global variable to store extracted resume text
9
+ current_resume_text = ""
10
+
11
+ DEEPSEEK_API_KEY = os.environ.get("DEEPSEEK_API_KEY")
12
+
13
+
14
+
15
+ def extract_text_from_pdf(pdf_file):
16
+ """Extract text from uploaded PDF file"""
17
+ try:
18
+ pdf_reader = PyPDF2.PdfReader(pdf_file)
19
+ text = ""
20
+ for page in pdf_reader.pages:
21
+ text += page.extract_text() + "\n"
22
+ return text.strip()
23
+ except Exception as e:
24
+ raise Exception(f"Error reading PDF: {str(e)}")
25
+
26
+
27
+ def process_resume(pdf_file):
28
+ """Process the uploaded resume and store text globally"""
29
+ global current_resume_text
30
+
31
+ if not pdf_file:
32
+ return "Please upload a PDF file.", ""
33
+
34
+ try:
35
+ current_resume_text = extract_text_from_pdf(pdf_file)
36
+ if not current_resume_text:
37
+ return "No text could be extracted from the PDF. Please ensure the PDF contains readable text.", ""
38
+
39
+ success_message = f"βœ… Resume processed successfully! ({len(current_resume_text)} characters extracted)\n\nYou can now ask questions about this resume in the chat."
40
+ return success_message, ""
41
+
42
+ except Exception as e:
43
+ current_resume_text = ""
44
+ return f"Error processing resume: {str(e)}", ""
45
+
46
+
47
+ def answer_question(question, chat_history):
48
+ """Answer questions about the uploaded resume"""
49
+ global current_resume_text
50
+
51
+ if not current_resume_text:
52
+ response = "❌ Please upload and process a resume first before asking questions."
53
+ chat_history.append([question, response])
54
+ return chat_history, ""
55
+
56
+ if not question.strip():
57
+ response = "Please enter a question about the resume."
58
+ chat_history.append([question, response])
59
+ return chat_history, ""
60
+
61
+ try:
62
+ prompt = f"""
63
+ Based on the following resume content, please answer the user's question accurately and concisely:
64
+ Resume Content:
65
+ {current_resume_text}
66
+ User Question: {question}
67
+ Please provide a clear, specific answer based only on the information available in the resume. If the information is not available in the resume, please state that clearly.
68
+ """
69
+
70
+ response = requests.post(
71
+ url="https://openrouter.ai/api/v1/chat/completions",
72
+ headers={
73
+ "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
74
+ "Content-Type": "application/json",
75
+ },
76
+ data=json.dumps({
77
+ "model": "deepseek/deepseek-chat",
78
+ "messages": [
79
+ {
80
+ "role": "system",
81
+ "content": "You are a helpful assistant that answers questions about resumes. Base your answers strictly on the resume content provided. Be concise but thorough."
82
+ },
83
+ {
84
+ "role": "user",
85
+ "content": prompt
86
+ }
87
+ ]
88
+ })
89
+ )
90
+
91
+ if response.status_code == 200:
92
+ result = response.json()
93
+ answer = result['choices'][0]['message']['content']
94
+ else:
95
+ answer = f"❌ API Error: {response.text}"
96
+
97
+ chat_history.append([question, answer])
98
+ return chat_history, ""
99
+
100
+ except Exception as e:
101
+ response = f"❌ Error: {str(e)}"
102
+ chat_history.append([question, response])
103
+ return chat_history, ""
104
+
105
+
106
+ def clear_chat():
107
+ return []
108
+
109
+
110
+ def get_sample_questions():
111
+ return [
112
+ "What are the key technical skills mentioned?",
113
+ "What is their educational background?",
114
+ "What certifications do they have?",
115
+ "Rate this resume on a scale of 1-10"
116
+ ]
117
+
118
+ # Gradio UI
119
+ def create_ui():
120
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="green")) as demo:
121
+ gr.Markdown("<h1 style='text-align: center; color: green;'>ResumAI</h1>")
122
+ gr.Markdown("<p style='text-align: center; color: white;'>Upload a resume (PDF) and ask specific questions about the candidate's skills, experience, and qualifications.</p>")
123
+
124
+ with gr.Row():
125
+ with gr.Column(scale=1):
126
+ gr.Markdown("### πŸ“„ Upload Resume")
127
+ pdf_input = gr.File(label="Upload PDF Resume", file_types=[".pdf"])
128
+ process_button = gr.Button("Process Resume", variant="primary")
129
+ status_text = gr.Textbox(label="Status", lines=3, interactive=False)
130
+
131
+ gr.Markdown("### πŸ’‘ Sample Questions")
132
+ sample_questions = get_sample_questions()
133
+ for question in sample_questions:
134
+ gr.Markdown(f"β€’ {question}")
135
+
136
+ with gr.Column(scale=2):
137
+ gr.Markdown("### πŸ’¬ Ask Questions About the Resume")
138
+ chatbot = gr.Chatbot(label="Q&A Chat", height=570)
139
+ with gr.Row():
140
+ question_input = gr.Textbox(label="Your Question", placeholder="Ask anything about the resume...", scale=4)
141
+ ask_button = gr.Button("Ask", variant="primary", scale=1)
142
+ with gr.Row():
143
+ clear_button = gr.Button("Clear Chat", variant="secondary")
144
+
145
+ process_button.click(fn=process_resume, inputs=[pdf_input], outputs=[status_text, question_input])
146
+ ask_button.click(fn=answer_question, inputs=[question_input, chatbot], outputs=[chatbot, question_input])
147
+ question_input.submit(fn=answer_question, inputs=[question_input, chatbot], outputs=[chatbot, question_input])
148
+ clear_button.click(fn=clear_chat, outputs=[chatbot])
149
+
150
+ return demo
151
+
152
+ if __name__ == "__main__":
153
+ print("Starting Resume Q&A Assistant with DeepSeek...")
154
+ demo = create_ui()
155
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ requests
3
+ PyPDF2