Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ninjaneural
GitHub Repository: ninjaneural/webui
Path: blob/master/misc/direct/v1.3.2/launch_utils.py
3275 views
1
# this scripts installs necessary requirements and launches main program in webui.py
2
import subprocess
3
import os
4
import sys
5
import importlib.util
6
import platform
7
import json
8
from functools import lru_cache
9
10
from modules import cmd_args
11
from modules.paths_internal import script_path, extensions_dir
12
13
args, _ = cmd_args.parser.parse_known_args()
14
15
python = sys.executable
16
git = os.environ.get('GIT', "git")
17
index_url = os.environ.get('INDEX_URL', "")
18
dir_repos = "repositories"
19
20
# Whether to default to printing command output
21
default_command_live = (os.environ.get('WEBUI_LAUNCH_LIVE_OUTPUT') == "1")
22
23
if 'GRADIO_ANALYTICS_ENABLED' not in os.environ:
24
os.environ['GRADIO_ANALYTICS_ENABLED'] = 'False'
25
26
27
def check_python_version():
28
is_windows = platform.system() == "Windows"
29
major = sys.version_info.major
30
minor = sys.version_info.minor
31
micro = sys.version_info.micro
32
33
if is_windows:
34
supported_minors = [10]
35
else:
36
supported_minors = [7, 8, 9, 10, 11]
37
38
if not (major == 3 and minor in supported_minors):
39
import modules.errors
40
41
modules.errors.print_error_explanation(f"""
42
INCOMPATIBLE PYTHON VERSION
43
44
This program is tested with 3.10.6 Python, but you have {major}.{minor}.{micro}.
45
If you encounter an error with "RuntimeError: Couldn't install torch." message,
46
or any other error regarding unsuccessful package (library) installation,
47
please downgrade (or upgrade) to the latest version of 3.10 Python
48
and delete current Python and "venv" folder in WebUI's directory.
49
50
You can download 3.10 Python from here: https://www.python.org/downloads/release/python-3106/
51
52
{"Alternatively, use a binary release of WebUI: https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases" if is_windows else ""}
53
54
Use --skip-python-version-check to suppress this warning.
55
""")
56
57
58
@lru_cache()
59
def commit_hash():
60
try:
61
return subprocess.check_output([git, "rev-parse", "HEAD"], shell=False, encoding='utf8').strip()
62
except Exception:
63
return "<none>"
64
65
66
@lru_cache()
67
def git_tag():
68
try:
69
return subprocess.check_output([git, "describe", "--tags"], shell=False, encoding='utf8').strip()
70
except Exception:
71
return "<none>"
72
73
74
def run(command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live) -> str:
75
if desc is not None:
76
print(desc)
77
78
run_kwargs = {
79
"args": command,
80
"shell": True,
81
"env": os.environ if custom_env is None else custom_env,
82
"encoding": 'utf8',
83
"errors": 'ignore',
84
}
85
86
if not live:
87
run_kwargs["stdout"] = run_kwargs["stderr"] = subprocess.PIPE
88
89
result = subprocess.run(**run_kwargs)
90
91
if result.returncode != 0:
92
error_bits = [
93
f"{errdesc or 'Error running command'}.",
94
f"Command: {command}",
95
f"Error code: {result.returncode}",
96
]
97
if result.stdout:
98
error_bits.append(f"stdout: {result.stdout}")
99
if result.stderr:
100
error_bits.append(f"stderr: {result.stderr}")
101
raise RuntimeError("\n".join(error_bits))
102
103
return (result.stdout or "")
104
105
106
def is_installed(package):
107
try:
108
spec = importlib.util.find_spec(package)
109
except ModuleNotFoundError:
110
return False
111
112
return spec is not None
113
114
115
def repo_dir(name):
116
return os.path.join(script_path, dir_repos, name)
117
118
119
def run_pip(command, desc=None, live=default_command_live):
120
if args.skip_install:
121
return
122
123
index_url_line = f' --index-url {index_url}' if index_url != '' else ''
124
return run(f'"{python}" -m pip {command} --prefer-binary{index_url_line}', desc=f"Installing {desc}", errdesc=f"Couldn't install {desc}", live=live)
125
126
127
def check_run_python(code: str) -> bool:
128
result = subprocess.run([python, "-c", code], capture_output=True, shell=False)
129
return result.returncode == 0
130
131
132
def git_clone(url, dir, name, commithash=None):
133
# TODO clone into temporary dir and move if successful
134
135
if os.path.exists(dir):
136
if commithash is None:
137
return
138
139
current_hash = run(f'"{git}" -C "{dir}" rev-parse HEAD', None, f"Couldn't determine {name}'s hash: {commithash}").strip()
140
if current_hash == commithash:
141
return
142
143
run(f'"{git}" -C "{dir}" fetch', f"Fetching updates for {name}...", f"Couldn't fetch {name}")
144
run(f'"{git}" -C "{dir}" reset --hard {commithash}', f"Checking out commit for {name} with hash: {commithash}...", f"Couldn't checkout commit {commithash} for {name}")
145
return
146
147
run(f'"{git}" clone "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}")
148
149
if commithash is not None:
150
run(f'"{git}" -C "{dir}" reset --hard {commithash}', None, "Couldn't checkout {name}'s hash: {commithash}")
151
152
153
def git_pull_recursive(dir):
154
for subdir, _, _ in os.walk(dir):
155
if os.path.exists(os.path.join(subdir, '.git')):
156
try:
157
output = subprocess.check_output([git, '-C', subdir, 'pull', '--autostash'])
158
print(f"Pulled changes for repository in '{subdir}':\n{output.decode('utf-8').strip()}\n")
159
except subprocess.CalledProcessError as e:
160
print(f"Couldn't perform 'git pull' on repository in '{subdir}':\n{e.output.decode('utf-8').strip()}\n")
161
162
163
def version_check(commit):
164
try:
165
import requests
166
commits = requests.get('https://api.github.com/repos/AUTOMATIC1111/stable-diffusion-webui/branches/master').json()
167
if commit != "<none>" and commits['commit']['sha'] != commit:
168
print("--------------------------------------------------------")
169
print("| You are not up to date with the most recent release. |")
170
print("| Consider running `git pull` to update. |")
171
print("--------------------------------------------------------")
172
elif commits['commit']['sha'] == commit:
173
print("You are up to date with the most recent release.")
174
else:
175
print("Not a git clone, can't perform version check.")
176
except Exception as e:
177
print("version check failed", e)
178
179
180
def run_extension_installer(extension_dir):
181
path_installer = os.path.join(extension_dir, "install.py")
182
if not os.path.isfile(path_installer):
183
return
184
185
try:
186
env = os.environ.copy()
187
env['PYTHONPATH'] = os.path.abspath(".")
188
189
print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env))
190
except Exception as e:
191
print(e, file=sys.stderr)
192
193
194
def list_extensions(settings_file):
195
settings = {}
196
197
try:
198
if os.path.isfile(settings_file):
199
with open(settings_file, "r", encoding="utf8") as file:
200
settings = json.load(file)
201
except Exception as e:
202
print(e, file=sys.stderr)
203
204
disabled_extensions = set(settings.get('disabled_extensions', []))
205
disable_all_extensions = settings.get('disable_all_extensions', 'none')
206
207
if disable_all_extensions != 'none':
208
return []
209
210
return [x for x in os.listdir(extensions_dir) if x not in disabled_extensions]
211
212
213
def run_extensions_installers(settings_file):
214
if not os.path.isdir(extensions_dir):
215
return
216
217
for dirname_extension in list_extensions(settings_file):
218
run_extension_installer(os.path.join(extensions_dir, dirname_extension))
219
220
221
def prepare_environment():
222
torch_index_url = os.environ.get('TORCH_INDEX_URL', "https://download.pytorch.org/whl/cu118")
223
torch_command = os.environ.get('TORCH_COMMAND', f"pip install torch==2.0.1 torchvision==0.15.2 --extra-index-url {torch_index_url}")
224
requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")
225
226
xformers_package = os.environ.get('XFORMERS_PACKAGE', 'xformers==0.0.17')
227
gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "https://github.com/TencentARC/GFPGAN/archive/8d2447a2d918f8eba5a4a01463fd48e45126a379.zip")
228
clip_package = os.environ.get('CLIP_PACKAGE', "https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip")
229
openclip_package = os.environ.get('OPENCLIP_PACKAGE', "https://github.com/mlfoundations/open_clip/archive/bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b.zip")
230
231
stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/Stability-AI/stablediffusion.git")
232
taming_transformers_repo = os.environ.get('TAMING_TRANSFORMERS_REPO', "https://github.com/CompVis/taming-transformers.git")
233
k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')
234
codeformer_repo = os.environ.get('CODEFORMER_REPO', 'https://github.com/sczhou/CodeFormer.git')
235
blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')
236
237
stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf")
238
taming_transformers_commit_hash = os.environ.get('TAMING_TRANSFORMERS_COMMIT_HASH', "24268930bf1dce879235a7fddd0b2355b84d7ea6")
239
k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "c9fe758757e022f05ca5a53fa8fac28889e4f1cf")
240
codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH', "c5b4593074ba6214284d6acd5f1719b6c5d739af")
241
blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH', "48211a1594f1321b00f14c9f7a5b4813144b2fb9")
242
243
if not args.skip_python_version_check:
244
check_python_version()
245
246
commit = commit_hash()
247
tag = git_tag()
248
249
print(f"Python {sys.version}")
250
print(f"Version: {tag}")
251
print(f"Commit hash: {commit}")
252
253
if args.reinstall_torch or not is_installed("torch") or not is_installed("torchvision"):
254
run(f'"{python}" -m {torch_command}', "Installing torch and torchvision", "Couldn't install torch", live=True)
255
256
if not args.skip_torch_cuda_test and not check_run_python("import torch; assert torch.cuda.is_available()"):
257
raise RuntimeError(
258
'Torch is not able to use GPU; '
259
'add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check'
260
)
261
262
if not is_installed("gfpgan"):
263
run_pip(f"install {gfpgan_package}", "gfpgan")
264
265
if not is_installed("clip"):
266
run_pip(f"install {clip_package}", "clip")
267
268
if not is_installed("open_clip"):
269
run_pip(f"install {openclip_package}", "open_clip")
270
271
if (not is_installed("xformers") or args.reinstall_xformers) and args.xformers:
272
if platform.system() == "Windows":
273
if platform.python_version().startswith("3.10"):
274
run_pip(f"install -U -I --no-deps {xformers_package}", "xformers", live=True)
275
else:
276
print("Installation of xformers is not supported in this version of Python.")
277
print("You can also check this and build manually: https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers#building-xformers-on-windows-by-duckness")
278
if not is_installed("xformers"):
279
exit(0)
280
elif platform.system() == "Linux":
281
run_pip(f"install -U -I --no-deps {xformers_package}", "xformers")
282
283
if not is_installed("ngrok") and args.ngrok:
284
run_pip("install ngrok", "ngrok")
285
286
os.makedirs(os.path.join(script_path, dir_repos), exist_ok=True)
287
288
git_clone(stable_diffusion_repo, repo_dir('stable-diffusion-stability-ai'), "Stable Diffusion", stable_diffusion_commit_hash)
289
git_clone(taming_transformers_repo, repo_dir('taming-transformers'), "Taming Transformers", taming_transformers_commit_hash)
290
git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
291
git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
292
git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash)
293
294
if not is_installed("lpips"):
295
run_pip(f"install -r \"{os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}\"", "requirements for CodeFormer")
296
297
if not os.path.isfile(requirements_file):
298
requirements_file = os.path.join(script_path, requirements_file)
299
run_pip(f"install -r \"{requirements_file}\"", "requirements")
300
301
run_extensions_installers(settings_file=args.ui_settings_file)
302
303
if args.update_check:
304
version_check(commit)
305
306
if args.update_all_extensions:
307
git_pull_recursive(extensions_dir)
308
309
if "--exit" in sys.argv:
310
print("Exiting because of --exit argument")
311
exit(0)
312
313
314
def configure_for_tests():
315
if "--api" not in sys.argv:
316
sys.argv.append("--api")
317
if "--ckpt" not in sys.argv:
318
sys.argv.append("--ckpt")
319
sys.argv.append(os.path.join(script_path, "test/test_files/empty.pt"))
320
if "--skip-torch-cuda-test" not in sys.argv:
321
sys.argv.append("--skip-torch-cuda-test")
322
if "--disable-nan-check" not in sys.argv:
323
sys.argv.append("--disable-nan-check")
324
325
os.environ['COMMANDLINE_ARGS'] = ""
326
327
328
def start():
329
print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")
330
import webui
331
if '--nowebui' in sys.argv:
332
webui.api_only()
333
else:
334
webui.webui()
335
336