razaali10 commited on
Commit
e994c7a
·
verified ·
1 Parent(s): a59550d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -31
app.py CHANGED
@@ -1,33 +1,39 @@
1
  import streamlit as st
2
- import groq
3
- from jobspy import scrape_jobs
4
  import pandas as pd
5
  import json
6
- import time
7
  import smtplib
8
  from email.message import EmailMessage
9
  from typing import Dict
10
 
 
 
 
11
 
12
- # --------------------------------------------------
13
  # Utilities
14
- # --------------------------------------------------
15
 
16
  def remove_duplicates(df: pd.DataFrame) -> pd.DataFrame:
17
- df["dedup_key"] = (
18
- df["title"].fillna("") + "|" +
19
- df["company"].fillna("") + "|" +
20
- df["location"].fillna("") + "|" +
21
- df["job_url"].fillna("")
 
 
 
22
  )
23
- return df.drop_duplicates("dedup_key").drop(columns="dedup_key")
24
 
25
 
26
- # --------------------------------------------------
27
  # Email helper
28
- # --------------------------------------------------
29
 
30
  def send_email_with_csv(recipient_email: str, df: pd.DataFrame):
 
 
 
31
  smtp_server = st.secrets["SMTP_SERVER"]
32
  smtp_port = int(st.secrets["SMTP_PORT"])
33
  smtp_user = st.secrets["SMTP_USER"]
@@ -47,7 +53,11 @@ def send_email_with_csv(recipient_email: str, df: pd.DataFrame):
47
  )
48
 
49
  csv_data = df.to_csv(index=False)
50
- msg.add_attachment(csv_data, subtype="csv", filename="job_results.csv")
 
 
 
 
51
 
52
  with smtplib.SMTP(smtp_server, smtp_port) as server:
53
  server.starttls()
@@ -55,14 +65,18 @@ def send_email_with_csv(recipient_email: str, df: pd.DataFrame):
55
  server.send_message(msg)
56
 
57
 
58
- # --------------------------------------------------
59
- # AI helper
60
- # --------------------------------------------------
61
 
62
- def convert_prompt_to_parameters(client, prompt: str) -> Dict[str, str]:
 
 
 
63
  system_prompt = """
64
- Extract structured job search parameters.
65
  Return JSON ONLY:
 
66
  {
67
  "search_term": "<job title or keywords>",
68
  "location": "<city, province/state, or country>"
@@ -82,15 +96,22 @@ def convert_prompt_to_parameters(client, prompt: str) -> Dict[str, str]:
82
  try:
83
  return json.loads(response.choices[0].message.content)
84
  except Exception:
85
- return {"search_term": prompt, "location": "Canada"}
 
 
 
 
86
 
87
 
88
- # --------------------------------------------------
89
  # Job scraping
90
- # --------------------------------------------------
91
 
92
  @st.cache_data(ttl=3600)
93
  def get_indeed_jobs(search_term: str, location: str) -> pd.DataFrame:
 
 
 
94
  try:
95
  jobs = scrape_jobs(
96
  site_name=["indeed"],
@@ -105,23 +126,29 @@ def get_indeed_jobs(search_term: str, location: str) -> pd.DataFrame:
105
  return pd.DataFrame()
106
 
107
 
108
- # --------------------------------------------------
109
- # Streamlit UI
110
- # --------------------------------------------------
111
 
112
  def main():
113
- st.set_page_config(page_title="Private Job Alert", layout="centered")
 
 
 
114
 
115
  st.title("📧 Private Job Search & Email Alert")
116
 
117
  job_prompt = st.text_area(
118
  "Describe the job you are looking for",
119
- placeholder="e.g., Civil Engineer, Transportation Planner, Water Resources Engineer in Alberta",
 
 
 
120
  height=120
121
  )
122
 
123
  email_address = st.text_input(
124
- "Email address (CSV will be sent here)"
125
  )
126
 
127
  api_key = st.text_input(
@@ -129,12 +156,15 @@ def main():
129
  type="password"
130
  )
131
 
132
- if st.button("🔍 Search & Email Jobs", disabled=not (job_prompt and email_address and api_key)):
 
 
 
133
 
134
  client = groq.Client(api_key=api_key)
135
 
136
  with st.spinner("Understanding your request..."):
137
- params = convert_prompt_to_parameters(client, job_prompt)
138
 
139
  with st.spinner("Searching jobs..."):
140
  jobs_df = get_indeed_jobs(
@@ -153,7 +183,7 @@ def main():
153
  try:
154
  send_email_with_csv(email_address, jobs_df)
155
  st.success(
156
- f"✅ {len(jobs_df)} jobs found and emailed successfully to {email_address}"
157
  )
158
  except Exception as e:
159
  st.error(f"Failed to send email: {e}")
 
1
  import streamlit as st
 
 
2
  import pandas as pd
3
  import json
 
4
  import smtplib
5
  from email.message import EmailMessage
6
  from typing import Dict
7
 
8
+ from jobspy import scrape_jobs
9
+ import groq
10
+
11
 
12
+ # ======================================================
13
  # Utilities
14
+ # ======================================================
15
 
16
  def remove_duplicates(df: pd.DataFrame) -> pd.DataFrame:
17
+ """
18
+ Remove duplicate jobs using title + company + location + URL
19
+ """
20
+ df["__dedup_key__"] = (
21
+ df.get("title", "").astype(str) + "|" +
22
+ df.get("company", "").astype(str) + "|" +
23
+ df.get("location", "").astype(str) + "|" +
24
+ df.get("job_url", "").astype(str)
25
  )
26
+ return df.drop_duplicates("__dedup_key__").drop(columns="__dedup_key__")
27
 
28
 
29
+ # ======================================================
30
  # Email helper
31
+ # ======================================================
32
 
33
  def send_email_with_csv(recipient_email: str, df: pd.DataFrame):
34
+ """
35
+ Send CSV file via SMTP email
36
+ """
37
  smtp_server = st.secrets["SMTP_SERVER"]
38
  smtp_port = int(st.secrets["SMTP_PORT"])
39
  smtp_user = st.secrets["SMTP_USER"]
 
53
  )
54
 
55
  csv_data = df.to_csv(index=False)
56
+ msg.add_attachment(
57
+ csv_data,
58
+ subtype="csv",
59
+ filename="job_results.csv"
60
+ )
61
 
62
  with smtplib.SMTP(smtp_server, smtp_port) as server:
63
  server.starttls()
 
65
  server.send_message(msg)
66
 
67
 
68
+ # ======================================================
69
+ # AI helper (intent extraction only)
70
+ # ======================================================
71
 
72
+ def extract_search_parameters(client, prompt: str) -> Dict[str, str]:
73
+ """
74
+ Extract search_term and location from free text
75
+ """
76
  system_prompt = """
