Spaces:
Runtime error
Runtime error
Upload 14 files
Browse files- src/chatbot/chatgpt.py +0 -1
- src/chatbot/prompts.py +3 -4
- src/data_handler.py +0 -2
- src/templates/resume.html +5 -5
- src/ui.py +83 -27
src/chatbot/chatgpt.py
CHANGED
@@ -18,7 +18,6 @@ openai_key_info = 'https://platform.openai.com/account/api-keys'
|
|
18 |
|
19 |
class Chatgpt:
|
20 |
def __init__(self, api_key):
|
21 |
-
self.validate_api(api_key)
|
22 |
self.chatbot = Chatbot(api_key)
|
23 |
logging.info("API key loaded successfully")
|
24 |
|
|
|
18 |
|
19 |
class Chatgpt:
|
20 |
def __init__(self, api_key):
|
|
|
21 |
self.chatbot = Chatbot(api_key)
|
22 |
logging.info("API key loaded successfully")
|
23 |
|
src/chatbot/prompts.py
CHANGED
@@ -2,9 +2,8 @@ prompt_placeholder = '[$$$]'
|
|
2 |
|
3 |
data_format = {'name': '', 'title': '',
|
4 |
'contactInfo': {'linkedin': '', 'github': '', 'email': '', 'address': '', 'phone': ''}, 'summary': '',
|
5 |
-
'workExperience': [{'title': '', 'company': '', 'dates': '', 'description': ''},
|
6 |
-
|
7 |
-
'education': [{'degree': '', 'school': '', 'dates': '', 'description': ''}, ], 'skills': ['', '', '']}
|
8 |
|
9 |
recruiter_prompt = 'You are a professional resume builder and a recruiter.\n'
|
10 |
command_prompt = 'Re-write the input as professionally as possible, adding vital, valuable information and skills.\n' \
|
@@ -31,4 +30,4 @@ def get_prompt(input_data, user_request='', output_type='all'):
|
|
31 |
template = '\n'.join(
|
32 |
[recruiter_prompt, command_prompt, user_request_prompt.replace(prompt_placeholder, user_request),
|
33 |
input_prompt.replace(prompt_placeholder, input_data), output_commands_prompts[output_type], command_prompt])
|
34 |
-
return template
|
|
|
2 |
|
3 |
data_format = {'name': '', 'title': '',
|
4 |
'contactInfo': {'linkedin': '', 'github': '', 'email': '', 'address': '', 'phone': ''}, 'summary': '',
|
5 |
+
'workExperience': [{'title': '', 'company': '', 'dates': '', 'description': ''}, ],
|
6 |
+
'education': [{'degree': '', 'school': '', 'dates': '', 'description': ''}, ], 'skills': ['', ]}
|
|
|
7 |
|
8 |
recruiter_prompt = 'You are a professional resume builder and a recruiter.\n'
|
9 |
command_prompt = 'Re-write the input as professionally as possible, adding vital, valuable information and skills.\n' \
|
|
|
30 |
template = '\n'.join(
|
31 |
[recruiter_prompt, command_prompt, user_request_prompt.replace(prompt_placeholder, user_request),
|
32 |
input_prompt.replace(prompt_placeholder, input_data), output_commands_prompts[output_type], command_prompt])
|
33 |
+
return template
|
src/data_handler.py
CHANGED
@@ -23,7 +23,6 @@ def update_resume_data(text_input, section_name, item_id=0):
|
|
23 |
st.session_state['resume_data'][section_key] = text_input
|
24 |
|
25 |
|
26 |
-
@st.cache
|
27 |
def download_pdf():
|
28 |
if st.session_state.get('name'):
|
29 |
resume_data = format_resume_data()
|
@@ -85,5 +84,4 @@ def format_resume_data():
|
|
85 |
|
86 |
skills.append(current_state.get(skill_key, ''))
|
87 |
resume_data['skills'] = skills
|
88 |
-
|
89 |
return resume_data
|
|
|
23 |
st.session_state['resume_data'][section_key] = text_input
|
24 |
|
25 |
|
|
|
26 |
def download_pdf():
|
27 |
if st.session_state.get('name'):
|
28 |
resume_data = format_resume_data()
|
|
|
84 |
|
85 |
skills.append(current_state.get(skill_key, ''))
|
86 |
resume_data['skills'] = skills
|
|
|
87 |
return resume_data
|
src/templates/resume.html
CHANGED
@@ -41,11 +41,11 @@
|
|
41 |
</div>
|
42 |
<div class="right">
|
43 |
<h2>Contact Information</h2>
|
44 |
-
<p>Email: {{email}}</p>
|
45 |
-
<p>Phone: {{phone}}</p>
|
46 |
-
<p>Address: {{address}}</p>
|
47 |
-
<p>LinkedIn: <a href="{{
|
48 |
-
<p>Github: <a href="{{
|
49 |
|
50 |
<section>
|
51 |
<h1>Skills</h1>
|
|
|
41 |
</div>
|
42 |
<div class="right">
|
43 |
<h2>Contact Information</h2>
|
44 |
+
<p>Email: {{contactInfo.email}}</p>
|
45 |
+
<p>Phone: {{contactInfo.phone}}</p>
|
46 |
+
<p>Address: {{contactInfo.address}}</p>
|
47 |
+
<p>LinkedIn: <a href="{{contactInfo.linkedin}}">LinkedIn Profile</a></p>
|
48 |
+
<p>Github: <a href="{{contactInfo.github}}">GitHub Profile</a></p>
|
49 |
|
50 |
<section>
|
51 |
<h1>Skills</h1>
|
src/ui.py
CHANGED
@@ -1,13 +1,15 @@
|
|
1 |
import streamlit as st
|
2 |
|
3 |
from src.chatbot.chatgpt import openai_key_info, Chatgpt
|
|
|
4 |
from src.data_handler import improve_resume, init_resume, download_pdf, update_resume_data, PDFSizeException
|
5 |
from src.exceptions import ChatbotInitException
|
6 |
from src.utils import is_new_file, is_data_loaded, key_to_tab_name, get_item_key, init_user_info
|
7 |
|
8 |
section_examples = {'summary': 'I have passion for new tech',
|
9 |
'workExperience': 'Tell about my ability to lead projects',
|
10 |
-
'education': 'Describe my degree type in more details'
|
|
|
11 |
|
12 |
|
13 |
def title():
|
@@ -110,16 +112,63 @@ def list_section(section_name, section_data):
|
|
110 |
item_keys = list(section_data[0].keys())
|
111 |
item_keys.remove(description_key)
|
112 |
for item_id, section_item in enumerate(section_data):
|
|
|
113 |
cols = st.columns(len(item_keys))
|
114 |
for col, key in zip(cols, item_keys):
|
115 |
col.text_input(key, section_item[key], key=f'{section_name}_{item_id}_{key}')
|
116 |
st.text_area(description_key, section_item[description_key], key=f'{section_name}_{item_id}_{description_key}')
|
117 |
|
118 |
recruiter_subsection(section_name, section_example=section_examples[section_name], item_id=item_id)
|
|
|
|
|
119 |
st.markdown('***')
|
120 |
|
121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
def skills_section(section_name, skills_data):
|
|
|
|
|
123 |
num_columns = 3
|
124 |
for skills_row in range(0, len(skills_data), num_columns):
|
125 |
cols = st.columns([3, 1] * num_columns)
|
@@ -128,7 +177,7 @@ def skills_section(section_name, skills_data):
|
|
128 |
skill_id = skills_row + item_id
|
129 |
cols[item_id * 2].text_input(' ', value=skill, key=f'{section_name}_{skill_id}', label_visibility='hidden')
|
130 |
cols[item_id * 2 + 1].markdown('## ')
|
131 |
-
if cols[item_id * 2 + 1].button('x', key=f'{section_name}_{skill_id}
|
132 |
del skills_data[skill_id]
|
133 |
st.experimental_rerun()
|
134 |
|
@@ -136,13 +185,6 @@ def skills_section(section_name, skills_data):
|
|
136 |
st.markdown('***')
|
137 |
|
138 |
|
139 |
-
def contact_info_section(section_name, info_data):
|
140 |
-
for key, value in info_data.items():
|
141 |
-
if value:
|
142 |
-
st.text_input(key.title(), value, key=f'{section_name}_{key}')
|
143 |
-
st.markdown('***')
|
144 |
-
|
145 |
-
|
146 |
def skill_subsection(section_name, item_id=0):
|
147 |
key = f'{section_name}_{item_id}_add_skill'
|
148 |
cols = st.columns([12, 1])
|
@@ -150,31 +192,45 @@ def skill_subsection(section_name, item_id=0):
|
|
150 |
cols[1].markdown('##')
|
151 |
clicked = cols[1].button("\+")
|
152 |
if clicked and new_skill:
|
153 |
-
st.write(new_skill)
|
154 |
st.session_state['resume_data'][section_name].append(new_skill)
|
155 |
-
st.write(st.session_state['resume_data'][section_name])
|
156 |
st.experimental_rerun()
|
157 |
|
158 |
|
159 |
-
def
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
cols[
|
164 |
-
|
165 |
-
|
166 |
-
|
|
|
|
|
|
|
167 |
|
168 |
-
|
169 |
-
|
170 |
-
if button_clicked:
|
171 |
-
user_request = '' if trigger_key in user_request else user_request
|
172 |
-
section_key = get_item_key(section_name, item_id)
|
173 |
-
section_text = st.session_state[section_key]
|
174 |
-
new_section_text = st.session_state['chatbot'].improve_section(section_text, user_request)
|
175 |
|
176 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
st.experimental_rerun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
|
179 |
|
180 |
def success_info(message):
|
|
|
1 |
import streamlit as st
|
2 |
|
3 |
from src.chatbot.chatgpt import openai_key_info, Chatgpt
|
4 |
+
from src.chatbot.prompts import data_format
|
5 |
from src.data_handler import improve_resume, init_resume, download_pdf, update_resume_data, PDFSizeException
|
6 |
from src.exceptions import ChatbotInitException
|
7 |
from src.utils import is_new_file, is_data_loaded, key_to_tab_name, get_item_key, init_user_info
|
8 |
|
9 |
section_examples = {'summary': 'I have passion for new tech',
|
10 |
'workExperience': 'Tell about my ability to lead projects',
|
11 |
+
'education': 'Describe my degree type in more details',
|
12 |
+
'contactInfo': 'phone, Linkedin, etc.'}
|
13 |
|
14 |
|
15 |
def title():
|
|
|
112 |
item_keys = list(section_data[0].keys())
|
113 |
item_keys.remove(description_key)
|
114 |
for item_id, section_item in enumerate(section_data):
|
115 |
+
|
116 |
cols = st.columns(len(item_keys))
|
117 |
for col, key in zip(cols, item_keys):
|
118 |
col.text_input(key, section_item[key], key=f'{section_name}_{item_id}_{key}')
|
119 |
st.text_area(description_key, section_item[description_key], key=f'{section_name}_{item_id}_{description_key}')
|
120 |
|
121 |
recruiter_subsection(section_name, section_example=section_examples[section_name], item_id=item_id)
|
122 |
+
edit_list_subsection(section_name, section_data, item_id)
|
123 |
+
|
124 |
st.markdown('***')
|
125 |
|
126 |
|
127 |
+
def edit_list_subsection(section_name, section_data, item_id):
|
128 |
+
with st.container():
|
129 |
+
st.markdown(
|
130 |
+
"""<style>
|
131 |
+
.element-container:nth-of-type(1) button {
|
132 |
+
width: 100%;
|
133 |
+
}
|
134 |
+
</style>""",
|
135 |
+
unsafe_allow_html=True,
|
136 |
+
)
|
137 |
+
|
138 |
+
remove_col, add_col = st.columns(2)
|
139 |
+
if remove_col.button('Delete', key=f'{section_name}_{item_id}_remove_from_list') and len(section_data) > 1:
|
140 |
+
del section_data[item_id]
|
141 |
+
st.experimental_rerun()
|
142 |
+
|
143 |
+
if add_col.button('Add', key=f'{section_name}_{item_id}_add_to_list') and len(section_data) < 10:
|
144 |
+
section_data.append(data_format[section_name][0])
|
145 |
+
st.experimental_rerun()
|
146 |
+
|
147 |
+
|
148 |
+
def recruiter_subsection(section_name, section_example, item_id=0):
|
149 |
+
with st.container():
|
150 |
+
cols = st.columns([3, 10], gap='small')
|
151 |
+
cols[0].write('\n')
|
152 |
+
cols[0].write('\n')
|
153 |
+
button_clicked = cols[0].button("Auto Section Improve", key=f'{section_name}_{item_id}_improve_auto')
|
154 |
+
trigger_key = 'Add a special request'
|
155 |
+
user_request_template = f"{trigger_key} to the bot here... e.g. {section_example}."
|
156 |
+
|
157 |
+
user_request = cols[1].text_input("section_example", value=user_request_template,
|
158 |
+
key=f'{section_name}_{item_id}_improve_manual', label_visibility='hidden')
|
159 |
+
if button_clicked:
|
160 |
+
user_request = '' if trigger_key in user_request else user_request
|
161 |
+
section_key = get_item_key(section_name, item_id)
|
162 |
+
section_text = st.session_state[section_key]
|
163 |
+
new_section_text = st.session_state['chatbot'].improve_section(section_text, user_request)
|
164 |
+
|
165 |
+
update_resume_data(new_section_text, section_name, item_id)
|
166 |
+
st.experimental_rerun()
|
167 |
+
|
168 |
+
|
169 |
def skills_section(section_name, skills_data):
|
170 |
+
[skills_data.remove(skill) for skill in skills_data if not skill]
|
171 |
+
|
172 |
num_columns = 3
|
173 |
for skills_row in range(0, len(skills_data), num_columns):
|
174 |
cols = st.columns([3, 1] * num_columns)
|
|
|
177 |
skill_id = skills_row + item_id
|
178 |
cols[item_id * 2].text_input(' ', value=skill, key=f'{section_name}_{skill_id}', label_visibility='hidden')
|
179 |
cols[item_id * 2 + 1].markdown('## ')
|
180 |
+
if cols[item_id * 2 + 1].button('x', key=f'{section_name}_{skill_id}_remove_from_list'):
|
181 |
del skills_data[skill_id]
|
182 |
st.experimental_rerun()
|
183 |
|
|
|
185 |
st.markdown('***')
|
186 |
|
187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
def skill_subsection(section_name, item_id=0):
|
189 |
key = f'{section_name}_{item_id}_add_skill'
|
190 |
cols = st.columns([12, 1])
|
|
|
192 |
cols[1].markdown('##')
|
193 |
clicked = cols[1].button("\+")
|
194 |
if clicked and new_skill:
|
|
|
195 |
st.session_state['resume_data'][section_name].append(new_skill)
|
|
|
196 |
st.experimental_rerun()
|
197 |
|
198 |
|
199 |
+
def contact_info_section(section_name, info_data):
|
200 |
+
keys = sorted(info_data.keys())
|
201 |
+
for key in keys:
|
202 |
+
value = info_data[key]
|
203 |
+
cols = st.columns([12, 1])
|
204 |
+
cols[0].text_input(key.title(), value, key=f'{section_name}_{key}')
|
205 |
+
cols[1].markdown('##')
|
206 |
+
clicked = cols[1].button('\-', key=f'{section_name}_{key}_remove')
|
207 |
+
if clicked:
|
208 |
+
del info_data[key]
|
209 |
+
st.experimental_rerun()
|
210 |
|
211 |
+
add_contact_subsection(section_name, info_data)
|
212 |
+
st.markdown('***')
|
|
|
|
|
|
|
|
|
|
|
213 |
|
214 |
+
|
215 |
+
def add_contact_subsection(section_name, info_data):
|
216 |
+
st.markdown('***')
|
217 |
+
|
218 |
+
with st.container():
|
219 |
+
cols = st.columns([12, 1])
|
220 |
+
new_key = cols[0].text_input('Add new details', value=f"e.g, {section_examples[section_name]}")
|
221 |
+
cols[1].markdown('##')
|
222 |
+
clicked = cols[1].button('\+', key=f'{section_name}_add_details')
|
223 |
+
|
224 |
+
if clicked and new_key:
|
225 |
+
info_data[new_key] = ''
|
226 |
st.experimental_rerun()
|
227 |
+
# if remove_col.button('Delete', key=f'{section_name}_{item_id}_remove_from_list') and len(section_data) > 1:
|
228 |
+
# del section_data[item_id]
|
229 |
+
# st.experimental_rerun()
|
230 |
+
#
|
231 |
+
# if add_col.button('Add', key=f'{section_name}_{item_id}_add_to_list') and len(section_data) < 10:
|
232 |
+
# section_data.append(data_format[section_name][0])
|
233 |
+
# st.experimental_rerun()
|
234 |
|
235 |
|
236 |
def success_info(message):
|