Spaces:
Runtime error
Runtime error
import gradio as gr | |
import requests | |
import os | |
# Load API keys securely from environment variables | |
proxycurl_api_key = os.getenv("PROXYCURL_API_KEY") # Add your Proxycurl API key to your environment variables | |
groq_api_key = os.getenv("GROQ_CLOUD_API_KEY") | |
# Function to use Proxycurl API to get the LinkedIn profile data | |
def get_linkedin_profile_via_proxycurl(linkedin_profile_url): | |
headers = { | |
"Authorization": f"Bearer {proxycurl_api_key}", | |
} | |
url = f"https://nubela.co/proxycurl/api/v2/linkedin?url={linkedin_profile_url}" | |
response = requests.get(url, headers=headers) | |
if response.status_code == 200: | |
data = response.json() | |
# Extract relevant skills and experiences from LinkedIn profile | |
bio = data.get("summary", "No bio available") | |
skills = data.get("skills", []) # List of skills from the LinkedIn profile | |
experiences = data.get("experiences", []) # List of experiences from the LinkedIn profile | |
return bio, skills, experiences | |
else: | |
return "Error: Unable to fetch LinkedIn profile", [], [] | |
# Function to get company information via Proxycurl Company API | |
def get_company_info(company_name): | |
headers = { | |
"Authorization": f"Bearer {proxycurl_api_key}", | |
} | |
url = f"https://nubela.co/proxycurl/api/v2/linkedin/company?company_name={company_name}" | |
response = requests.get(url, headers=headers) | |
if response.status_code == 200: | |
data = response.json() | |
company_info = data.get("description", "No detailed company info available.") | |
return company_info | |
else: | |
return "Error: Unable to fetch company information." | |
# Placeholder for role description; could be enhanced to scrape or fetch real role data | |
def get_role_description(role_name, company_name): | |
return f"The role of {role_name} at {company_name} involves..." | |
# Helper function to call Groq Cloud LLM API to generate and correct the email | |
def generate_and_correct_email(bio, company_name, role, company_info, role_description, skills, experiences): | |
url = "https://api.groq.com/openai/v1/chat/completions" | |
headers = { | |
"Authorization": f"Bearer {groq_api_key}", | |
"Content-Type": "application/json", | |
} | |
# New, detailed prompt with emphasis on correlating LinkedIn skills and experience to the job role | |
prompt = f""" | |
Write a professional email applying for the {role} position at {company_name}. | |
The candidate’s bio is: {bio}. | |
The candidate's LinkedIn profile highlights the following skills: {', '.join(skills)}. | |
The candidate has the following experiences relevant to the job: {', '.join([exp['title'] for exp in experiences])}. | |
The email should: | |
- Be professional, engaging, and customized to the company's culture and the role’s requirements. | |
- Include relevant company details: {company_info}. | |
- Highlight the candidate’s skills and experiences from LinkedIn, mapping them directly to the job's requirements. The role description is: {role_description}. | |
- Emphasize how the candidate’s background aligns with the company’s values and mission. | |
- Attract the company's attention by focusing on how the candidate's background can bring value to the role and the company's future goals. | |
- Use a tone that is persuasive but not overly promotional. | |
- End with a strong call to action, encouraging the company to schedule an interview to discuss how the candidate can contribute to their success. | |
Structure the email as follows: | |
1. **Introduction**: Briefly introduce the candidate and state the role they are applying for. | |
2. **Skills & Experience**: Map the candidate’s skills and experience from LinkedIn to the job's key requirements. | |
3. **Alignment with the Company**: Emphasize how the candidate’s background fits with the company's mission, values, and goals. | |
4. **Call to Action**: Encourage the company to schedule an interview to further discuss the candidate’s fit for the role. | |
Ensure that redundant sign-offs like 'Best regards' or 'Sincerely' are not included. | |
""" | |
# Construct the data payload for the API request | |
data = { | |
"messages": [ | |
{ | |
"role": "user", | |
"content": prompt | |
} | |
], | |
"model": "llama3-8b-8192" | |
} | |
response = requests.post(url, headers=headers, json=data) | |
if response.status_code == 200: | |
return response.json()["choices"][0]["message"]["content"].strip() | |
else: | |
print(f"Error: {response.status_code}, {response.text}") | |
return "Error generating email. Please check your API key or try again later." | |
# Main function to create the email and allow for saving, editing, or copying | |
def create_email(name, company_name, role, email, phone, linkedin_profile_url): | |
# Step 1: Fetch LinkedIn profile using Proxycurl API if LinkedIn URL is provided | |
if linkedin_profile_url: | |
bio, skills, experiences = get_linkedin_profile_via_proxycurl(linkedin_profile_url) | |
else: | |
bio = f"{name} is a professional." # Default bio if no LinkedIn URL is provided | |
skills, experiences = [], [] | |
# Step 2: Fetch company information and role description | |
company_info = get_company_info(company_name) | |
role_description = get_role_description(role, company_name) | |
# Step 3: Generate the email using Groq Cloud LLM | |
generated_email = generate_and_correct_email(bio, company_name, role, company_info, role_description, skills, experiences) | |
# Step 4: Add the user's email, phone number, and LinkedIn profile to the signature | |
signature = f"\n\nBest regards,\n{name}\nEmail: {email}\nPhone: {phone}\nLinkedIn: {linkedin_profile_url if linkedin_profile_url else 'Not provided'}" | |
# Ensure the body doesn't include any redundant 'Best regards' or 'Sincerely' and just append our signature | |
for phrase in ["Best regards", "Sincerely"]: | |
if phrase in generated_email: | |
generated_email = generated_email.split(phrase)[0].strip() | |
# Return the final polished email with the signature | |
return generated_email + signature | |
# Define interface with Gradio | |
def gradio_ui(): | |
# Define inputs | |
name_input = gr.Textbox(label="Name", placeholder="Enter your name") | |
company_name_input = gr.Textbox(label="Company Name", placeholder="Enter the name of the company you are applying to") | |
role_input = gr.Textbox(label="Role", placeholder="Enter the role you are applying for") | |
email_input = gr.Textbox(label="Email Address", placeholder="Enter your email address") | |
phone_input = gr.Textbox(label="Phone Number", placeholder="Enter your phone number") | |
linkedin_input = gr.Textbox(label="LinkedIn URL", placeholder="Enter your LinkedIn profile URL") # New field for LinkedIn URL | |
# Define output for the generated email | |
email_output = gr.Textbox(label="Generated Email", placeholder="Your generated email will appear here", lines=10) | |
# Create the Gradio interface | |
demo = gr.Interface( | |
fn=create_email, # Function to call when the user submits | |
inputs=[name_input, company_name_input, role_input, email_input, phone_input, linkedin_input], | |
outputs=[email_output], | |
title="Email Writing AI Agent", | |
description="Generate a professional email for a job application by providing your basic info.", | |
allow_flagging="never" # Disable flagging | |
) | |
# Launch the Gradio app | |
demo.launch() | |
# Start the Gradio app when running the script | |
if __name__ == "__main__": | |
gradio_ui() | |