sonuprasad23 commited on
Commit
36fd3e9
·
1 Parent(s): b0a85e5
Files changed (2) hide show
  1. Dockerfile +22 -3
  2. worker.py +77 -19
Dockerfile CHANGED
@@ -8,7 +8,12 @@ ENV TZ=Etc/UTC
8
  ENV HOME=/home/appuser
9
  ENV PYTHONUSERBASE=/home/appuser/.local
10
 
11
- # System deps + Chromium + ChromeDriver + common headless libs
 
 
 
 
 
12
  RUN apt-get update && apt-get install -y --no-install-recommends \
13
  wget \
14
  gnupg \
@@ -24,11 +29,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
24
  libgtk-3-0 \
25
  libgbm1 \
26
  fonts-liberation \
 
 
 
 
 
 
 
 
 
27
  && rm -rf /var/lib/apt/lists/*
28
 
29
- # Create unprivileged user
30
  RUN addgroup --system appuser && adduser --system --ingroup appuser appuser
31
- RUN mkdir -p /home/appuser/.local && chown -R appuser:appuser /app /home/appuser
 
 
32
 
33
  USER appuser
34
 
@@ -39,6 +55,9 @@ ENV PATH="/home/appuser/.local/bin:${PATH}"
39
 
40
  COPY --chown=appuser:appuser . .
41
 
 
 
 
42
  EXPOSE 7860
43
 
44
  CMD ["python", "server.py"]
 
8
  ENV HOME=/home/appuser
9
  ENV PYTHONUSERBASE=/home/appuser/.local
10
 
11
+ # HuggingFace Spaces specific optimizations
12
+ ENV CHROME_BIN=/usr/bin/chromium
13
+ ENV CHROMEDRIVER_PATH=/usr/bin/chromedriver
14
+ ENV DISPLAY=:99
15
+
16
+ # System deps + Chromium + ChromeDriver + essential libs for HF Spaces
17
  RUN apt-get update && apt-get install -y --no-install-recommends \
18
  wget \
19
  gnupg \
 
29
  libgtk-3-0 \
30
  libgbm1 \
31
  fonts-liberation \
32
+ libappindicator3-1 \
33
+ libasound2 \
34
+ libdbus-glib-1-2 \
35
+ libdrm2 \
36
+ libxcomposite1 \
37
+ libxdamage1 \
38
+ libxrandr2 \
39
+ xvfb \
40
+ procps \
41
  && rm -rf /var/lib/apt/lists/*
42
 
43
+ # Create unprivileged user with proper permissions
44
  RUN addgroup --system appuser && adduser --system --ingroup appuser appuser
45
+ RUN mkdir -p /home/appuser/.local /tmp/chrome-temp && \
46
+ chown -R appuser:appuser /app /home/appuser /tmp/chrome-temp && \
47
+ chmod 755 /tmp/chrome-temp
48
 
49
  USER appuser
50
 
 
55
 
56
  COPY --chown=appuser:appuser . .
57
 
58
+ # Create config directory if needed
59
+ RUN mkdir -p config
60
+
61
  EXPOSE 7860
62
 
63
  CMD ["python", "server.py"]
worker.py CHANGED
@@ -1,6 +1,10 @@
1
  # worker.py
2
  import time
3
  import threading
 
 
 
 
4
 
5
  from selenium import webdriver
6
  from selenium.webdriver.chrome.service import Service as ChromeService
@@ -18,42 +22,83 @@ class QuantumBot:
18
  self.driver = None
19
  self.DEFAULT_TIMEOUT = 30
20
  self.termination_event = threading.Event()
 
 
 
 
 
 
 
 
 
 
21
 
22
  def initialize_driver(self):
23
  try:
24
  self.micro_status("Initializing headless browser...")
 
 
 
 
 
 
 
 
25
  options = ChromeOptions()
26
-
27
- # Use system Chromium installed in the image
28
- options.binary_location = "/usr/bin/chromium"
29
-
30
- # Do NOT set --user-data-dir; let ChromeDriver create a fresh temp profile per session
31
- # Use an ephemeral DevTools port to avoid collisions in constrained environments
32
- options.add_argument("--remote-debugging-port=0")
33
-
34
- # Stable/headless startup flags
35
- user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
36
- options.add_argument(f"--user-agent={user_agent}")
37
  options.add_argument("--headless=new")
38
- options.add_argument("--window-size=1920,1080")
39
- options.add_argument("--no-first-run")
40
- options.add_argument("--no-default-browser-check")
41
  options.add_argument("--no-sandbox")
42
  options.add_argument("--disable-dev-shm-usage")
43
  options.add_argument("--disable-gpu")
44
- options.add_argument("--disable-features=Translate,AutomationControlled")
45
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  service = ChromeService(executable_path="/usr/bin/chromedriver")
 
 
 
 
47
  self.driver = webdriver.Chrome(service=service, options=options)
48
-
49
  # Reduce webdriver detection
50
  self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
51
  'source': "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
52
  })
 
53
  return True, None
 
54
  except Exception as e:
55
  error_message = f"Message: {str(e)}"
56
  print(f"CRITICAL ERROR in WebDriver Initialization: {error_message}")
 
 
 
 
 
57
  return False, error_message
58
 
59
  def micro_status(self, message):
@@ -196,6 +241,19 @@ class QuantumBot:
196
  return 'Error'
197
 
198
  def shutdown(self):
199
- if self.driver:
200
- self.driver.quit()
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  print("[Bot] Chrome session closed.")
 
1
  # worker.py
2
  import time
3
  import threading
4
+ import tempfile
5
+ import shutil
6
+ import os
7
+ import subprocess
8
 
9
  from selenium import webdriver
10
  from selenium.webdriver.chrome.service import Service as ChromeService
 
22
  self.driver = None
23
  self.DEFAULT_TIMEOUT = 30
24
  self.termination_event = threading.Event()
25
+ self.temp_user_dir = None
26
+
27
+ def _kill_existing_chrome_processes(self):
28
+ """Kill any existing Chrome processes that might be locking directories"""
29
+ try:
30
+ subprocess.run(['pkill', '-f', 'chrome'], capture_output=True, text=True)
31
+ subprocess.run(['pkill', '-f', 'chromium'], capture_output=True, text=True)
32
+ time.sleep(2)
33
+ except Exception:
34
+ pass
35
 
36
  def initialize_driver(self):
37
  try:
38
  self.micro_status("Initializing headless browser...")
39
+
40
+ # Kill any existing Chrome processes first
41
+ self._kill_existing_chrome_processes()
42
+
43
+ # Create a completely isolated temporary directory for this session
44
+ self.temp_user_dir = tempfile.mkdtemp(prefix="hf-chrome-", dir="/tmp")
45
+ os.chmod(self.temp_user_dir, 0o755)
46
+
47
  options = ChromeOptions()
48
+
49
+ # Force Chrome to use our isolated temporary directory
50
+ options.add_argument(f"--user-data-dir={self.temp_user_dir}")
51
+ options.add_argument(f"--data-path={self.temp_user_dir}")
52
+ options.add_argument(f"--disk-cache-dir={self.temp_user_dir}/cache")
53
+
54
+ # HuggingFace Spaces specific optimizations
 
 
 
 
55
  options.add_argument("--headless=new")
 
 
 
56
  options.add_argument("--no-sandbox")
57
  options.add_argument("--disable-dev-shm-usage")
58
  options.add_argument("--disable-gpu")
59
+ options.add_argument("--disable-software-rasterizer")
60
+ options.add_argument("--disable-background-timer-throttling")
61
+ options.add_argument("--disable-backgrounding-occluded-windows")
62
+ options.add_argument("--disable-renderer-backgrounding")
63
+ options.add_argument("--disable-features=TranslateUI,BlinkGenPropertyTrees")
64
+ options.add_argument("--remote-debugging-port=0")
65
+ options.add_argument("--no-first-run")
66
+ options.add_argument("--no-default-browser-check")
67
+ options.add_argument("--disable-extensions")
68
+ options.add_argument("--disable-plugins")
69
+ options.add_argument("--disable-images")
70
+ options.add_argument("--disable-javascript")
71
+ options.add_argument("--window-size=1920,1080")
72
+
73
+ # Set user agent
74
+ user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
75
+ options.add_argument(f"--user-agent={user_agent}")
76
+
77
+ # Set binary location for HF Spaces
78
+ options.binary_location = "/usr/bin/chromium"
79
+
80
  service = ChromeService(executable_path="/usr/bin/chromedriver")
81
+
82
+ # Set service args for additional stability
83
+ service.service_args = ["--verbose", "--whitelisted-ips="]
84
+
85
  self.driver = webdriver.Chrome(service=service, options=options)
86
+
87
  # Reduce webdriver detection
88
  self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
89
  'source': "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
90
  })
91
+
92
  return True, None
93
+
94
  except Exception as e:
95
  error_message = f"Message: {str(e)}"
96
  print(f"CRITICAL ERROR in WebDriver Initialization: {error_message}")
97
+
98
+ # Cleanup on failure
99
+ if self.temp_user_dir and os.path.exists(self.temp_user_dir):
100
+ shutil.rmtree(self.temp_user_dir, ignore_errors=True)
101
+
102
  return False, error_message
103
 
104
  def micro_status(self, message):
 
241
  return 'Error'
242
 
243
  def shutdown(self):
244
+ try:
245
+ if self.driver:
246
+ self.driver.quit()
247
+
248
+ # Kill any remaining Chrome processes
249
+ self._kill_existing_chrome_processes()
250
+
251
+ # Clean up temporary directory
252
+ if self.temp_user_dir and os.path.exists(self.temp_user_dir):
253
+ shutil.rmtree(self.temp_user_dir, ignore_errors=True)
254
+ print(f"[Bot] Cleaned up temporary Chrome profile: {self.temp_user_dir}")
255
+
256
+ except Exception as e:
257
+ print(f"[Bot] Error during shutdown: {e}")
258
+
259
  print("[Bot] Chrome session closed.")