File size: 4,594 Bytes
da138ab
 
 
e07276a
da138ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d18155
da138ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# import packages
import streamlit as st
import os
from utils import load_file, plot_similarity_scores
from constants import StreamlitException

from nlp import (
    clean_text, split_text, summarize_text,
    extract_person_names_and_email, extract_tech_skills,
    calculate_similarity, qna_query, lang_model
)

from constants import API_TOKEN, VESRION
os.environ["HUGGINGFACEHUB_API_TOKEN"] = API_TOKEN

def process_exception(e):
    st.error(e.message)
    st.stop()


if __name__ == "__main__":
    # Set page width to a larger size
    st.set_page_config(layout="wide")

    # Streamlit app UI
    st.write(
        """<h1 style='display: inline-block; color: black;'>ResuMate</h1> 
        <h3 style='display: inline-block; color: grey'>πŸš€ Transforming the recruitment and staffing experience through Generative AI </h3>""", 
        unsafe_allow_html=True
    )
    st.write("")
    st.write("")

    st.sidebar.write("")
    with st.sidebar.expander("πŸ€– About", expanded=False):
        st.write("This app is powered by free and open-source **Langchain** and **LLM technology**.")
        st.write("Developed by **[Chandramauli Chaudhuri](https://www.linkedin.com/in/chandramaulic/)**.")
        st.write("")
        st.write(f"Version **{VESRION}**.")

    # Upload a file, share job description and summarize its content
    #st.sidebar.write("")
    st.sidebar.header("User Inputs")
    #st.sidebar.write("")
    job_description_raw = st.sidebar.text_area("Enter the job description:")
    #st.sidebar.write("")
    job_description = clean_text(job_description_raw)
    #st.write("")

    uploaded_file = st.sidebar.file_uploader("Upload a resume:", type=["docx", "pdf", "ppt", "pptx"])
    #st.sidebar.write("")

    # Spinner set-up  
    with st.spinner("Details loading, please wait.."):
        if uploaded_file is not None:
            load_file_result = load_file(st, uploaded_file)
            if type(load_file_result) is StreamlitException:
                process_exception(load_file_result)
            else:
                resume_text_raw, lang_loader = load_file_result

            resume_text = clean_text(resume_text_raw)
            doc = lang_model(resume_text)
            
            st.subheader("πŸ“ƒ Overview")
            st.write("")

            # Set up candidate name & email extraction
            person_names, emails = extract_person_names_and_email(resume_text)
            st.write("**Candidate's name:** " + ", ".join(person_names))
            st.write("")
            st.write("**Candidate's email address:** " + ", ".join(emails))
            st.write("")

            # Set up job description summarization
            summarization_result = summarize_text(job_description)
            if type(summarization_result) is StreamlitException:
                process_exception(summarization_result)
            else:
                st.write("**Job description summary:** " + summarization_result)
            st.write("")

            # Set up resume summarization
            summarization_result = summarize_text(resume_text)
            if type(summarization_result) is StreamlitException:
                process_exception(summarization_result)
            else:
                st.write("**Candidate's resume summary:** " + summarization_result)
            st.write("")
            
            st.write("")
            st.subheader("πŸ” Fitment")
            st.write("")

            # Set up technical skill extraction
            st.write("**Candidate's key technical skills:** " + ", ".join(extract_tech_skills(doc)))
            st.write("")

            # Set up percentage match calculation
            st.write("**Percentage match between job description and candidate's resume:** " + f"{calculate_similarity(job_description, resume_text):.2f}%" + "\n")
            st.write("")
            
            # Set up percentage match calculation at sentence level
            job_description_phrases = split_text(job_description)
            resume_phrases = split_text(resume_text)
            st.write('**Percentage resume match against TOP 10 job description items:**')
            if job_description_raw != '':           
                fig = plot_similarity_scores(job_description_phrases, resume_phrases)
                st.plotly_chart(fig, use_container_width=True)

            # Set up user Q&A
            user_input = st.sidebar.text_input("Ask any other resume-related questions:", "")
            if user_input:
                answer = qna_query(lang_loader, user_input)
                st.sidebar.write(answer)