Amin1600 commited on
Commit
446955e
Β·
1 Parent(s): 0c646e4

changed to run on HF directly

Browse files
Files changed (3) hide show
  1. main.py +68 -36
  2. requirements.txt +2 -1
  3. run.py +18 -58
main.py CHANGED
@@ -1,9 +1,11 @@
1
- import os
2
- import requests
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
5
 
6
- # ... your existing code displaying data tables ...
7
 
8
  st.sidebar.header("βš™οΈ Live Scraper Controller")
9
  st.sidebar.write("Trigger an on-demand cloud scraping run on GitHub Actions.")
@@ -22,36 +24,66 @@ if date_input == 'all':
22
  #date_mapping = {"all": "None", "daily": "r86400", "weekly": "r604800", "monthly": "r2592000"}
23
 
24
  # 3. The Activation Button
25
- if st.sidebar.button("πŸš€ Trigger Cloud Scraper"):
26
- # Fetch your hidden access token from Hugging Face environment variables
27
- gh_token = os.environ.get("GH_PAT")
28
-
29
- # Change these to match your exact github profile details
30
- GITHUB_USERNAME = "Min1600"
31
- REPO_NAME = "malaysia-data-jobs-platform"
32
- WORKFLOW_FILE = "run-web-scraper.yml" # Name of your workflow file
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- if not gh_token:
35
- st.sidebar.error("Missing 'GH_PAT' Secret in Hugging Face Settings.")
36
- else:
37
- with st.spinner("Waking up GitHub Action Runner..."):
38
- url = f"https://api.github.com/repos/{GITHUB_USERNAME}/{REPO_NAME}/actions/workflows/{WORKFLOW_FILE}/dispatches"
39
- headers = {
40
- "Authorization": f"token {gh_token}",
41
- "Accept": "application/vnd.github.v3+json"
42
- }
43
- payload = {
44
- "ref": "main", # Run on your main branch code
45
- "inputs": {
46
- "job_type": job_input,
47
- "location": loc_input,
48
- "date_range": date_input
49
- }
50
- }
51
-
52
- response = requests.post(url, headers=headers, json=payload)
53
-
54
- if response.status_code == 204:
55
- st.sidebar.success("πŸŽ‰ GitHub Workflow started! Your fresh data will show up here in a few minutes.")
56
- else:
57
- st.sidebar.error(f"Failed to connect. Error {response.status_code}: {response.text}")
 
 
 
 
1
  import streamlit as st
2
+ import logging
3
+ import sys
4
+ import threading
5
+ from datetime import datetime
6
+ from run import job_scraper
7
+ from apscheduler.schedulers.background import BackgroundScheduler
8
 
 
9
 
10
  st.sidebar.header("βš™οΈ Live Scraper Controller")
11
  st.sidebar.write("Trigger an on-demand cloud scraping run on GitHub Actions.")
 
24
  #date_mapping = {"all": "None", "daily": "r86400", "weekly": "r604800", "monthly": "r2592000"}
25
 
26
  # 3. The Activation Button
27
+ if st.sidebar.button("πŸš€ Run Scraper"):
28
+
29
+ # 🌟 Create a separate background thread so the UI doesn't freeze!
30
+ scraper_thread = threading.Thread(
31
+ target=job_scraper,
32
+ kwargs={
33
+ "job_title": job_input,
34
+ "target_location": loc_input,
35
+ "date_range": date_input,
36
+ "run_type": "manual"
37
+ }
38
+ )
39
+ # Start the background task
40
+ scraper_thread.start()
41
+
42
+
43
+ # 🌟 1. Configure the global root logger ONLY ONCE on application startup
44
+ if "logger_initialized" not in st.session_state: # Streamlit specific safety guard
45
+ root_logger = logging.getLogger()
46
+ root_logger.setLevel(logging.DEBUG)
47
+
48
+ # Mute sub-loggers
49
+ logging.getLogger("urllib3").setLevel(logging.WARNING)
50
+ logging.getLogger("requests").setLevel(logging.WARNING)
51
+
52
+ # File Handler
53
+ import os
54
+ os.makedirs("logs", exist_ok=True)
55
+ timestamp = datetime.now().strftime("%Y%m%dT%H%M%S")
56
+ file_handler = logging.FileHandler(f"logs/app-{timestamp}.log")
57
+ file_handler.setLevel(logging.INFO)
58
+ file_formatter = logging.Formatter('%(asctime)s:%(name)s - [%(levelname)s]: %(message)s')
59
+ file_handler.setFormatter(file_formatter)
60
+
61
+ # Console Handler
62
+ console_handler = logging.StreamHandler(sys.stdout)
63
+ console_handler.setLevel(logging.DEBUG)
64
+ console_formatter = logging.Formatter('[%(levelname)s]: %(message)s')
65
+ console_handler.setFormatter(console_formatter)
66
+
67
+ # Attach both
68
+ root_logger.addHandler(file_handler)
69
+ root_logger.addHandler(console_handler)
70
 
