AI-Screening / src /streamlit_app.py
mdakhras's picture
correct the targeted content from cv to PD
0004adb verified
import streamlit as st
import os
import openai
from dotenv import load_dotenv
import os
from openai import AzureOpenAI
from azure.core.credentials import AzureKeyCredential
# Load environment variables from .env file
load_dotenv()
# Set environment variables for Azure OpenAI
ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT")
API_KEY = os.getenv("AZURE_OPENAI_API_KEY")
DEPLOYMENT_NAME = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME")
API_VERSION = os.getenv("AZURE_OPENAI_API_VERION")
# Check if the necessary environment variables are loaded
if not API_KEY or not ENDPOINT or not DEPLOYMENT_NAME:
st.error("Azure OpenAI credentials are missing. Please check your .env file.")
st.stop()
client = AzureOpenAI(
api_version=API_VERSION,
azure_endpoint=ENDPOINT,
api_key=API_KEY,
)
# Function to extract information from PD using Azure OpenAI GPT-4 model
def extract_PD_info_from_azure(text):
prompt = f"""
Act as an HR recruiter. Carefully evaluate the provided job description (PD) document and extract the following information into the specified structured format. Ensure that all fields are populated. If a field is not explicitly mentioned in the text, use ""N/A"" as the default value.
- Requirements Categories to Extract:
- Location
- Country
- City
- Department
- Required Years of Experience
- Responsibilities
- Skills
- Experience
- Education
- Other Factors
- Languages
PD Text:
{text}
"""
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "You are a helpful assistant.",
},
{
"role": "user",
"content": prompt,
}
],
max_tokens=4096,
temperature=1.0,
top_p=1.0,
model=DEPLOYMENT_NAME
)
try:
result = response.choices[0].message.content
return result
except Exception as e:
st.error(f"Error occurred while contacting Azure OpenAI: {e}")
return None
# Function to extract information from PD using Azure OpenAI GPT-4 model
def extract_criterions_from_azure(text):
prompt = f"""
Act as an HR recruiter. Based on the main criteria categories defined below, extract bullet items from the provided PD text. For each bullet item, create a Criterion Object with the following fields:
Instructions:
- Criterions should represent each item listed under each PD section (Skills,Education, Experience, Other Factors):
1- For each item under PD sections mentioned above, ensure to have related criteria item created to measure it. only skip those items may not relevant or negate a state such as ""There are no extra requirements specified for this position"" .
- PD sections with NA value, dont create Crtierion for it at all.
- Ensure to add Criterions for Languages Proficiency based on its identified level
- Ensure to add Criterions that has clue within the PD to measure it, if no clue in PD, do not consider it.
**Important:**
- Output all Criterion items together under each other as follows, make sure category part formated in bold:
1- Item 1 (Category: Skills)
2- Item 2 (Category: Experience)
PD Text:
{text}
"""
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "You are a helpful assistant.",
},
{
"role": "user",
"content": prompt,
}
],
max_tokens=4096,
temperature=1.0,
top_p=1.0,
model=DEPLOYMENT_NAME
)
try:
result = response.choices[0].message.content
return result
except Exception as e:
st.error(f"Error occurred while contacting Azure OpenAI: {e}")
return None
def extract_weights_from_azure(text):
prompt = f"""
Act as an HR recruiter. Based on the extracted criteria records from the previous step, evaluate the importance of each requirement category type based on provided criteria and assign a weight to it. The weight should reflect how critical the category is for the job, with a score from 1 to 100, ensuring that the sum of all weights does not exceed 100.
Requirements Categories to Evaluate and Assign Weights:
Location (keyword: Location)
Required Years of Experience (keyword: Required_Years_of_Experience)
Responsibilities (keyword: Responsibilities)
Skills (keyword: Skills)
Experience (keyword: Experience)
Education (keyword: Education)
Other Factors (keyword: Other_Factors)
Languages (keyword: Language_Proficiency)
Instructions:
Dynamic Handling of Categories:
**Include categories that have explicit criteria mentioned in the Criterions JSON Content.
**Exclude categories that are not present in the content.
**Adjust the weights dynamically so the sum of all assigned weights does not exceed 100.
Weight Assignment:
**Assign a weight (1–100) to each category based on its importance to the job.
**Distribute weights logically, ensuring critical categories like Skills, Experience, Education, and Language Proficiency are well represented.
**Ensure the sum of all weights, including Extra_Requirement_Three if present, totals exactly 100.
**If the total exceeds or is less than 100, proportionally adjust the weights of the other categories.
Category Justification:
**For each category, provide a detailed justification of its importance, tied to the specific requirements in the job description.
**Explain how the requirements support the assigned weight and their direct relevance to job performance or success.
Final Adjustment Rule:
After assigning initial weights:
** Check if the total weight equals 100.
** If the total is less than 100, proportionally increase the weights of all present categories.
** If the total is more than 100, proportionally decrease the weights of all present categories.
** Preserve explicit weight floors (e.g., Experience greater than or equal to 15%) when adjusting.
** The final output must sum to exactly 100.
Output Format:
**The response must strictly follow below, including the Category_Description for each category.
**Ensure that all categories in the PD criteria are represented in the weights, and no category is missing.
**If Language_Proficiency is found in the criteria, it should have a weight assigned and be included in the output.
**If Extra_Requirement_One is found in the criteria, it should have a weight assigned and be included in the output.
**If Extra_Requirement_Two is found in the criteria, it should have a weight assigned and be included in the output.
**If Extra_Requirement_Three is found in the criteria, it should have a weight assigned and be included in the output.
Example Output:
1- Skills (Weight: 35%): <short description about required skills for this job>
2- Experience (Weight: 25%): <short description about required experiences for this job>
3- Education (Weight: 25%): <short description about required education for this job>
4- Language Proficincy (Weight: 15%): <short description about required languages for this job>
Criterions list:
{text}
"""
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "You are a helpful assistant.",
},
{
"role": "user",
"content": prompt,
}
],
max_tokens=4096,
temperature=1.0,
top_p=1.0,
model=DEPLOYMENT_NAME
)
try:
result = response.choices[0].message.content
return result
except Exception as e:
st.error(f"Error occurred while contacting Azure OpenAI: {e}")
return None
# Streamlit App UI
st.title("AI Screening - Post Description Information Extraction")
st.write("Enter the PD text below, and the agent will extract relevant information such as job title, location, skills, experience, and education, Criterions, Criterion Weights.")
# Text area for entering PD content manually
pd_text = st.text_area("Enter PD Text", height=300)
if pd_text:
# Display the entered PD text
# st.subheader("Entered Text from PD")
# st.text_area("PD Text", pd_text, height=300)
# Extract relevant information using Azure OpenAI GPT-4
extracted_info = extract_PD_info_from_azure(pd_text)
# Display the extracted information
if extracted_info:
st.subheader("Extracted Information")
with st.chat_message("assistant", avatar="πŸ€–"):
st.markdown(
f"<div class='chat-message assistant'>{extracted_info}</div>",
unsafe_allow_html=True,
)
# st.write(extracted_info)
else:
st.write("Could not extract information. Please try again.")
# Extract Criterions
extracted_criterions = extract_criterions_from_azure(extracted_info)
# Display the extracted information
if extracted_criterions:
st.subheader("Extracted Criterion List")
# Immediately display the assistant's response
with st.chat_message("assistant", avatar="πŸ€–"):
st.markdown(
f"<div class='chat-message assistant'>{extracted_criterions}</div>",
unsafe_allow_html=True,
)
# st.write(extracted_criterions)
else:
st.write("Could not extract criterion information. Please try again.")
# Extract Criterions
extracted_weights = extract_weights_from_azure(extracted_criterions)
# Display the extracted information
if extracted_weights:
st.subheader("Extracted Weights List")
with st.chat_message("assistant", avatar="πŸ€–"):
st.markdown(
f"<div class='chat-message assistant'>{extracted_weights}</div>",
unsafe_allow_html=True,
)
# st.write(extracted_weights)
else:
st.write("Could not extract weights information. Please try again.") #