File size: 6,907 Bytes
0e52c2c
 
693b654
6adf9db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4efe666
382ddb8
 
 
 
 
 
 
 
 
4efe666
6adf9db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4efe666
 
6adf9db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d335d2
 
6adf9db
 
 
fd767e5
6adf9db
382ddb8
 
 
 
 
 
 
 
 
 
6adf9db
ce906d2
382ddb8
 
ce906d2
382ddb8
 
 
ce906d2
382ddb8
 
ce906d2
382ddb8
 
ce906d2
382ddb8
4efe666
 
382ddb8
 
 
 
693b654
382ddb8
 
 
693b654
382ddb8
 
30ad011
382ddb8
 
 
30ad011
382ddb8
 
 
30ad011
382ddb8
 
 
 
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
from io import BytesIO

import pandas as pd
import requests
import streamlit as st
import json
from tqdm import tqdm
from openai import AzureOpenAI
import json_repair
import backoff
import os


# API setting constants
API_MAX_RETRY = 5
API_RETRY_SLEEP = 10

class GPTAgent:
    def __init__(self):
        self.client = AzureOpenAI(
            api_key=os.getenv("OPENAI_API_KEY"),
            api_version="2024-02-15-preview",
            azure_endpoint=os.getenv("END_POINTS")
        )

        self.deployment_name = ("gpt-4o-mini")

    @backoff.on_exception(backoff.expo, requests.exceptions.RequestException, max_tries=8)
    def invoke(self, text):


        prompt = """You are a creative recruitment specialist tasked with generating witty and engaging recruitment potshots. Your goal is to craft short, attention-grabbing statements designed to attract potential candidates for job openings. These potshots should be tailored to the role, audience, and company values provided, and should make the job opportunity stand out in a competitive market."""
        temperature = 0.9
        max_tokens = 3500


        response = self.client.chat.completions.create(
            model=self.deployment_name,
            messages=[
                {"role": "system", "content": prompt},
                {"role": "user", "content": text},
            ],
            temperature=temperature,
            max_tokens=max_tokens,
        )

        output = response.choices[0].message.content
        return output



def authenticate_user():
    user_key = st.text_input("Enter your authentication key", type="password")

    if user_key == os.getenv("AUTH_KEY"):
        st.success("Authentication successful!")
        return True
    else:
        st.error("Invalid authentication key. Please try again.")
        return False

def generate_potshot_prompt(batch, role, tone, audience, values):
    prompt = f"""You are a recruitment specialist tasked with generating witty and engaging recruitment potshots.

Your goal is to craft short, attention-grabbing statements designed to attract potential job candidates for the role of {role}. These statements should appeal to {audience} and reflect the company's values: {values}.

Please adopt a tone that is {tone}. Your objective is to make the job opportunity stand out and be highly appealing to the intended audience.

Provide this list of {batch} recruitment potshots in JSON format, for example:
{{"potshots": ["potshot 1", "potshot 2", ..., "potshot n"]}}

Remember to focus on being engaging, playful, and sharp in these recruitment potshots."""
    return prompt.strip()


# Function to get recruitment potshots with customizations
def get_potshots(n_repeat=1, batch=20, role="Developer", tone="humorous", audience="tech-savvy candidates",
                 values="innovation, teamwork"):
    total_potshots = []
    desired_count = n_repeat * batch
    with tqdm(total=desired_count, desc="Generating potshots") as pbar:
        while len(total_potshots) < desired_count:
            needed = min(batch, desired_count - len(total_potshots))
            prompt = generate_potshot_prompt(batch=needed, role=role, tone=tone, audience=audience, values=values)
            gpt_agent = GPTAgent()
            response = gpt_agent.invoke(prompt)
            try:
                batch_potshots = json.loads(response).get("potshots", [])
                total_potshots.extend(batch_potshots)
                pbar.update(len(batch_potshots))
            except json.JSONDecodeError:
                # Attempt to repair the JSON if decoding fails
                try:
                    repaired_json = json_repair.repair_json(response, skip_json_loads=True, return_objects=False)
                    batch_potshots = json.loads(repaired_json).get("potshots", [])
                    total_potshots.extend(batch_potshots)
                    pbar.update(len(batch_potshots))
                except json.JSONDecodeError:
                    st.error("Failed to decode JSON response even after repair attempt. Skipping this batch.")

    if len(total_potshots) > desired_count:
        total_potshots = total_potshots[:desired_count]

    df = pd.DataFrame([{"potshot": potshot, "role": role, "tone": tone, "audience": audience, "values": values} for potshot in total_potshots])
    return df


# Streamlit App Interface
st.title("Recruiting Potshots Generator")

if authenticate_user():

    # Input Fields for Customization
    # Input Fields for Full Customization with Default Values
    role = st.text_input("Job Role", value="Developer", help="Enter the job role you are recruiting for. Default is 'Developer'.")
    tone = st.text_input("Tone of the Potshots", value="humorous", help="Enter any tone for the potshots (e.g., humorous, serious, edgy). Default is 'humorous'.")
    audience = st.text_input("Target Audience", value="tech-savvy candidates", help="Define the target audience for the potshots. Default is 'tech-savvy candidates'.")
    values = st.text_area("Company Values", value="innovation, teamwork, transparency", help="Enter your company values that should be reflected in the potshots. Default is 'innovation, teamwork, transparency'.")
    batch_size = st.number_input("Batch Size", min_value=1, max_value=100, value=10)
    repeat_times = st.number_input("Number of Batches", min_value=1, max_value=10, value=1)


    def to_excel(df):
        output = BytesIO()

        # Use the 'with' statement to handle the file writer and ensure proper closure
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, index=False, sheet_name='Potshots')

        # Get the processed data from the buffer
        processed_data = output.getvalue()

        # Reset the buffer for safety (useful if this is reused)
        output.seek(0)

        return processed_data


    if st.button("Generate Potshots"):
        with st.spinner("Generating customized potshots..."):
            df = get_potshots(n_repeat=repeat_times, batch=batch_size, role=role, tone=tone, audience=audience,
                              values=values)

            # Display the generated potshots as a table
            st.write("### Generated Potshots")
            st.dataframe(df)

            excel_data = to_excel(df)
            file_name = "potshots.xlsx"

            # Open and read the file to serve for download
            with open(file_name, "wb") as f:
                f.write(excel_data)

            # Provide a download button for the Excel file
            with open(file_name, "rb") as template_file:
                template_byte = template_file.read()

            st.download_button(label="Click to Download Potshots File",
                               data=template_byte,
                               file_name="potshots.xlsx",
                               mime='application/octet-stream')