Ahmad-Moiz commited on
Commit
d0b1771
1 Parent(s): e624046

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -46
app.py CHANGED
@@ -1,14 +1,24 @@
1
  import streamlit as st
 
2
  from pathlib import Path
3
  from typing import Any, Dict, List, Optional
 
 
4
  from llama_index.llms.base import LLM
5
  from llama_index.llms import OpenAI
6
- from llama_index.readers import PDFReader
7
- from llama_index.llama_pack.base import BaseLlamaPack
8
  from llama_index.schema import NodeWithScore
9
  from llama_index.response_synthesizers import TreeSummarize
10
- from pydantic import BaseModel, Field
11
- from llama_index.service_context import ServiceContext
 
 
 
 
 
 
 
 
12
 
13
  QUERY_TEMPLATE = """
14
  You are an expert resume reviewer.
@@ -21,27 +31,16 @@ Your job is to decide if the candidate passes the resume screen given the job de
21
  {criteria_str}
22
  """
23
 
24
-
25
  class CriteriaDecision(BaseModel):
26
  """The decision made based on a single criterion"""
27
-
28
- decision: bool = Field(description="The decision made based on the criterion")
29
- reasoning: str = Field(description="The reasoning behind the decision")
30
-
31
 
32
  class ResumeScreenerDecision(BaseModel):
33
  """The decision made by the resume screener"""
34
-
35
- criteria_decisions: List[CriteriaDecision] = Field(
36
- description="The decisions made based on the criteria"
37
- )
38
- overall_reasoning: str = Field(
39
- description="The reasoning behind the overall decision"
40
- )
41
- overall_decision: bool = Field(
42
- description="The overall decision made based on the criteria"
43
- )
44
-
45
 
46
  def _format_criteria_str(criteria: List[str]) -> str:
47
  criteria_str = ""
@@ -49,16 +48,12 @@ def _format_criteria_str(criteria: List[str]) -> str:
49
  criteria_str += f"- {criterion}\n"
50
  return criteria_str
51
 
52
-
53
  class ResumeScreenerPack(BaseLlamaPack):
54
- def __init__(
55
- self,
56
- job_description: str,
57
- criteria: List[str],
58
- llm: Optional[LLM] = None,
59
  ) -> None:
60
  self.reader = PDFReader()
61
- llm = llm or OpenAI(model="gpt-4")
62
  service_context = ServiceContext.from_defaults(llm=llm)
63
  self.synthesizer = TreeSummarize(
64
  output_cls=ResumeScreenerDecision, service_context=service_context
@@ -81,25 +76,44 @@ class ResumeScreenerPack(BaseLlamaPack):
81
  )
82
  return output.response
83
 
84
-
85
  def main():
86
- st.title("Resume Screener")
87
 
 
88
  job_description = st.text_area("Job Description")
89
- criteria = st.text_area("Screening Criteria (Separate by new lines)")
90
-
91
- criteria_list = criteria.split('\n') if criteria else []
92
-
93
- def run_resume_screener(resume_path):
94
- screener = ResumeScreenerPack(job_description, criteria_list)
95
- output = screener.run(resume_path)
96
- st.json(output) # Displaying JSON output for example
97
-
98
- uploaded_file = st.file_uploader("Upload a resume", type=['pdf'])
99
-
100
- if uploaded_file:
101
- st.write("Resume uploaded!")
102
- run_resume_screener(uploaded_file)
103
-
104
- if __name__ == "__main__":
105
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ from dotenv import load_dotenv
3
  from pathlib import Path
4
  from typing import Any, Dict, List, Optional
5
+ from llama_index.llama_pack.base import BaseLlamaPack
6
+ from llama_index.readers import PDFReader
7
  from llama_index.llms.base import LLM
8
  from llama_index.llms import OpenAI
9
+ from llama_index import ServiceContext
 
10
  from llama_index.schema import NodeWithScore
11
  from llama_index.response_synthesizers import TreeSummarize
12
+ from pydantic import BaseModel
13
+ import os
14
+ import pdfplumber
15
+ import io
16
+
17
+ # Load environment variables from .env file
18
+ load_dotenv()
19
+
20
+ # Get OpenAI API key from environment variables
21
+ openai_api_key = os.getenv("OPENAI_API_KEY")
22
 
23
  QUERY_TEMPLATE = """
24
  You are an expert resume reviewer.
 
31
  {criteria_str}
32
  """
33
 
 
34
  class CriteriaDecision(BaseModel):
35
  """The decision made based on a single criterion"""
36
+ decision: bool
37
+ reasoning: str
 
 
38
 
39
  class ResumeScreenerDecision(BaseModel):
40
  """The decision made by the resume screener"""
41
+ criteria_decisions: List[CriteriaDecision]
42
+ overall_reasoning: str
43
+ overall_decision: bool
 
 
 
 
 
 
 
 
44
 
45
  def _format_criteria_str(criteria: List[str]) -> str:
46
  criteria_str = ""
 
48
  criteria_str += f"- {criterion}\n"
49
  return criteria_str
50
 
 
51
  class ResumeScreenerPack(BaseLlamaPack):
52
+ def _init_(
53
+ self, job_description: str, criteria: List[str], llm: Optional[LLM] = None
 
 
 
54
  ) -> None:
55
  self.reader = PDFReader()
56
+ llm = llm or OpenAI(model="gpt-4", api_key=openai_api_key)
57
  service_context = ServiceContext.from_defaults(llm=llm)
58
  self.synthesizer = TreeSummarize(
59
  output_cls=ResumeScreenerDecision, service_context=service_context
 
76
  )
77
  return output.response
78
 
 
79
  def main():
80
+ st.title("Resume Screener App")
81
 
82
+ # Sidebar for user input
83
  job_description = st.text_area("Job Description")
84
+ criteria = st.text_area("Screening Criteria (separate each criterion by a new line)")
85
+
86
+ uploaded_file = st.file_uploader("Upload Resume (PDF)", type=["pdf"])
87
+
88
+ if st.button("Submit"):
89
+ if job_description and criteria and uploaded_file:
90
+ resume_text = extract_text_from_pdf(uploaded_file)
91
+
92
+ screener_pack = ResumeScreenerPack(job_description=job_description, criteria=criteria.split("\n"))
93
+
94
+ with st.spinner("Analyzing the resume..."):
95
+ result = screener_pack.run(resume_text)
96
+
97
+ st.subheader("Screening Results")
98
+ st.json(result)
99
+
100
+ def extract_text_from_pdf(uploaded_file):
101
+ if uploaded_file is not None:
102
+ try:
103
+ # Read PDF content from BytesIO
104
+ uploaded_content = io.BytesIO(uploaded_file.read())
105
+
106
+ with pdfplumber.open(uploaded_content) as pdf:
107
+ text = ""
108
+ for page in pdf.pages:
109
+ text += page.extract_text()
110
+ return text
111
+ except Exception as e:
112
+ st.error(f"Error extracting text from PDF: {str(e)}")
113
+ return ""
114
+ else:
115
+ st.error("Please upload a PDF file.")
116
+ return ""
117
+
118
+ if _name_ == "_main_":
119
+ main()