Sazzz02 commited on
Commit
2b98632
·
verified ·
1 Parent(s): 90b4a83

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -0
app.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import sys
4
+ import uuid
5
+ import tempfile
6
+ import chromadb
7
+ from langchain_groq import ChatGroq
8
+ from langchain_community.document_loaders import WebBaseLoader, UnstructuredFileLoader
9
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
10
+ from langchain_core.prompts import PromptTemplate
11
+
12
+ # Get API key from Hugging Face Secrets
13
+ GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
14
+
15
+ def generate_content(resume_file, job_url):
16
+ """
17
+ Main function to generate the cover letter.
18
+ """
19
+ if not GROQ_API_KEY:
20
+ return "❌ Error: Groq API key is not set in Hugging Face secrets. Please add it to your Space settings."
21
+ if not resume_file:
22
+ return "❌ Error: Please upload a resume."
23
+ if not job_url:
24
+ return "❌ Error: Please provide a job description URL."
25
+
26
+ # --- 1. Validate Groq API Key ---
27
+ try:
28
+ llm = ChatGroq(
29
+ temperature=0,
30
+ groq_api_key=GROQ_API_KEY,
31
+ model_name="llama3-70b-8192"
32
+ )
33
+ llm.invoke("Test LLM connection.")
34
+ except Exception as e:
35
+ return f"❌ Error: Invalid Groq API key or model unavailable. Details: {e}"
36
+
37
+ # --- 2. Process Resume ---
38
+ try:
39
+ # Gradio's File component provides a NamedTemporaryFile
40
+ loader = UnstructuredFileLoader(resume_file.name)
41
+ resume_text = loader.load()[0].page_content
42
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
43
+ resume_chunks = text_splitter.split_text(resume_text)
44
+ except Exception as e:
45
+ return f"❌ Error processing the resume file. Ensure it's a valid PDF. Error: {e}"
46
+
47
+ # --- 3. Set up the Resume Vector Database ---
48
+ client = chromadb.PersistentClient('resume_vectorstore')
49
+ collection = client.get_or_create_collection(name="resume_content")
50
+
51
+ # Clear old data before adding new
52
+ if collection.count() > 0:
53
+ collection.delete(ids=collection.get()['ids'])
54
+
55
+ ids = [str(uuid.uuid4()) for _ in range(len(resume_chunks))]
56
+ collection.add(documents=resume_chunks, ids=ids)
57
+
58
+ # --- 4. Web Scraping and JD Extraction ---
59
+ try:
60
+ loader = WebBaseLoader(job_url)
61
+ jd_text = loader.load().pop().page_content
62
+ except Exception as e:
63
+ return f"❌ Error scraping the URL. Please check the URL. Error: {e}"
64
+
65
+ prompt_extract = PromptTemplate.from_template(
66
+ """### SCRAPED TEXT FROM WEBSITE: {page_data}
67
+ ### INSTRUCTION: Extract key skills, technologies, and responsibilities.
68
+ Return them as a list of strings. ### OUTPUT:"""
69
+ )
70
+ chain_extract = prompt_extract | llm
71
+ jd_requirements = chain_extract.invoke(input={'page_data': jd_text}).content.split('\n')
72
+
73
+ # --- 5. Find Relevant Resume Content ---
74
+ relevant_resume_chunks = collection.query(
75
+ query_texts=jd_requirements,
76
+ n_results=5
77
+ ).get('documents', [])
78
+
79
+ # --- 6. Generate Cover Letter/Resume Content ---
80
+ prompt_content = PromptTemplate.from_template(
81
+ """### JOB REQUIREMENTS: {jd_requirements}
82
+ ### YOUR RESUME CONTENT: {resume_content}
83
+ ### INSTRUCTION: You are a career consultant. Write a professional and compelling cover letter.
84
+ ### COVER LETTER:"""
85
+ )
86
+ chain_content = prompt_content | llm
87
+ generated_content = chain_content.invoke(
88
+ input={
89
+ 'jd_requirements': "\n".join(jd_requirements),
90
+ 'resume_content': "\n".join([item for sublist in relevant_resume_chunks for item in sublist])
91
+ }
92
+ ).content
93
+
94
+ return generated_content
95
+
96
+ # --- Gradio UI ---
97
+ iface = gr.Interface(
98
+ fn=generate_content,
99
+ inputs=[
100
+ gr.File(label="Upload your resume (PDF)"),
101
+ gr.Textbox(label="Job Posting URL"),
102
+ ],
103
+ outputs=gr.Textbox(label="Generated Cover Letter"),
104
+ title="AI Resume Matcher and Content Generator",
105
+ description="Upload your resume and a job description to get a personalized cover letter.",
106
+ theme="huggingface"
107
+ )
108
+
109
+ iface.launch()