Nathyboy commited on
Commit
576633b
Β·
verified Β·
1 Parent(s): 1173096

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -88
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # app.py - HF Space launcher (Option B, HF tree aware, auto-open WebUI)
2
  import os
3
  import subprocess
4
  import threading
@@ -6,10 +6,10 @@ import shlex
6
  import time
7
  import requests
8
  import gradio as gr
9
- import webbrowser
10
 
11
  # -----------------------------
12
- # Configuration (edit if needed)
13
  # -----------------------------
14
  DOWNLOADS = {
15
  "lora": {
@@ -31,13 +31,13 @@ DOWNLOADS = {
31
  }
32
 
33
  WEBUI_ARGS = "--listen --xformers --enable-insecure-extension-access --medvram"
34
- LAUNCH_PY = "launch.py" # relative to repo root (per HF tree)
35
 
36
  # -----------------------------
37
  # Utilities
38
  # -----------------------------
39
- def ensure_persistent_folders():
40
- """Make sure HF tree persistent folders exist (safe no-op if present)."""
41
  folders = [
42
  "stable-diffusion-webui/deforum/input",
43
  "stable-diffusion-webui/deforum/output_committed/frames",
@@ -50,127 +50,91 @@ def ensure_persistent_folders():
50
  os.makedirs(f, exist_ok=True)
51
  print("βœ… Persistent folders ensured.")
52
 
53
-
54
- def download_file_with_retries(url, dest, max_retries=3, backoff=5):
55
- """Download a file with simple retry/backoff. Skips if dest exists."""
56
  if os.path.exists(dest):
57
  print(f"βœ… Already exists: {dest}")
58
  return True
59
-
60
  os.makedirs(os.path.dirname(dest), exist_ok=True)
61
- attempt = 1
62
- while attempt <= max_retries:
63
  try:
64
- print(f"⬇️ Download attempt {attempt}: {url} -> {dest}")
65
  with requests.get(url, stream=True, timeout=60) as r:
66
  r.raise_for_status()
67
  with open(dest + ".part", "wb") as f:
68
  for chunk in r.iter_content(chunk_size=8192):
69
  if chunk:
70
  f.write(chunk)
71
- # atomically move into place
72
  os.replace(dest + ".part", dest)
73
  print(f"βœ… Downloaded: {dest}")
74
  return True
75
  except Exception as e:
76
- print(f"⚠️ Download failed (attempt {attempt}) for {url}: {e}")
77
- attempt += 1
78
  time.sleep(backoff * attempt)
79
- print(f"❌ Failed to download after {max_retries} attempts: {url}")
80
- # ensure partial file removed
81
- try:
82
- if os.path.exists(dest + ".part"):
83
- os.remove(dest + ".part")
84
- except Exception:
85
- pass
86
  return False
87
 
88
-
89
  def fetch_models():
90
- """Download all configured models into the HF tree persistent paths."""
91
- print("πŸ”½ Starting runtime model downloads (if missing)...")
92
- success_all = True
93
- for name, info in DOWNLOADS.items():
94
- url = info["url"]
95
- dest = info["dest"]
96
- ok = download_file_with_retries(url, dest)
97
- success_all = success_all and ok
98
- if success_all:
99
- print("βœ… All runtime downloads done (or already present).")
100
- else:
101
- print("⚠️ Some runtime downloads failed. Check logs for details.")
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  # -----------------------------
105
- # Start WebUI routine (clean + auto open)
106
  # -----------------------------
107
  def start_webui():
108
- """
109
- Option B β€” background WebUI launcher aware of HF tree and persistent folders.
110
- 1) Ensure persistent folders exist.
111
- 2) Download missing runtime models.
112
- 3) Launch Automatic1111 WebUI (launch.py) with correct PORT binding.
113
- 4) Automatically open WebUI URL when ready.
114
- """
115
- try:
116
- ensure_persistent_folders()
117
- fetch_models()
118
 
119
- port = int(os.environ.get("PORT", 7860))
120
- cmd = ["python", LAUNCH_PY] + shlex.split(WEBUI_ARGS) + [f"--port {port}"]
121
- print("▢️ Launching WebUI with:", " ".join(cmd))
122
 
123
- # Launch launch.py and capture stdout
124
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
125
-
126
- for line in iter(proc.stdout.readline, ""):
127
- print(line, end="") # Show logs in HF Space logs
128
-
129
- # Detect URL line
130
- if "Running on local URL:" in line or "Running on" in line:
131
- url_start = line.find("http")
132
- if url_start != -1:
133
- url = line[url_start:].strip()
134
- print(f"🌐 WebUI ready: {url} β€” opening automatically")
135
- webbrowser.open(url)
136
-
137
- proc.wait()
138
  print("ℹ️ launch.py exited normally.")
139
- except subprocess.CalledProcessError as cpe:
140
- print(f"❌ launch.py exited with non-zero status: {cpe.returncode}")
141
  except Exception as e:
142
- print("❌ Exception in start_webui():", e)
143
 
144
-
145
- # -----------------------------
146
- # Kick off WebUI in background thread
147
- # -----------------------------
148
  threading.Thread(target=start_webui, daemon=True).start()
149
- print("🧡 WebUI thread started (background).")
150
 
151
  # -----------------------------
152
- # Minimal Gradio UI to keep Space alive + quick controls
153
  # -----------------------------
154
  def show_status():
155
- msg_lines = ["βœ… HF Space running (Option B launcher)."]
156
- # quick presence checks
157
- if os.path.exists(LAUNCH_PY):
158
- msg_lines.append(f"launch.py: found")
159
- else:
160
- msg_lines.append(f"launch.py: MISSING at root!")
161
- # list basic model presence
162
  for key, info in DOWNLOADS.items():
163
  present = "yes" if os.path.exists(info["dest"]) else "no"
164
- msg_lines.append(f"{key}: {present}")
165
- return "\n".join(msg_lines)
166
-
167
 
168
  with gr.Blocks() as demo:
169
  gr.Markdown("## Automatic1111 WebUI β€” HF Space launcher (Option B)")
170
- gr.Markdown(
171
- "This Space launches Automatic1111 in a background thread and keeps a small Gradio UI alive "
172
- "so Hugging Face marks the app as initialized."
173
- )
174
  status_btn = gr.Button("Check status")
175
  status_out = gr.Textbox(lines=10)
176
  status_btn.click(fn=show_status, inputs=None, outputs=status_out)
 
1
+ # app.py - HF Space launcher (Option B, HF tree aware, clean logs)
2
  import os
3
  import subprocess
4
  import threading
 
6
  import time
7
  import requests
8
  import gradio as gr
9
+ import socket
10
 
11
  # -----------------------------
12
+ # Configuration
13
  # -----------------------------
14
  DOWNLOADS = {
15
  "lora": {
 
31
  }
32
 
33
  WEBUI_ARGS = "--listen --xformers --enable-insecure-extension-access --medvram"
34
+ LAUNCH_PY = "launch.py" # root of repo
35
 
36
  # -----------------------------
37
  # Utilities
38
  # -----------------------------
39
+ def ensure_folders():
40
+ """Ensure HF tree persistent folders exist."""
41
  folders = [
42
  "stable-diffusion-webui/deforum/input",
43
  "stable-diffusion-webui/deforum/output_committed/frames",
 
50
  os.makedirs(f, exist_ok=True)
51
  print("βœ… Persistent folders ensured.")
52
 
53
+ def download_file(url, dest, retries=3, backoff=5):
54
+ """Download a file if missing, with retries."""
 
55
  if os.path.exists(dest):
56
  print(f"βœ… Already exists: {dest}")
57
  return True
 
58
  os.makedirs(os.path.dirname(dest), exist_ok=True)
59
+ for attempt in range(1, retries + 1):
 
60
  try:
61
+ print(f"⬇️ Download attempt {attempt}: {url}")
62
  with requests.get(url, stream=True, timeout=60) as r:
63
  r.raise_for_status()
64
  with open(dest + ".part", "wb") as f:
65
  for chunk in r.iter_content(chunk_size=8192):
66
  if chunk:
67
  f.write(chunk)
 
68
  os.replace(dest + ".part", dest)
69
  print(f"βœ… Downloaded: {dest}")
70
  return True
71
  except Exception as e:
72
+ print(f"⚠️ Attempt {attempt} failed: {e}")
 
73
  time.sleep(backoff * attempt)
74
+ print(f"❌ Failed to download: {dest}")
 
 
 
 
 
 
75
  return False
76
 
 
77
  def fetch_models():
78
+ print("πŸ”½ Fetching runtime models...")
79
+ for key, info in DOWNLOADS.items():
80
+ download_file(info["url"], info["dest"])
81
+ print("βœ… Model downloads done.")
 
 
 
 
 
 
 
 
82
 
83
+ # -----------------------------
84
+ # Check if port is free
85
+ # -----------------------------
86
+ def wait_for_port(port, host="127.0.0.1", timeout=120):
87
+ """Wait until the WebUI port is open."""
88
+ start = time.time()
89
+ while time.time() - start < timeout:
90
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
91
+ try:
92
+ s.connect((host, port))
93
+ return True
94
+ except:
95
+ time.sleep(1)
96
+ return False
97
 
98
  # -----------------------------
99
+ # Start WebUI thread
100
  # -----------------------------
101
  def start_webui():
102
+ ensure_folders()
103
+ fetch_models()
 
 
 
 
 
 
 
 
104
 
105
+ port = int(os.environ.get("PORT", 7860))
106
+ cmd = ["python", LAUNCH_PY] + shlex.split(WEBUI_ARGS) + [f"--port {port}"]
107
+ print("▢️ Launching WebUI with:", " ".join(cmd))
108
 
109
+ # Run launch.py once; logs go to HF logs
110
+ try:
111
+ subprocess.run(cmd, check=True)
 
 
 
 
 
 
 
 
 
 
 
 
112
  print("ℹ️ launch.py exited normally.")
113
+ except subprocess.CalledProcessError as e:
114
+ print(f"❌ launch.py failed: {e}")
115
  except Exception as e:
116
+ print(f"❌ Exception: {e}")
117
 
 
 
 
 
118
  threading.Thread(target=start_webui, daemon=True).start()
119
+ print("🧡 WebUI background thread started.")
120
 
121
  # -----------------------------
122
+ # Gradio UI
123
  # -----------------------------
124
  def show_status():
125
+ port = int(os.environ.get("PORT", 7860))
126
+ url = f"http://localhost:{port}"
127
+ lines = ["βœ… HF Space running (Option B launcher)."]
128
+ lines.append(f"WebUI URL: [Click here]({url}) (opens in browser when ready)")
129
+ # Check models
 
 
130
  for key, info in DOWNLOADS.items():
131
  present = "yes" if os.path.exists(info["dest"]) else "no"
132
+ lines.append(f"{key}: {present}")
133
+ return "\n".join(lines)
 
134
 
135
  with gr.Blocks() as demo:
136
  gr.Markdown("## Automatic1111 WebUI β€” HF Space launcher (Option B)")
137
+ gr.Markdown("This Space launches Automatic1111 in a background thread and keeps a small Gradio UI alive.")
 
 
 
138
  status_btn = gr.Button("Check status")
139
  status_out = gr.Textbox(lines=10)
140
  status_btn.click(fn=show_status, inputs=None, outputs=status_out)