UnivAI001
initial commit - AI automation agents
6798e8f
Raw
History Blame Contribute Delete
3.34 kB
import gradio as gr
import pdfplumber
from fetcher import fetch_jobs
from formatter import format_jobs
from cover_letter import generate_cover_letter
# store jobs globally so cover letter tab can access them
job_store = []
def read_cv(cv_file):
if cv_file is None:
return ""
try:
with pdfplumber.open(cv_file.name) as pdf:
text = ""
for page in pdf.pages:
text += page.extract_text() or ""
return text
except Exception as e:
return f"Could not read CV: {e}"
def search_jobs(job_title):
global job_store
jobs = fetch_jobs(job_title)
job_store = jobs
if not jobs:
return "No jobs found. Try a broader search term."
formatted = format_jobs(jobs, job_title, "")
return formatted
def create_cover_letter(job_number, cv_file):
global job_store
cv_text = read_cv(cv_file)
if not cv_text:
return "Please upload your CV first."
if not job_store:
return "Please search for jobs first."
try:
index = int(job_number) - 1
job = job_store[index]
except Exception:
return "Invalid job number. Please enter a number from the job results."
return generate_cover_letter(
job["title"],
job["company"],
job["description"],
cv_text
)
with gr.Blocks(title="AI Job Finder Agent") as ui:
gr.Markdown("# 🤖 AI Job Finder Agent")
gr.Markdown("Find remote jobs and generate tailored cover letters from your CV")
with gr.Tab("🔍 Find Jobs"):
job_input = gr.Textbox(
label="What role are you looking for?",
placeholder="e.g. Python Developer, Designer, Data Analyst..."
)
search_btn = gr.Button("Find Jobs", variant="primary")
job_results = gr.Markdown()
status_text = gr.Textbox(label="Status", interactive=False, value="Idle")
def search_jobs_with_status(job_title):
if not job_title or not job_title.strip():
return "", "Please enter a search query."
return search_jobs(job_title), "Search completed"
search_btn.click(
fn=search_jobs_with_status,
inputs=[job_input],
outputs=[job_results, status_text]
)
with gr.Tab("✉️ Generate Cover Letter"):
gr.Markdown("Upload your CV and enter the job number from the search results")
cv_upload = gr.File(label="Upload CV (PDF)", file_types=[".pdf"])
job_number = gr.Textbox(
label="Job Number",
placeholder="e.g. 1, 2, 3..."
)
cl_btn = gr.Button("Generate Cover Letter", variant="primary")
cl_output = gr.Markdown()
cl_status = gr.Textbox(label="Status", interactive=False, value="Idle")
def create_cover_letter_with_status(job_number, cv_file):
if not job_number or not str(job_number).isdigit():
return "", "Invalid job number"
if not cv_file:
return "", "Upload CV first"
return create_cover_letter(job_number, cv_file), "Cover letter generated"
cl_btn.click(
fn=create_cover_letter_with_status,
inputs=[job_number, cv_upload],
outputs=[cl_output, cl_status]
)
ui.launch()