77
+ Extract job search parameters.
78
  Return JSON ONLY:
79
+
80
  {
81
  "search_term": "<job title or keywords>",
82
  "location": "<city, province/state, or country>"
 
96
  try:
97
  return json.loads(response.choices[0].message.content)
98
  except Exception:
99
+ # Safe fallback
100
+ return {
101
+ "search_term": prompt,
102
+ "location": "Canada"
103
+ }
104
 
105
 
106
+ # ======================================================
107
  # Job scraping
108
+ # ======================================================
109
 
110
  @st.cache_data(ttl=3600)
111
  def get_indeed_jobs(search_term: str, location: str) -> pd.DataFrame:
112
+ """
113
+ Scrape Indeed jobs using JobSpy
114
+ """
115
  try:
116
  jobs = scrape_jobs(
117
  site_name=["indeed"],
 
126
  return pd.DataFrame()
127
 
128
 
129
+ # ======================================================
130
+ # Streamlit App
131
+ # ======================================================
132
 
133
  def main():
134
+ st.set_page_config(
135
+ page_title="Private Job Alert",
136
+ layout="centered"
137
+ )
138
 
139
  st.title("📧 Private Job Search & Email Alert")
140
 
141
  job_prompt = st.text_area(
142
  "Describe the job you are looking for",
143
+ placeholder=(
144
+ "e.g. Civil Engineer, Transportation Planner, "
145
+ "Water Resources Engineer in Alberta"
146
+ ),
147
  height=120
148
  )
149
 
150
  email_address = st.text_input(
151
+ "Email address (CSV results will be sent here)"
152
  )
153
 
154
  api_key = st.text_input(
 
156
  type="password"
157
  )
158
 
159
+ if st.button(
160
+ "🔍 Search & Email Jobs",
161
+ disabled=not (job_prompt and email_address and api_key)
162
+ ):
163
 
164
  client = groq.Client(api_key=api_key)
165
 
166
  with st.spinner("Understanding your request..."):
167
+ params = extract_search_parameters(client, job_prompt)
168
 
169
  with st.spinner("Searching jobs..."):
170
  jobs_df = get_indeed_jobs(
 
183
  try:
184
  send_email_with_csv(email_address, jobs_df)
185
  st.success(
186
+ f"✅ {len(jobs_df)} jobs found and emailed to {email_address}"
187
  )
188
  except Exception as e:
189
  st.error(f"Failed to send email: {e}")