Musabbirkm commited on
Commit
44cc0f5
·
verified ·
1 Parent(s): 7f9c440

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -28
app.py CHANGED
@@ -17,26 +17,30 @@ import urllib.request
17
  import os
18
  import base64
19
 
20
-
21
  # Streamlit page configuration
22
  st.set_page_config(
23
- page_title="CareerBoost",
24
- page_icon="💼",
25
- layout="wide",
26
- initial_sidebar_state="expanded"
27
- )
28
  # Load API keys
29
  try:
30
- serp_api_key = os.getenv("serp_api_key")
31
- rapidapi_key = os.getenv("rapidapi_key")
32
- google_api_key = os.getenv("google_api_key")
33
- gnews_api_key = os.getenv("gnews_api_key")
34
- newsapi_key = os.getenv("newsapi_ke")
 
 
 
 
 
35
  except KeyError as e:
36
  st.error(f"Missing API key: {e}. Please configure it in secrets.toml.")
37
  st.stop()
38
 
39
- # Custom CSS
40
  st.markdown("""
41
  <style>
42
  .main {
@@ -76,7 +80,7 @@ st.markdown("""
76
  width: 150px;
77
  }
78
  .card {
79
- background-color: white;
80
  padding: 15px;
81
  border-radius: 10px;
82
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
@@ -110,7 +114,6 @@ Start with our [CV Maker](#) or [Job Finder](#)!
110
 
111
  st.sidebar.caption("v2.1.0 | Last updated: April 2024")
112
 
113
-
114
  # Home page
115
  if page == "Home":
116
  st.markdown("""
@@ -189,7 +192,7 @@ if page == "Home":
189
 
190
  logo_path = "logo.ico"
191
  if os.path.exists(logo_path):
192
- col1, col2, col3 = st.columns([1,2,1])
193
  with col2:
194
  with open(logo_path, "rb") as f:
195
  logo_bytes = f.read()
@@ -202,7 +205,7 @@ if page == "Home":
202
 
203
  st.markdown("""
204
  ## Welcome to Your Career Transformation
205
-
206
  CareerBoost is your **AI-powered career companion** designed to help you navigate every step of your professional
207
  journey with confidence. Whether you're looking for your dream job, optimizing your resume, or preparing for
208
  interviews, we've got you covered with smart, personalized tools.
@@ -230,7 +233,7 @@ if page == "Home":
230
  """, unsafe_allow_html=True)
231
 
232
  st.markdown("## ✨ How CareerBoost Helps You Succeed")
233
-
234
  features = [
235
  {
236
  "title": "Smart Job Matching",
@@ -253,7 +256,7 @@ if page == "Home":
253
  "icon": "🧭"
254
  }
255
  ]
256
-
257
  for feature in features:
258
  st.markdown(f"""
259
  <div class="feature-card">
@@ -272,10 +275,12 @@ elif page == "Job Finding":
272
  st.title("🔍 Job Finding")
273
  st.markdown("Search for job opportunities tailored to your preferences.")
274
 
 
275
  def build_google_search_link(title, company):
276
  query = f"{title} {company} apply job"
277
  return f"https://www.google.com/search?q={quote_plus(query)}"
278
 
 
279
  def search_serp(query, location, experience='fresher', job_category='full-time', num_results=10):
280
  params = {
281
  "engine": "google_jobs",
@@ -297,7 +302,9 @@ elif page == "Job Finding":
297
  "location": job.get('location', 'N/A'),
298
  "posted": job.get('detected_extensions', {}).get('posted_at', 'N/A'),
299
  "description": job.get('description', '')[:200] + "...",
300
- "apply_link": job.get("job_google_link") or build_google_search_link(job.get('title', ''), job.get('company_name', 'Unknown')),
 
 
301
  "source": "SerpAPI",
302
  "category": job_category
303
  }
@@ -306,6 +313,7 @@ elif page == "Job Finding":
306
  except requests.exceptions.RequestException as e:
307
  return [{"error": f"SerpAPI error: {str(e)}"}]
308
 
 
309
  def duckduckgo_job_search(query: str, job_category: str) -> list:
310
  try:
311
  with DDGS() as ddgs:
@@ -326,10 +334,12 @@ elif page == "Job Finding":
326
  except Exception as e:
327
  return [{"error": f"DuckDuckGo error: {str(e)}"}]
328
 
 
329
  def job_search(field, location, experience, job_category='full-time'):
330
  query = f"find {field} job in {location} for {experience}"
331
  return duckduckgo_job_search(query, job_category)
332
 
 
333
  def rapid_job_searcher(job: str, location: str, pages: int = 1, country: str = "us") -> list:
334
  conn = http.client.HTTPSConnection("jsearch.p.rapidapi.com")
335
  headers = {
@@ -365,6 +375,7 @@ elif page == "Job Finding":
365
  except Exception as e:
366
  return [{"error": f"RapidAPI request failed: {str(e)}"}]
367
 
 
368
  job_categories = ['full-time', 'part-time', 'intern', 'contract', 'temporary']
369
  experience_levels = ['fresher', 'experienced', 'senior']
370
 
@@ -383,10 +394,10 @@ elif page == "Job Finding":
383
  rapid_results = rapid_job_searcher(job, location)
384
  ddg_results = job_search(job, location, experience, category)
385
  serp_results = search_serp(job, location, experience, category)
386
- all_results = {'RapidAPI': rapid_results, 'DuckDuckGo': ddg_results, 'SerpAPI': serp_results}
387
 
388
  for source, results in all_results.items():
389
- st.subheader(f"Jobs from {source}")
390
  if results and not any("error" in r for r in results):
391
  for result in results:
392
  with st.container():
@@ -403,7 +414,7 @@ elif page == "Job Finding":
403
  else:
404
  error_msg = results[0].get("error", "No results found.") if results else "No results found."
405
  st.error(error_msg)
406
-
407
  # CV Maker Section
408
  elif page == "CV Maker":
409
  st.title("📝 CV Maker")
@@ -592,9 +603,9 @@ elif page == "Interview Preparation":
592
  interview_prompt = PromptTemplate(
593
  input_variables=["job_field", "search_results"],
594
  template="""
595
- You are an interview preparation expert. Generate exactly 10 interview questions with detailed, professional answers for {job_field}. Do NOT provide links or references to external resources; focus on self-contained questions and answers.
596
  Requirements:
597
- - Include 4 technical questions, 3 behavioral questions, and 3 situational questions.
598
  - Incorporate trends and frequently asked questions from 2022-2025.
599
  - Use the search results for context to inform answers, but do not include raw search data or URLs in the output: {search_results}.
600
  - Format as plain text with question numbers, type (Technical/Behavioral/Situational), questions, and answers.
@@ -622,7 +633,7 @@ elif page == "Interview Preparation":
622
  st.markdown("### Interview Questions")
623
  st.text_area("Questions and Answers", questions, height=400)
624
  st.download_button(
625
- label="Download Questions",
626
  data=questions,
627
  file_name="Interview_Questions.txt",
628
  mime="text/plain"
@@ -637,6 +648,7 @@ elif page == "Career Insights":
637
 
638
  newsapi = NewsApiClient(api_key=newsapi_key)
639
 
 
640
  def get_gnews_articles():
641
  url = f"https://gnews.io/api/v4/search?q=job%20market%20OR%20employment%20OR%20hiring%20OR%20recruitment%20OR%20careers%20OR%20job%20opportunities%20India%20OR%20tech%20OR%20IT%20OR%20technology&lang=en&country=in&max=10&apikey={gnews_api_key}"
642
  try:
@@ -658,6 +670,7 @@ elif page == "Career Insights":
658
  st.error(f"Failed to fetch GNews: {e.reason}")
659
  return []
660
 
 
661
  def get_indian_job_news():
662
  try:
663
  yesterday = (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d') # Extended to 7 days
@@ -684,6 +697,7 @@ elif page == "Career Insights":
684
  st.error(f"Unexpected error fetching job news: {str(e)}")
685
  return []
686
 
 
687
  def get_indian_tech_news():
688
  try:
689
  domains = 'economictimes.indiatimes.com,livemint.com,indiatoday.in'
@@ -708,6 +722,7 @@ elif page == "Career Insights":
708
  st.error(f"Unexpected error fetching tech news: {str(e)}")
709
  return []
710
 
 
711
  def get_company_hiring_news():
712
  companies = ['TCS', 'Infosys', 'Wipro', 'HCL', 'Tech Mahindra']
713
  company_news = []
@@ -735,6 +750,7 @@ elif page == "Career Insights":
735
  st.error(f"Unexpected error fetching company news: {str(e)}")
736
  return []
737
 
 
738
  with st.spinner("Fetching news..."):
739
  gnews_articles = get_gnews_articles()
740
  job_news = get_indian_job_news()
@@ -765,7 +781,8 @@ elif page == "Career Insights":
765
  """, unsafe_allow_html=True)
766
  st.markdown('</div>', unsafe_allow_html=True)
767
  else:
768
- st.markdown('<p class="no-news">No job market news available at the moment. Please try again later.</p>', unsafe_allow_html=True)
 
769
 
770
  # Company Hiring News Section
771
  st.markdown('<h2 class="section-header">Company Hiring News</h2>', unsafe_allow_html=True)
@@ -782,7 +799,8 @@ elif page == "Career Insights":
782
  """, unsafe_allow_html=True)
783
  st.markdown('</div>', unsafe_allow_html=True)
784
  else:
785
- st.markdown('<p class="no-news">No company hiring news available at the moment. Please try again later.</p>', unsafe_allow_html=True)
 
786
 
787
  # Tech Industry News Section
788
  st.markdown('<h2 class="section-header">Tech Industry News</h2>', unsafe_allow_html=True)
@@ -799,7 +817,8 @@ elif page == "Career Insights":
799
  """, unsafe_allow_html=True)
800
  st.markdown('</div>', unsafe_allow_html=True)
801
  else:
802
- st.markdown('<p class="no-news">No tech industry news available at the moment. Please try again later.</p>', unsafe_allow_html=True)
 
803
 
804
 
805
  # About Section
 
17
  import os
18
  import base64
19
 
 
20
  # Streamlit page configuration
21
  st.set_page_config(
22
+ page_title="CareerBoost",
23
+ page_icon="💼",
24
+ layout="wide",
25
+ initial_sidebar_state="expanded"
26
+ )
27
  # Load API keys
28
  try:
29
+ # serp_api_key = os.getenv("serp_api_key")
30
+ # rapidapi_key = os.getenv("rapidapi_key")
31
+ # google_api_key = os.getenv("google_api_key")
32
+ # gnews_api_key = os.getenv("gnews_api_key")
33
+ # newsapi_key = os.getenv("newsapi_ke")
34
+ serp_api_key = "97e9c83e6b430eb8a8cdd71cf70aaf2d22812a74d6192c87a56dfcbad55dfaa3"
35
+ rapidapi_key = "d4b6e17cb6msh1464b70685fc390p17d5ccjsn81a387e95e22"
36
+ google_api_key = "AIzaSyB-IkNZfgUbdS78JoOByBFfhiW7nydLa08"
37
+ gnews_api_key = "2c381983217903362384b7e454fccd09"
38
+ newsapi_key = "e6e70c06012845b7a9c5fa1e53b79d83"
39
  except KeyError as e:
40
  st.error(f"Missing API key: {e}. Please configure it in secrets.toml.")
41
  st.stop()
42
 
43
+ # Custom CSS
44
  st.markdown("""
45
  <style>
46
  .main {
 
80
  width: 150px;
81
  }
82
  .card {
83
+ background-color: #2d3748;
84
  padding: 15px;
85
  border-radius: 10px;
86
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
 
114
 
115
  st.sidebar.caption("v2.1.0 | Last updated: April 2024")
116
 
 
117
  # Home page
118
  if page == "Home":
119
  st.markdown("""
 
192
 
193
  logo_path = "logo.ico"
194
  if os.path.exists(logo_path):
195
+ col1, col2, col3 = st.columns([1, 2, 1])
196
  with col2:
197
  with open(logo_path, "rb") as f:
198
  logo_bytes = f.read()
 
205
 
206
  st.markdown("""
207
  ## Welcome to Your Career Transformation
208
+
209
  CareerBoost is your **AI-powered career companion** designed to help you navigate every step of your professional
210
  journey with confidence. Whether you're looking for your dream job, optimizing your resume, or preparing for
211
  interviews, we've got you covered with smart, personalized tools.
 
233
  """, unsafe_allow_html=True)
234
 
235
  st.markdown("## ✨ How CareerBoost Helps You Succeed")
236
+
237
  features = [
238
  {
239
  "title": "Smart Job Matching",
 
256
  "icon": "🧭"
257
  }
258
  ]
259
+
260
  for feature in features:
261
  st.markdown(f"""
262
  <div class="feature-card">
 
275
  st.title("🔍 Job Finding")
276
  st.markdown("Search for job opportunities tailored to your preferences.")
277
 
278
+
279
  def build_google_search_link(title, company):
280
  query = f"{title} {company} apply job"
281
  return f"https://www.google.com/search?q={quote_plus(query)}"
282
 
283
+
284
  def search_serp(query, location, experience='fresher', job_category='full-time', num_results=10):
285
  params = {
286
  "engine": "google_jobs",
 
302
  "location": job.get('location', 'N/A'),
303
  "posted": job.get('detected_extensions', {}).get('posted_at', 'N/A'),
304
  "description": job.get('description', '')[:200] + "...",
305
+ "apply_link": job.get("job_google_link") or build_google_search_link(job.get('title', ''),
306
+ job.get('company_name',
307
+ 'Unknown')),
308
  "source": "SerpAPI",
309
  "category": job_category
310
  }
 
313
  except requests.exceptions.RequestException as e:
314
  return [{"error": f"SerpAPI error: {str(e)}"}]
315
 
316
+
317
  def duckduckgo_job_search(query: str, job_category: str) -> list:
318
  try:
319
  with DDGS() as ddgs:
 
334
  except Exception as e:
335
  return [{"error": f"DuckDuckGo error: {str(e)}"}]
336
 
337
+
338
  def job_search(field, location, experience, job_category='full-time'):
339
  query = f"find {field} job in {location} for {experience}"
340
  return duckduckgo_job_search(query, job_category)
341
 
342
+
343
  def rapid_job_searcher(job: str, location: str, pages: int = 1, country: str = "us") -> list:
344
  conn = http.client.HTTPSConnection("jsearch.p.rapidapi.com")
345
  headers = {
 
375
  except Exception as e:
376
  return [{"error": f"RapidAPI request failed: {str(e)}"}]
377
 
378
+
379
  job_categories = ['full-time', 'part-time', 'intern', 'contract', 'temporary']
380
  experience_levels = ['fresher', 'experienced', 'senior']
381
 
 
394
  rapid_results = rapid_job_searcher(job, location)
395
  ddg_results = job_search(job, location, experience, category)
396
  serp_results = search_serp(job, location, experience, category)
397
+ all_results = {'DuckDuckGo': ddg_results,'RapidAPI': rapid_results, 'SerpAPI': serp_results}
398
 
399
  for source, results in all_results.items():
400
+ st.subheader(f"Jobs Tailored for You")
401
  if results and not any("error" in r for r in results):
402
  for result in results:
403
  with st.container():
 
414
  else:
415
  error_msg = results[0].get("error", "No results found.") if results else "No results found."
416
  st.error(error_msg)
417
+
418
  # CV Maker Section
419
  elif page == "CV Maker":
420
  st.title("📝 CV Maker")
 
603
  interview_prompt = PromptTemplate(
604
  input_variables=["job_field", "search_results"],
605
  template="""
606
+ You are an interview preparation expert. Generate exactly 15 interview questions with detailed, professional answers for {job_field}. Do NOT provide links or references to external resources; focus on self-contained questions and answers.
607
  Requirements:
608
+ - Include 6 technical questions, 5 behavioral questions, and 4 situational questions.
609
  - Incorporate trends and frequently asked questions from 2022-2025.
610
  - Use the search results for context to inform answers, but do not include raw search data or URLs in the output: {search_results}.
611
  - Format as plain text with question numbers, type (Technical/Behavioral/Situational), questions, and answers.
 
633
  st.markdown("### Interview Questions")
634
  st.text_area("Questions and Answers", questions, height=400)
635
  st.download_button(
636
+ label="Download Questions&Answer",
637
  data=questions,
638
  file_name="Interview_Questions.txt",
639
  mime="text/plain"
 
648
 
649
  newsapi = NewsApiClient(api_key=newsapi_key)
650
 
651
+
652
  def get_gnews_articles():
653
  url = f"https://gnews.io/api/v4/search?q=job%20market%20OR%20employment%20OR%20hiring%20OR%20recruitment%20OR%20careers%20OR%20job%20opportunities%20India%20OR%20tech%20OR%20IT%20OR%20technology&lang=en&country=in&max=10&apikey={gnews_api_key}"
654
  try:
 
670
  st.error(f"Failed to fetch GNews: {e.reason}")
671
  return []
672
 
673
+
674
  def get_indian_job_news():
675
  try:
676
  yesterday = (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d') # Extended to 7 days
 
697
  st.error(f"Unexpected error fetching job news: {str(e)}")
698
  return []
699
 
700
+
701
  def get_indian_tech_news():
702
  try:
703
  domains = 'economictimes.indiatimes.com,livemint.com,indiatoday.in'
 
722
  st.error(f"Unexpected error fetching tech news: {str(e)}")
723
  return []
724
 
725
+
726
  def get_company_hiring_news():
727
  companies = ['TCS', 'Infosys', 'Wipro', 'HCL', 'Tech Mahindra']
728
  company_news = []
 
750
  st.error(f"Unexpected error fetching company news: {str(e)}")
751
  return []
752
 
753
+
754
  with st.spinner("Fetching news..."):
755
  gnews_articles = get_gnews_articles()
756
  job_news = get_indian_job_news()
 
781
  """, unsafe_allow_html=True)
782
  st.markdown('</div>', unsafe_allow_html=True)
783
  else:
784
+ st.markdown('<p class="no-news">No job market news available at the moment. Please try again later.</p>',
785
+ unsafe_allow_html=True)
786
 
787
  # Company Hiring News Section
788
  st.markdown('<h2 class="section-header">Company Hiring News</h2>', unsafe_allow_html=True)
 
799
  """, unsafe_allow_html=True)
800
  st.markdown('</div>', unsafe_allow_html=True)
801
  else:
802
+ st.markdown('<p class="no-news">No company hiring news available at the moment. Please try again later.</p>',
803
+ unsafe_allow_html=True)
804
 
805
  # Tech Industry News Section
806
  st.markdown('<h2 class="section-header">Tech Industry News</h2>', unsafe_allow_html=True)
 
817
  """, unsafe_allow_html=True)
818
  st.markdown('</div>', unsafe_allow_html=True)
819
  else:
820
+ st.markdown('<p class="no-news">No tech industry news available at the moment. Please try again later.</p>',
821
+ unsafe_allow_html=True)
822
 
823
 
824
  # About Section