datamk commited on
Commit
fcd3b26
·
verified ·
1 Parent(s): b68e51c

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +7 -23
  2. app.py +35 -50
  3. requirements.txt +3 -3
Dockerfile CHANGED
@@ -1,24 +1,6 @@
1
- FROM python:3.10-slim
 
2
 
3
- # Install system dependencies needed for Chrome and Selenium
4
- ENV DEBIAN_FRONTEND=noninteractive
5
- RUN apt-get update && apt-get install -y \
6
- wget \
7
- gnupg \
8
- unzip \
9
- curl \
10
- --no-install-recommends \
11
- && rm -rf /var/lib/apt/lists/*
12
-
13
- # Install Google Chrome Stable safely without hanging on prompts
14
- RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg \
15
- && sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' \
16
- && apt-get update \
17
- && apt-get install -y google-chrome-stable \
18
- --no-install-recommends \
19
- && rm -rf /var/lib/apt/lists/*
20
-
21
- # Create user securely to run in HF Spaces instead of root
22
  RUN useradd -m -u 1000 user
23
  USER user
24
  ENV HOME=/home/user \
@@ -27,15 +9,17 @@ ENV HOME=/home/user \
27
 
28
  WORKDIR $HOME/app
29
 
30
- # Install Python requirements
31
  COPY --chown=user requirements.txt .
32
  RUN pip install --no-cache-dir -r requirements.txt
33
 
 
 
 
34
  # Copy our backend script into the container
35
  COPY --chown=user app.py .
36
 
37
- # HF Spaces requires the container to expose port 7860
38
  EXPOSE 7860
39
 
40
- # Start Gradio which will host our Background keep-alive thread
41
  CMD ["python", "app.py"]
 
1
+ # Use the official Microsoft Playwright image. It has ALL complex system dependencies pre-installed!
2
+ FROM mcr.microsoft.com/playwright/python:v1.40.0-jammy
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  RUN useradd -m -u 1000 user
5
  USER user
6
  ENV HOME=/home/user \
 
9
 
10
  WORKDIR $HOME/app
11
 
12
+ # Install our python requirements
13
  COPY --chown=user requirements.txt .
14
  RUN pip install --no-cache-dir -r requirements.txt
15
 
16
+ # Download the Chromium portable browser incredibly fast without apt-get!
17
+ RUN playwright install chromium
18
+
19
  # Copy our backend script into the container
20
  COPY --chown=user app.py .
21
 
 
22
  EXPOSE 7860
23
 
24
+ # Start Gradio background daemon
25
  CMD ["python", "app.py"]
app.py CHANGED
@@ -2,92 +2,77 @@ import gradio as gr
2
  import threading
3
  import time
4
  import schedule
5
- from selenium import webdriver
6
- from selenium.webdriver.chrome.options import Options
7
  import random
8
  import datetime
9
 
10
  URL = "https://streamer1-gvbgwaea2w2qmwgjey7ksg.streamlit.app/"
11
- logs = ["Service started. Setting up Chrome driver..."]
12
 
13
  def add_log(message):
14
  timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
15
  logs.append(f"[{timestamp}] {message}")
16
- # Keep the last 30 logs in memory to show on the UI
17
  if len(logs) > 30:
18
  logs.pop(0)
19
 
20
  def visit_and_scroll():
21
  add_log(f"Started keeping alive {URL}...")
22
 
23
- options = Options()
24
- options.add_argument("--headless=new")
25
- # These flags are critically important for running Chrome inside a Docker container
26
- options.add_argument("--no-sandbox")
27
- options.add_argument("--disable-dev-shm-usage")
28
- options.add_argument("--disable-gpu")
29
- options.add_argument("--window-size=1920,1080")
30
-
31
- driver = None
32
  try:
33
- driver = webdriver.Chrome(options=options)
34
- driver.get(URL)
35
- time.sleep(8)
36
-
37
- total_height = driver.execute_script("return document.body.scrollHeight")
38
- add_log("Scrolling down naturally...")
39
- current_scroll = 0
40
- while current_scroll < total_height:
41
- scroll_step = random.randint(100, 500)
42
- current_scroll += scroll_step
43
- driver.execute_script(f"window.scrollTo(0, {current_scroll});")
44
- time.sleep(random.uniform(0.3, 1.2))
45
- new_height = driver.execute_script("return document.body.scrollHeight")
46
- if new_height > total_height:
47
- total_height = new_height
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
- add_log("Scrolling up naturally...")
50
- while current_scroll > 0:
51
- scroll_step = random.randint(100, 500)
52
- current_scroll -= scroll_step
53
- if current_scroll < 0:
54
- current_scroll = 0
55
- driver.execute_script(f"window.scrollTo(0, {current_scroll});")
56
- time.sleep(random.uniform(0.3, 1.2))
57
 
58
- add_log("Done navigating! Closing background browser...")
59
-
60
  except Exception as e:
61
  add_log(f"Error occurred: {e}")
62
- finally:
63
- if driver:
64
- time.sleep(2)
65
- driver.quit()
66
 
67
  def run_schedule():
68
- # Initial run upon startup
69
  visit_and_scroll()
70
-
71
- # Schedule to run every 1 hour
72
  schedule.every(1).hours.do(visit_and_scroll)
73
  while True:
74
  schedule.run_pending()
75
  time.sleep(60)
76
 
77
- # Start the keep-alive task in a background threading daemon
78
  thread = threading.Thread(target=run_schedule, daemon=True)
79
  thread.start()
80
 
81
  def get_logs():
82
  return "\n".join(logs)
83
 
84
- # Create a minimal Gradio UI specifically to satisfy Hugging Face Spaces port mapping
85
  with gr.Blocks() as demo:
86
- gr.Markdown("# 🤖 Keep-Alive Bot Status Panel")
87
- gr.Markdown(f"Currently maintaining a background connection to **{URL}** every 1 hour.")
88
  output = gr.Textbox(label="Live System Logs", lines=15, value=get_logs(), interactive=False)
89
  refresh_btn = gr.Button("Refresh Logs")
90
  refresh_btn.click(fn=get_logs, outputs=output)
91
 
92
- # Expose the port commonly used for HF Spaces deployments
93
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
2
  import threading
3
  import time
4
  import schedule
5
+ from playwright.sync_api import sync_playwright
 
6
  import random
7
  import datetime
8
 
9
  URL = "https://streamer1-gvbgwaea2w2qmwgjey7ksg.streamlit.app/"
10
+ logs = ["Service started. Waiting for next schedule..."]
11
 
12
  def add_log(message):
13
  timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
14
  logs.append(f"[{timestamp}] {message}")
 
15
  if len(logs) > 30:
16
  logs.pop(0)
17
 
18
  def visit_and_scroll():
19
  add_log(f"Started keeping alive {URL}...")
20
 
 
 
 
 
 
 
 
 
 
21
  try:
22
+ with sync_playwright() as p:
23
+ # Playwright handles headless browsers inside Docker flawlessly
24
+ browser = p.chromium.launch(headless=True, args=['--no-sandbox', '--disable-dev-shm-usage'])
25
+ page = browser.new_page()
26
+
27
+ # Open the Streamlit app
28
+ page.goto(URL, wait_until='networkidle')
29
+ time.sleep(8)
30
+
31
+ total_height = page.evaluate("document.body.scrollHeight")
32
+ add_log("Scrolling down naturally...")
33
+ current_scroll = 0
34
+ while current_scroll < total_height:
35
+ scroll_step = random.randint(100, 500)
36
+ current_scroll += scroll_step
37
+ page.evaluate(f"window.scrollTo(0, {current_scroll});")
38
+ time.sleep(random.uniform(0.3, 1.2))
39
+ new_height = page.evaluate("document.body.scrollHeight")
40
+ if new_height > total_height:
41
+ total_height = new_height
42
+
43
+ add_log("Scrolling up naturally...")
44
+ while current_scroll > 0:
45
+ scroll_step = random.randint(100, 500)
46
+ current_scroll -= scroll_step
47
+ if current_scroll < 0:
48
+ current_scroll = 0
49
+ page.evaluate(f"window.scrollTo(0, {current_scroll});")
50
+ time.sleep(random.uniform(0.3, 1.2))
51
 
52
+ add_log("Done navigating! Closing Playwright browser...")
53
+ browser.close()
 
 
 
 
 
 
54
 
 
 
55
  except Exception as e:
56
  add_log(f"Error occurred: {e}")
 
 
 
 
57
 
58
  def run_schedule():
 
59
  visit_and_scroll()
 
 
60
  schedule.every(1).hours.do(visit_and_scroll)
61
  while True:
62
  schedule.run_pending()
63
  time.sleep(60)
64
 
65
+ # Start background thread
66
  thread = threading.Thread(target=run_schedule, daemon=True)
67
  thread.start()
68
 
69
  def get_logs():
70
  return "\n".join(logs)
71
 
 
72
  with gr.Blocks() as demo:
73
+ gr.Markdown("# 🤖 Playwright Keep-Alive Status")
 
74
  output = gr.Textbox(label="Live System Logs", lines=15, value=get_logs(), interactive=False)
75
  refresh_btn = gr.Button("Refresh Logs")
76
  refresh_btn.click(fn=get_logs, outputs=output)
77
 
 
78
  demo.launch(server_name="0.0.0.0", server_port=7860)
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- selenium>=4.10.0
2
- schedule>=1.2.0
3
- gradio>=4.0.0
 
1
+ playwright
2
+ schedule
3
+ gradio