meesamraza commited on
Commit
d44b040
·
verified ·
1 Parent(s): 7c21cf8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -75
app.py CHANGED
@@ -7,8 +7,6 @@ from io import BytesIO
7
  import os
8
  from dotenv import load_dotenv
9
  from groq import Groq
10
- import requests
11
- from bs4 import BeautifulSoup
12
 
13
  # Load API key
14
  load_dotenv()
@@ -21,7 +19,7 @@ except Exception as e:
21
  st.error(f"Failed to initialize Groq client: {str(e)}")
22
  client = None
23
 
24
- # Extract resume text
25
  def extract_text(file):
26
  if file.name.endswith(".pdf"):
27
  try:
@@ -36,34 +34,25 @@ def extract_text(file):
36
  st.error(f"DOCX error: {e}")
37
  return None
38
 
39
- # Extract job description from URL
40
- def extract_from_url(url):
41
- try:
42
- response = requests.get(url, headers={"User-Agent": "Mozilla"}, timeout=10)
43
- soup = BeautifulSoup(response.text, "html.parser")
44
- for tag in soup(["script", "style"]):
45
- tag.decompose()
46
- return " ".join(soup.stripped_strings)
47
- except Exception as e:
48
- st.error(f"URL extract error: {e}")
49
- return None
50
-
51
- # AI using llama3 (replaces broken deepseek)
52
  def analyze_with_ai(prompt):
53
  if not client:
54
  return "Missing API key"
55
  try:
56
- response = client.chat.completions.create(
57
  model="llama3-70b-8192",
58
  messages=[{"role": "user", "content": prompt}],
59
- temperature=0.3,
60
- max_tokens=1800,
 
 
 
61
  )
62
- return response.choices[0].message.content
63
  except Exception as e:
64
  return f"AI Error: {e}"
65
 
66
- # Save text as docx
67
  def text_to_docx(text):
68
  doc = Document()
69
  for p in text.split("\n"):
@@ -74,82 +63,89 @@ def text_to_docx(text):
74
  buffer.seek(0)
75
  return buffer
76
 
77
- # UI
78
- st.set_page_config(page_title="AI Resume & Cover Letter Assistant", layout="wide")
79
- st.title("🤖 AI Resume & Cover Letter Assistant")
80
- st.write("Upload your resume and job description to generate a custom resume + cover letter.")
81
 
82
  with st.sidebar:
83
  st.markdown("### Instructions")
84
- st.markdown("1. Upload your resume (PDF or DOCX)")
85
- st.markdown("2. Paste a job description or job URL")
86
- st.markdown("3. Click 'Analyze'")
87
- st.markdown("4. Download your optimized resume and cover letter")
88
 
89
  # Inputs
90
  col1, col2 = st.columns(2)
91
  with col1:
92
- resume_file = st.file_uploader("Upload Resume", type=["pdf", "docx"])
93
  with col2:
94
- job_input = st.text_input("Job Description (URL or Text)")
 
95
 
96
  if st.button("🔍 Analyze and Generate"):
97
- if resume_file and job_input:
98
- with st.spinner("Processing your resume and job info..."):
99
- resume_text = extract_text(resume_file)
100
- job_text = extract_from_url(job_input) if job_input.startswith("http") else job_input
101
-
102
- if not resume_text or not job_text:
103
- st.error("Resume or job description could not be processed.")
104
  st.stop()
105
 
106
- prompt = f"""
107
- Given the following resume and job description, improve the resume by injecting relevant ATS keywords and tailoring it to the job. Also generate a custom cover letter.
108
-
109
- RESUME:
110
- {resume_text[:3000]}
111
-
112
- JOB DESCRIPTION:
113
- {job_text[:3000]}
114
-
115
- Respond in this format:
116
- ### Optimized Resume:
117
- <Improved resume>
118
-
119
- ### Cover Letter:
120
- <Professional cover letter>
 
 
 
 
 
 
 
121
  """
122
 
123
  ai_response = analyze_with_ai(prompt)
124
 
125
- if "### Optimized Resume:" in ai_response and "### Cover Letter:" in ai_response:
126
- resume_part = ai_response.split("### Cover Letter:")[0].replace("### Optimized Resume:", "").strip()
127
- cover_letter_part = ai_response.split("### Cover Letter:")[1].strip()
128
  else:
129
- resume_part = ai_response.strip()
130
- cover_letter_part = ""
131
- st.warning("Unexpected format. Showing full response as resume.")
132
-
133
- # Show & Download Resume
134
- st.success("✅ Documents generated!")
135
- st.subheader("📄 Optimized Resume")
136
- st.markdown(resume_part)
137
- st.download_button("⬇ Download Resume", data=text_to_docx(resume_part), file_name="optimized_resume.docx")
138
-
139
- # Show & Download Cover Letter
140
- if cover_letter_part:
141
- st.subheader("📄 Cover Letter")
142
- st.markdown(cover_letter_part)
143
- st.download_button("⬇ Download Cover Letter", data=text_to_docx(cover_letter_part), file_name="cover_letter.docx")
144
  else:
145
- st.info("No cover letter was generated.")
146
  else:
147
- st.warning("Please upload both resume and job input.")
148
 
149
  # Footer
150
  st.markdown("---")
151
  st.markdown("""
152
  <div style='text-align:center; font-size:0.85em; color:gray'>
153
- AI Career Assistant · Powered by Groq LLaMA3 · Built with ❤️ in Streamlit
154
  </div>
155
- """, unsafe_allow_html=True)
 
7
  import os
8
  from dotenv import load_dotenv
9
  from groq import Groq
 
 
10
 
11
  # Load API key
