resume / app.py
LALAa11's picture
Create app.py
d4c397a verified
raw
history blame
3.64 kB
import os
import gradio as gr
import requests
from huggingface_hub import InferenceClient
# Load Gemini API key from environment variable
GEMINI_API_KEY = os.getenv("GOOGLE_AI_API_KEY")
HF_API_KEY = os.getenv("HUGGINGFACE_API_KEY") # optional if private model
# Hugging Face Client (free model, no API key needed for public models)
hf_client = InferenceClient(model="HuggingFaceH4/zephyr-7b-beta")
def generate_with_huggingface(resume_text, job_desc):
prompt = f"""
You are an expert career assistant.
Resume:
{resume_text}
Job Description:
{job_desc}
Task:
1. Create a customized resume version highlighting relevant skills and achievements.
2. Write a professional cover letter tailored for this role.
"""
response = hf_client.text_generation(
prompt,
max_new_tokens=800,
temperature=0.7,
)
return response
def call_gemini_api(resume_text, job_desc):
if not GEMINI_API_KEY:
return None # force fallback
prompt = f"""
You are an expert career assistant.
Resume:
{resume_text}
Job Description:
{job_desc}
Task:
1. Create a customized resume version highlighting relevant skills and achievements.
2. Write a professional cover letter tailored for this role.
"""
url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent"
headers = {
"Content-Type": "application/json",
"X-goog-api-key": GEMINI_API_KEY,
}
data = {
"contents": [
{"parts": [{"text": prompt}]}
]
}
try:
response = requests.post(url, headers=headers, json=data, timeout=30)
result = response.json()
if "candidates" in result:
output_text = result["candidates"][0]["content"]["parts"][0]["text"]
return output_text
else:
return None
except Exception:
return None
def generate_documents(resume_text, job_desc):
# Try Gemini first
gemini_output = call_gemini_api(resume_text, job_desc)
if gemini_output:
output_text = gemini_output
source = "βœ… Google Gemini"
else:
output_text = generate_with_huggingface(resume_text, job_desc)
source = "⚠️ Gemini failed β†’ Using Hugging Face LLM"
# Split Resume + Cover Letter
if "Cover Letter" in output_text:
parts = output_text.split("Cover Letter")
resume_out = parts[0].strip()
cover_letter_out = "Cover Letter" + parts[1].strip()
else:
resume_out = output_text
cover_letter_out = ""
return resume_out + f"\n\n(Source: {source})", cover_letter_out
# Gradio UI
with gr.Blocks(title="AI Resume & Cover Letter Generator") as demo:
gr.Markdown("# πŸ“„ AI Resume & Cover Letter Generator")
gr.Markdown("Upload your resume or paste LinkedIn profile + Job description, and get customized documents.\
\n(Default: Gemini, fallback: Hugging Face LLM)")
with gr.Row():
resume_input = gr.Textbox(label="Paste Resume / LinkedIn profile", lines=10, placeholder="Paste your resume text here...")
job_input = gr.Textbox(label="Paste Job Description", lines=8, placeholder="Paste job description here...")
generate_btn = gr.Button("✨ Generate Resume & Cover Letter")
with gr.Row():
resume_output = gr.Textbox(label="Customized Resume", lines=15)
cover_output = gr.Textbox(label="Cover Letter", lines=15)
generate_btn.click(generate_documents, inputs=[resume_input, job_input], outputs=[resume_output, cover_output])
demo.launch()