ChaitanyaSubhakar commited on
Commit
f5358a9
Β·
verified Β·
1 Parent(s): 7ff9374

Create Home.py

Browse files
Files changed (1) hide show
  1. Home.py +130 -0
Home.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import zipfile
3
+ from pathlib import Path
4
+ import streamlit as st
5
+ from langchain_community.document_loaders import UnstructuredPDFLoader
6
+ from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace
7
+ from langchain.prompts import PromptTemplate
8
+ from langchain_core.output_parsers import PydanticOutputParser
9
+ from pydantic import BaseModel, Field
10
+
11
+ st.markdown(
12
+ """
13
+ <style>
14
+ .stApp {
15
+ background-color: midnightblue;
16
+ color: white;
17
+ }
18
+ </style>
19
+ """,
20
+ unsafe_allow_html=True
21
+ )
22
+
23
+ # Setup your HF token and model (replace with your token handling)
24
+ newhf = st.secrets["HF_TOKEN"]
25
+
26
+ # Create folders if not present
27
+ Path("Extracted_Resumes").mkdir(exist_ok=True)
28
+ Path("Selected_Resumes").mkdir(exist_ok=True)
29
+
30
+ # Set up the LLaMA model
31
+ llama_model = HuggingFaceEndpoint(
32
+ repo_id="meta-llama/Llama-3.1-8B-Instruct",
33
+ provider="nebius",
34
+ temperature=0.7,
35
+ api_key=newhf,
36
+ max_new_tokens=512,
37
+ task="conversational"
38
+ )
39
+
40
+ model = ChatHuggingFace(
41
+ llm=llama_model,
42
+ repo_id="meta-llama/Llama-3.1-8B-Instruct",
43
+ provider="nebius",
44
+ temperature=0.7,
45
+ api_key=newhf,
46
+ max_new_tokens=512,
47
+ task="conversational"
48
+ )
49
+
50
+ # Pydantic schema for parsing resume content
51
+ class JobDesc(BaseModel):
52
+ Objective: str = Field(description="Objective")
53
+ Name: str = Field(description="Name")
54
+ Age: int = Field(description="Age")
55
+ Qualification: str = Field(description="Qualification")
56
+ Skills: list[str] = Field(description="Skills")
57
+ Experience: float = Field(description="Work Experience")
58
+
59
+ parser = PydanticOutputParser(pydantic_object=JobDesc)
60
+
61
+ # Prompt template for extracting fields from resume
62
+ pt = PromptTemplate(template="""
63
+ Extract the following fields from the resume description below and return them as a JSON object.
64
+
65
+ Resume Text:
66
+ {input}
67
+
68
+ Return JSON matching this format exactly:
69
+ {instruction}
70
+ """)
71
+
72
+ # Streamlit app UI
73
+ st.title("πŸ“„ Resume Screening Application")
74
+
75
+ uploaded_zip = st.file_uploader("Upload a ZIP file containing resumes", type="zip")
76
+
77
+ if uploaded_zip:
78
+ with zipfile.ZipFile(uploaded_zip, "r") as zip_ref:
79
+ zip_ref.extractall("Extracted_Resumes")
80
+ st.success("βœ… Resumes extracted successfully!")
81
+
82
+ resumes = list(Path("Extracted_Resumes").glob("*.pdf"))
83
+ valid_resumes = []
84
+
85
+ # Check for 2-page resumes
86
+ for pdf in resumes:
87
+ try:
88
+ loader = UnstructuredPDFLoader(str(pdf), mode="paged")
89
+ pages = loader.load()
90
+ if len(pages) == 2:
91
+ valid_resumes.append((pdf.name, pages))
92
+ except Exception as e:
93
+ st.warning(f"❌ Could not process {pdf.name}: {e}")
94
+
95
+ if valid_resumes:
96
+ st.subheader("πŸ”Ž Select Required Skills")
97
+
98
+ # Extract skills from all resumes
99
+ all_resume_skills = set()
100
+
101
+ parsed_resumes = {}
102
+
103
+ for filename, pages in valid_resumes:
104
+ final_data = [page for page in pages]
105
+ fp = pt.format(input=final_data, instruction=parser.get_format_instructions())
106
+ result = model.invoke(fp)
107
+ parsed_resume = parser.parse(result.content)
108
+ parsed_resumes[filename] = parsed_resume
109
+ all_resume_skills.update(map(str.lower, parsed_resume.Skills))
110
+
111
+ selected_skills = st.multiselect("Choose required skills:", sorted(all_resume_skills))
112
+
113
+ # Match resumes based on selected skills
114
+ for filename, parsed_resume in parsed_resumes.items():
115
+ resume_skills = parsed_resume.Skills
116
+ found_skills = [
117
+ skill for skill in selected_skills
118
+ if any(skill.lower() in rs.lower() for rs in resume_skills)
119
+ ]
120
+
121
+ if set(found_skills) == set(selected_skills):
122
+ src_path = Path("Extracted_Resumes") / filename
123
+ dest_path = Path("Selected_Resumes") / filename
124
+ with open(src_path, "rb") as src, open(dest_path, "wb") as dst:
125
+ dst.write(src.read())
126
+ st.success(f"βœ… {filename} matches and saved to 'Selected_Resumes'")
127
+ else:
128
+ st.info(f"ℹ️ {filename} does not match all selected skills.")
129
+ else:
130
+ st.warning("⚠️ No 2-page resumes found.")