71
+ st.session_state["logger_initialized"] = True
72
+
73
+ # 🌟 2. Now initialize file-specific loggers anywhere using __name__
74
+ main_logger = logging.getLogger(__name__)
75
+ main_logger.info("Application UI successfully booted up!")
76
+
77
+ def daily_scraper():
78
+ # Injected values are passed directly into the function call here!
79
+ start_scraping_routine(
80
+ job_title="Data Analyst",
81
+ target_location="Kuala Lumpur",
82
+ date_range="daily",
83
+ run_type="scheduled"
84
+ )
85
+
86
+ scheduler = BackgroundScheduler()
87
+ # Runs every single night
88
+ scheduler.add_job(automated_job, 'cron', hour=16, minute=0)
89
+ scheduler.start()
 
 
 
 
 
requirements.txt CHANGED
@@ -10,4 +10,5 @@ python-dotenv==1.0.1
10
  streamlit
11
  pandas
12
 
13
- huggingface_hub
 
 
10
  streamlit
11
  pandas
12
 
13
+ huggingface_hub
14
+ apscheduler
run.py CHANGED
@@ -9,57 +9,14 @@ from dotenv import load_dotenv
9
  from ingestion.jobstreet.jobstreet_scraper import js_scraper, get_total_pages
10
  from ingestion.linkedin.linkedin_scraper import ld_scraper
11
 
12
- # Setup
13
- ROOT = Path(__file__).parent
14
- load_dotenv(ROOT / ".env")
15
 
16
- # Read variables injected by GitHub Actions environment blocks
17
- job_title = os.environ.get("JOB_TYPE", "Data Analyst")
18
- target_location = os.environ.get("LOCATION", "Kuala Lumpur")
19
- date_range = os.environ.get("DATE_RANGE", "None")
20
- run_type = os.environ.get("RUN_TYPE")
21
 
22
- # Standardize "N/A" string back into Python's actual None type
23
- if date_range == "None":
24
- date_range = None
25
-
26
- # Logging
27
- os.makedirs("logs", exist_ok=True)
28
- timestamp = datetime.now().strftime("%Y%m%dT%H%M%S")
29
-
30
- # 1. Initialize the master root logger
31
- root_logger = logging.getLogger()
32
- root_logger.setLevel(logging.DEBUG) # Master threshold level
33
-
34
- # Mute the specific sub-loggers
35
- logging.getLogger("urllib3").setLevel(logging.WARNING)
36
- logging.getLogger("requests").setLevel(logging.WARNING)
37
-
38
- # 2. Create Handler #1: For writing to a file
39
- timestamp = datetime.now().strftime("%Y%m%dT%H%M%S")
40
- file_handler = logging.FileHandler(f"logs/app-{timestamp}.log")
41
- file_handler.setLevel(logging.INFO)
42
- file_formatter = logging.Formatter('%(asctime)s:%(name)s - [%(levelname)s]: %(message)s')
43
- file_handler.setFormatter(file_formatter)
44
-
45
- # 3. Create Handler #2: For streaming to terminal screen
46
- console_handler = logging.StreamHandler(sys.stdout)
47
- console_handler.setLevel(logging.DEBUG)
48
- console_formatter = logging.Formatter('[%(levelname)s]: %(message)s')
49
- console_handler.setFormatter(console_formatter)
50
-
51
- # 4. Tie both handlers to the root logger
52
- root_logger.addHandler(file_handler)
53
- root_logger.addHandler(console_handler)
54
-
55
- # initialize logger for current file (main.py)
56
- main_logger = logging.getLogger(__name__)
57
-
58
-
59
-
60
- if __name__ == "__main__":
61
 
