Spaces:
Sleeping
Sleeping
File size: 7,592 Bytes
517425f 892e1f4 fa99c44 517425f fa99c44 76c7d10 fa99c44 162a534 fa99c44 517425f 162a534 517425f a5f7e84 892e1f4 216705d 517425f 5bbbd48 2d51595 5bbbd48 fa99c44 ef44a19 10c7d1e 5bbbd48 fa99c44 5bbbd48 2ec0e1c 26cfb02 2ec0e1c 26cfb02 2ec0e1c 5bbbd48 96ccd72 5bbbd48 517425f b1238e4 517425f 96ccd72 b73a118 96ccd72 b73a118 96ccd72 b73a118 96ccd72 5bbbd48 517425f 96ccd72 e75f63f 2ec0e1c 96ccd72 b73a118 96ccd72 517425f a5f7e84 96ccd72 271898d 517425f d8e1141 517425f e75f63f 517425f fa99c44 892e1f4 b73a118 892e1f4 517425f 3dae1ad 517425f 10c7d1e 517425f a5f7e84 fa99c44 a5f7e84 517425f 8326e44 10c7d1e 517425f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
import gradio as gr
from parser import parse_resume
# import json
from langchain_docling.loader import ExportType
from langchain_docling import DoclingLoader
def process_file(file_path, resumes):
loader = DoclingLoader(file_path=file_path, export_type=ExportType.MARKDOWN)
job_description = loader.load()[0].page_content
if not job_description.strip() or not resumes:
return "Please provide both job description and at least one resume."
print("[RESUME]", job_description)
print("[CATEGORIES]", resumes)
thinking, results = parse_resume(job_description, resumes)
print("[THINKING]", thinking)
print("[RESULTS]", results)
# results = json.loads(results)
# print("[SUCCESS JSON PARSING]")
return thinking, results
def process_input(job_description, file_upload, resumes):
# resumes = [r for r in resumes if r and r.strip() != ""] # Remove empty
print("[FILE UPLOAD]", file_upload)
if file_upload:
return process_file(file_upload, resumes)
if not job_description.strip() or not resumes:
return "Please provide both job description and at least one resume."
print("[CATEGORIES]", resumes)
thinking, results = parse_resume(job_description, resumes)
print("[THINKING]", thinking)
print("[RESULTS]", results)
# results = json.loads(results)
# print("[SUCCESS JSON PARSING]")
return thinking, results
# results = zip(*parse_resume(job_description, resumes))
# formatted_output = ""
# for i, (resume, score) in enumerate(results, 1):
# formatted_output += f"Resume #{i}:\nScore: {score:.2f}\nResume Snippet: {resume[:200]}...\n\n-------\n\n"
# return formatted_output
initial_parsing = [
{"name":"education", "type":"List[str]","description":"attended school, university, and other education programs"},
{"name":"experience", "type":"int", "description":"years of experience"},
{"name":"skills", "type":"List[str]", "description":"list of skills"},
{"name":"name", "type":"str", "description":"name of the person"},
{"name":"location", "type":"str", "description":"location of the person"},
{"name":"email", "type":"str", "description":"email of the person"},
{"name":"websites", "type":"List[str]", "description":"urls related of the person"},
{"name":"certifications", "type":"List[str]", "description":"list of certifications"},
{"name":"languages", "type":"List[str]", "description":"list of languages"},
{"name":"projects", "type":"List[str]", "description":"list of projects"},
{"name":"note", "type":"str", "description":"additional note which highlight the best or uniqueness of the person"}
]
def toggle_textbox(file):
print("[FILE TOOGLE]", file)
# return gr.Textbox.update(interactive=False if file else True)
is_file = bool(file)
return gr.update(visible=not is_file), gr.update(visible=not is_file), gr.update(visible=is_file)
def update_json(data, name, data_type, desc):
if name:
idx = -1
for i,x in enumerate(data):
if name == x["name"]:
idx = i
break
if idx != -1:
if desc:
data[idx]["description"] = desc
if data_type:
data[idx]["type"] = data_type
elif desc:
data.append(
{"name":name, "type":data_type if data_type else "str", "description":desc}
)
# if name and desc:
# data.append(
# {"name":name, "type":data_type if data_type else "str", "description":desc}
# )
return data
def delete_json(data, name):
for i,x in enumerate(data):
if x["name"] == name:
data.pop(i)
return data
# UI definition
with gr.Blocks() as demo:
gr.Markdown("## π CV / Resume Parsing")
resumes_list = []
with gr.Row():
resume_count = gr.State(2)
with gr.Column():
@gr.render(inputs=resume_count)
def render_count(count):
name = gr.Textbox(
lines=1,
placeholder="Category name",
label="Name"
)
data_type = gr.Textbox(
lines=1,
placeholder="Category data type",
label="Data Type"
)
desc = gr.Textbox(
lines=1,
placeholder="Category description",
label="Description"
)
update_json_button.click(update_json, inputs=[json_display, name, data_type, desc], outputs=json_display)
# resumes_list.append(
# {"name":name, "type":data_type, "description":desc}
# )
# resumes_list.append(name)
# resumes_list.append(data_type)
# resumes_list.append(desc)
# @gr.render(inputs=input_text)
# def add_resume():
# new_input = gr.Textbox(
# lines=6,
# placeholder=f"Paste resume #{len(resumes_list)+1} here...",
# label=f"Resume #{len(resumes_list)+1}"
# )
# resumes_list.append(new_input)
# return resumes_group.update(visible=True)
# add_resume_btn = gr.Button("β Add Another Category")
# add_resume_btn.click(lambda x: x + 1, resume_count, resume_count)
update_json_button = gr.Button("Add / Edit Category")
category_delete = gr.Textbox(
lines=1,
placeholder="Category Name",
label="Remove Category By Name"
)
delete_json_button = gr.Button("Delete Category")
json_display = gr.JSON(value=initial_parsing, label="Parsing Categories", show_label=True)
delete_json_button.click(delete_json, inputs=[json_display, category_delete], outputs=json_display)
with gr.Column():
job_description = gr.Textbox(
lines=16,
placeholder="Paste Resume here...",
label="CV / Resume"
)
file_upload = gr.File(
label="Input Resume File"
)
output = gr.Textbox(
lines=6,
label="Parsing Result",
interactive=False
)
# output = gr.JSON(show_indices=True, label="Parsing Result", show_label=True)
thinking_output = gr.Textbox(
lines=6,
label="Thinking Result",
interactive=False
)
submit_btn_2 = gr.Button("π Parse Resume / CV", visible=False)
submit_btn_2.click(
fn=process_input,
inputs=[job_description, file_upload, json_display],
outputs=[thinking_output, output]
)
submit_btn = gr.Button("π Parse Resume / CV")
submit_btn.click(
fn=process_input,
inputs=[job_description, file_upload, json_display],
outputs=[thinking_output, output]
)
file_upload.change(fn=toggle_textbox, inputs=file_upload, outputs=[job_description, submit_btn, submit_btn_2])
# add_resume_btn.click(add_resume, outputs=resumes_group)
# add_resume_btn.click(lambda x: x + 1, resume_count, resume_count)
demo.launch()
|