12
  load_dotenv()
 
19
  st.error(f"Failed to initialize Groq client: {str(e)}")
20
  client = None
21
 
22
+ # Extract text from uploaded file
23
  def extract_text(file):
24
  if file.name.endswith(".pdf"):
25
  try:
 
34
  st.error(f"DOCX error: {e}")
35
  return None
36
 
37
+ # Analyze with Groq API
 
 
 
 
 
 
 
 
 
 
 
 
38
  def analyze_with_ai(prompt):
39
  if not client:
40
  return "Missing API key"
41
  try:
42
+ completion = client.chat.completions.create(
43
  model="llama3-70b-8192",
44
  messages=[{"role": "user", "content": prompt}],
45
+ temperature=0.7, # Balanced creativity for feedback
46
+ max_tokens=4096, # Adjusted for detailed feedback
47
+ top_p=1,
48
+ stream=False,
49
+ stop=None
50
  )
51
+ return completion.choices[0].message.content
52
  except Exception as e:
53
  return f"AI Error: {e}"
54
 
55
+ # Save text as DOCX
56
  def text_to_docx(text):
57
  doc = Document()
58
  for p in text.split("\n"):
 
63
  buffer.seek(0)
64
  return buffer
65
 
66
+ # Streamlit UI
67
+ st.set_page_config(page_title="AI IELTS Preparation Assistant", layout="wide")
68
+ st.title("📚 AI IELTS Preparation Assistant")
69
+ st.write("Upload your IELTS essay or input text to get feedback and practice questions for Writing and Speaking.")
70
 
71
  with st.sidebar:
72
  st.markdown("### Instructions")
73
+ st.markdown("1. Upload an essay (PDF or DOCX) or enter text.")
74
+ st.markdown("2. Select the IELTS section (Writing/Speaking).")
75
+ st.markdown("3. Click 'Analyze' for feedback and practice questions.")
76
+ st.markdown("4. Download feedback and practice materials.")
77
 
78
  # Inputs
79
  col1, col2 = st.columns(2)
80
  with col1:
81
+ essay_file = st.file_uploader("Upload Essay (Optional)", type=["pdf", "docx"])
82
  with col2:
83
+ essay_text = st.text_area("Or Enter Essay Text", height=200)
84
+ ielts_section = st.selectbox("IELTS Section", ["Writing Task 1", "Writing Task 2", "Speaking"])
85
 
86
  if st.button("🔍 Analyze and Generate"):
87
+ if essay_file or essay_text:
88
+ with st.spinner("Analyzing your input..."):
89
+ # Extract text from file or use direct input
90
+ input_text = extract_text(essay_file) if essay_file else essay_text
91
+ if not input_text:
92
+ st.error("No text provided or extraction failed.")
 
93
  st.stop()
94
 
95
+ # Define prompt based on IELTS section
96
+ if ielts_section.startswith("Writing"):
97
+ prompt = f"""
98
+ You are an IELTS examiner. Analyze the following {ielts_section} essay for grammar, vocabulary, coherence, and task response. Provide detailed feedback, including strengths, weaknesses, and suggestions for improvement (aligned with IELTS band descriptors). Also, generate 3 practice questions for {ielts_section}.
99
+ ESSAY:
100
+ {input_text[:3000]}
101
+ Respond in this format:
102
+ ### Feedback:
103
+ <Detailed feedback>
104
+ ### Practice Questions:
105
+ <Three practice questions>
106
+ """
107
+ else: # Speaking
108
+ prompt = f"""
109
+ You are an IELTS examiner. Analyze the following IELTS Speaking response for fluency, vocabulary, grammar, and pronunciation. Provide detailed feedback, including strengths, weaknesses, and suggestions for improvement (aligned with IELTS band descriptors). Also, generate 3 practice questions for IELTS Speaking.
110
+ RESPONSE:
111
+ {input_text[:3000]}
112
+ Respond in this format:
113
+ ### Feedback:
114
+ <Detailed feedback>
115
+ ### Practice Questions:
116
+ <Three practice questions>
117
  """
118
 
119
  ai_response = analyze_with_ai(prompt)
120
 
121
+ if "### Feedback:" in ai_response and "### Practice Questions:" in ai_response:
122
+ feedback_part = ai_response.split("### Practice Questions:")[0].replace("### Feedback:", "").strip()
123
+ questions_part = ai_response.split("### Practice Questions:")[1].strip()
124
  else:
125
+ feedback_part = ai_response.strip()
126
+ questions_part = ""
127
+ st.warning("Unexpected response format. Showing full response as feedback.")
128
+
129
+ # Display and download feedback
130
+ st.success("✅ Analysis complete!")
131
+ st.subheader("📝 Feedback")
132
+ st.markdown(feedback_part)
133
+ st.download_button("⬇ Download Feedback", data=text_to_docx(feedback_part), file_name="ielts_feedback.docx")
134
+
135
+ # Display and download practice questions
136
+ if questions_part:
137
+ st.subheader(" Practice Questions")
138
+ st.markdown(questions_part)
139
+ st.download_button("⬇ Download Practice Questions", data=text_to_docx(questions_part), file_name="practice_questions.docx")
140
  else:
141
+ st.info("No practice questions generated.")
142
  else:
143
+ st.warning("Please upload an essay or enter text.")
144
 
145
  # Footer
146
  st.markdown("---")
147
  st.markdown("""
148
  <div style='text-align:center; font-size:0.85em; color:gray'>
149
+ AI IELTS Assistant · Powered by Groq LLaMA3 · Built with ❤️ in Streamlit
150
  </div>
151
+ """, unsafe_allow_html=True)