62
- if run_type == 'daily':
63
  # 🌟 Define all the jobs you want to track automatically every night!
64
  DAILY_JOBS = [
65
  "Data Analyst"
@@ -71,30 +28,33 @@ if __name__ == "__main__":
71
 
72
  for job in DAILY_JOBS:
73
 
74
- main_logger.info(f"⏰ Starting Scheduled web scraper run for {job} job listings.")
75
 
76
- main_logger.info("πŸš€ Scraping jobs from Jobstreet")
77
  js_scraper(job_type = job, location = s_target_location, date_range = js_date_range)
78
 
79
- main_logger.info("πŸš€ Scraping jobs from Linkedin")
80
  ld_scraper(job_type = job, location = s_target_location, date_range = ld_date_range)
81
 
82
- main_logger.info("🏁 All scraping tasks completed successfully.")
83
 
84
  elif run_type == 'manual':
85
- main_logger.info(date_range)
86
  if date_range == 'daily':
87
  ld_date_range = "r86400"
88
  js_date_range = 1
89
 
90
- main_logger.info(f"Starting web scraper run for {job_title} job listings.")
91
- main_logger.info("πŸš€ Scraping jobs from Jobstreet")
92
  js_scraper(job_type = job_title, location = target_location, date_range = js_date_range)
93
 
94
- main_logger.info("πŸš€ Scraping jobs from Linkedin")
95
  ld_scraper(job_type = job_title, location = target_location, date_range = ld_date_range)
96
 
97
- main_logger.info("🏁 All scraping tasks completed successfully.")
98
 
99
  else:
100
- main_logger.warning('πŸ›‘ Undetermined run type task is unable to start!')
 
 
 
 
9
  from ingestion.jobstreet.jobstreet_scraper import js_scraper, get_total_pages
10
  from ingestion.linkedin.linkedin_scraper import ld_scraper
11
 
12
+ app_logger = logging.getLogger(__name__)
 
 
13
 
14
+ def job_scraper(job_title="Data Analyst", target_location="Kuala Lumpur", date_range="daily", run_type="scheduled"):
 
 
 
 
15
 
16
+ if date_range == "None" or date_range is None:
17
+ date_range = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
+ if run_type == 'scheduled':
20
  # 🌟 Define all the jobs you want to track automatically every night!
21
  DAILY_JOBS = [
22
  "Data Analyst"
 
28
 
29
  for job in DAILY_JOBS:
30
 
31
+ app_logger.info(f"⏰ Starting Scheduled web scraper run for {job} job listings.")
32
 
33
+ app_logger.info("πŸš€ Scraping jobs from Jobstreet")
34
  js_scraper(job_type = job, location = s_target_location, date_range = js_date_range)
35
 
36
+ app_logger.info("πŸš€ Scraping jobs from Linkedin")
37
  ld_scraper(job_type = job, location = s_target_location, date_range = ld_date_range)
38
 
39
+ app_logger.info("🏁 All scraping tasks completed successfully.")
40
 
41
  elif run_type == 'manual':
42
+ app_logger.info(date_range)
43
  if date_range == 'daily':
44
  ld_date_range = "r86400"
45
  js_date_range = 1
46
 
47
+ app_logger.info(f"Starting web scraper run for {job_title} job listings.")
48
+ app_logger.info("πŸš€ Scraping jobs from Jobstreet")
49
  js_scraper(job_type = job_title, location = target_location, date_range = js_date_range)
50
 
51
+ app_logger.info("πŸš€ Scraping jobs from Linkedin")
52
  ld_scraper(job_type = job_title, location = target_location, date_range = ld_date_range)
53
 
54
+ app_logger.info("🏁 All scraping tasks completed successfully.")
55
 
56
  else:
57
+ app_logger.warning('πŸ›‘ Undetermined run type task is unable to start!')
58
+
59
+ if __name__ == "__main__":
60
+