import logging
import threading
import fitz # PyMuPDF
import numpy as np
import plotly.graph_objects as go
import streamlit as st
from main import (all_other, education_master, finale, last_score,
logic_actionable_words, logic_similarity_matching2,
main_score, master_score, resume_parsing_2, to_check_exp)
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s', # Log message format
handlers=[logging.StreamHandler()] # Log output to the console
)
country = 'India'
st.title('Resume in PDF and Job Description Input')
uploaded_pdf = st.file_uploader("Upload your Resume", type="pdf")
text_input = st.text_input("Enter the Job Description")
def ensure_all_scores(score_dict, required_keys):
for key in required_keys:
if key not in score_dict:
score_dict[key] = 0
def extract_text_from_pdf(file):
if file is None:
st.error("No file uploaded")
return None
try:
pdf_document = fitz.open(stream=file.read(), filetype="pdf")
text = ""
for page_num in range(len(pdf_document)):
page = pdf_document.load_page(page_num)
text += page.get_text()
return text
except Exception as e:
st.error(f"Error reading PDF: {e}")
return None
def run_thread(target, *args):
try:
thread = threading.Thread(target=target, args=args)
thread.start()
thread.join()
except Exception as e:
st.error(f"Error in {target.__name__}: {e}")
def convert_tuple_to_int(t):
return t[0] if isinstance(t, tuple) and len(t) == 1 else None
if st.button('Scan'):
if uploaded_pdf and text_input:
resume = extract_text_from_pdf(uploaded_pdf)
jd = text_input
if resume and jd:
run_thread(education_master, resume, master_score, country)
run_thread(finale, resume, master_score)
run_thread(resume_parsing_2, resume, master_score)
run_thread(to_check_exp, resume, jd, main_score)
run_thread(logic_actionable_words, resume, master_score)
run_thread(logic_similarity_matching2, resume, jd, master_score)
run_thread(all_other, master_score, uploaded_pdf)
required_master_keys = [
'score_education_detection_', 'score_other',
'similarity_matching_score', 'Action_score'
, 'matrix_score'
]
required_main_keys = ['exp_match','Parsing_score']
ensure_all_scores(master_score, required_master_keys)
ensure_all_scores(main_score, required_main_keys)
all_score = [
master_score['score_education_detection_'],
master_score['score_other'],
master_score['similarity_matching_score'],
master_score['Action_score'],
master_score['matrix_score']
]
if_resume=master_score['Parsing_score'],
work_exp_matches = main_score['exp_match']
scoring = last_score(all_score, work_exp_matches)
if convert_tuple_to_int(if_resume)==1:
logging.info("resume parsed")
if isinstance(scoring,str):
current_value = float(scoring.strip('%'))
else:
current_value = float(scoring)
logging.info(f'final _score {current_value}')
else:
logging.info(f'resumed not parsed score {convert_tuple_to_int(if_resume)}')
current_value=0
st.subheader("Total Score")
plot_bgcolor = 'rgba(0,0,0,0)'
plot_bgcolor = 'rgba(0,0,0,0)'
quadrant_colors = [
plot_bgcolor, "#2bad4e", "#85e043",
"#eff229", "#f2a529", "#f25829"
]
quadrant_text = [
"", "Very high", "High",
"Medium", "Low", "Very low"
]
n_quadrants = len(quadrant_colors) - 1
min_value = 0
max_value = 100
hand_length = 0.25
hand_angle = np.pi * (1 - (current_value - min_value) / (max_value - min_value))
fig = go.Figure(
data=[
go.Pie(
values=[0.5] + (np.ones(n_quadrants) / 2 / n_quadrants).tolist(),
rotation=90,
hole=0.5,
marker_colors=quadrant_colors,
text=quadrant_text,
textinfo="text",
hoverinfo="skip",
),
],
layout=go.Layout(
showlegend=False,
margin=dict(b=20, t=20, l=20, r=20),
width=500,
height=500,
paper_bgcolor=plot_bgcolor,
annotations=[
go.layout.Annotation(
text=f"Score:
{current_value}%",
x=0.5, xanchor="center", xref="paper",
y=0.35, yanchor="bottom", yref="paper",
showarrow=False,
font=dict(size=14, color="#ffffff")
)
],
shapes=[
go.layout.Shape(
type="circle",
x0=0.48, x1=0.52,
y0=0.48, y1=0.52,
fillcolor="#ffffff",
line_color="#ffffff",
),
go.layout.Shape(
type="line",
x0=0.5, x1=0.5 + hand_length * np.cos(hand_angle),
y0=0.5, y1=0.5 + hand_length * np.sin(hand_angle),
line=dict(color="#ffffff", width=4)
)
]
)
)
st.plotly_chart(fig)
st.text("Detailed Scores:")
print(master_score)
master_score.update({'exp_match': main_score['exp_match']})
st.json(master_score)
else:
st.error("Failed to process the inputs. Please try again.")
else:
st.error("Please upload both the Resume and Job Description.")