ofikodar commited on
Commit
780a2a4
1 Parent(s): ba6ea70

Upload 14 files

Browse files
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
- {'title': '', 'company': '', 'dates': '', 'description': ''}, ],
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="{{linkedin_url}}">LinkedIn Profile</a></p>
48
- <p>Github: <a href="{{github_url}}">GitHub Profile</a></p>
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}remove_from_list'):
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 recruiter_subsection(section_name, section_example, item_id=0):
160
- with st.container():
161
- cols = st.columns([3, 10], gap='small')
162
- cols[0].write('\n')
163
- cols[0].write('\n')
164
- button_clicked = cols[0].button("Auto Section Improve", key=f'{section_name}_{item_id}_improve_auto')
165
- trigger_key = 'Add a special request'
166
- user_request_template = f"{trigger_key} to the bot here... e.g. {section_example}."
 
 
 
167
 
168
- user_request = cols[1].text_input("section_example", value=user_request_template,
169
- key=f'{section_name}_{item_id}_improve_manual', label_visibility='hidden')
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
- update_resume_data(new_section_text, section_name, item_id)
 
 
 
 
 
 
 
 
 
 
 
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):