ninjaneural commited on
Commit
e1b7d6c
·
verified ·
1 Parent(s): ce26ca2

Upload 20 files

Browse files
.gitattributes CHANGED
@@ -32,3 +32,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ direct/v1.3.2/repositories.tar filter=lfs diff=lfs merge=lfs -text
36
+ direct/v1.4.1/repositories.tar filter=lfs diff=lfs merge=lfs -text
37
+ direct/v1.5.2/repositories.tar filter=lfs diff=lfs merge=lfs -text
38
+ direct/v1.6.0/repositories.tar filter=lfs diff=lfs merge=lfs -text
39
+ direct/v1.7.0/repositories.tar filter=lfs diff=lfs merge=lfs -text
direct/v1.3.2/directui.py ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import sys
5
+ import time
6
+ import importlib
7
+ import signal
8
+ import re
9
+ import warnings
10
+ import json
11
+ from threading import Thread
12
+ from typing import Iterable
13
+
14
+ from fastapi import FastAPI, Response
15
+ from fastapi.middleware.cors import CORSMiddleware
16
+ from fastapi.middleware.gzip import GZipMiddleware
17
+ from packaging import version
18
+
19
+ import logging
20
+
21
+ logging.getLogger("xformers").addFilter(lambda record: 'A matching Triton is not available' not in record.getMessage())
22
+
23
+ from modules import paths, timer, import_hook, errors # noqa: F401
24
+
25
+ startup_timer = timer.Timer()
26
+
27
+ import torch
28
+ import pytorch_lightning # noqa: F401 # pytorch_lightning should be imported after torch, but it re-enables warnings on import so import once to disable them
29
+ warnings.filterwarnings(action="ignore", category=DeprecationWarning, module="pytorch_lightning")
30
+ warnings.filterwarnings(action="ignore", category=UserWarning, module="torchvision")
31
+
32
+
33
+ startup_timer.record("import torch")
34
+
35
+ import gradio
36
+ startup_timer.record("import gradio")
37
+
38
+ import ldm.modules.encoders.modules # noqa: F401
39
+ startup_timer.record("import ldm")
40
+
41
+ from modules import extra_networks
42
+ from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, queue_lock # noqa: F401
43
+
44
+ # Truncate version number of nightly/local build of PyTorch to not cause exceptions with CodeFormer or Safetensors
45
+ if ".dev" in torch.__version__ or "+git" in torch.__version__:
46
+ torch.__long_version__ = torch.__version__
47
+ torch.__version__ = re.search(r'[\d.]+[\d]', torch.__version__).group(0)
48
+
49
+ from modules import shared, sd_samplers, upscaler, extensions, localization, ui_tempdir, ui_extra_networks, config_states
50
+ import modules.codeformer_model as codeformer
51
+ import modules.face_restoration
52
+ import modules.gfpgan_model as gfpgan
53
+ import modules.img2img
54
+
55
+ import modules.lowvram
56
+ import modules.scripts
57
+ import modules.sd_hijack
58
+ import modules.sd_hijack_optimizations
59
+ import modules.sd_models
60
+ import modules.sd_vae
61
+ import modules.txt2img
62
+ import modules.script_callbacks
63
+ import modules.textual_inversion.textual_inversion
64
+ import modules.progress
65
+
66
+ import modules.ui
67
+ from modules import modelloader
68
+ from modules.shared import cmd_opts
69
+ import modules.hypernetworks.hypernetwork
70
+
71
+ startup_timer.record("other imports")
72
+
73
+
74
+ if cmd_opts.server_name:
75
+ server_name = cmd_opts.server_name
76
+ else:
77
+ server_name = "0.0.0.0" if cmd_opts.listen else None
78
+
79
+
80
+ def fix_asyncio_event_loop_policy():
81
+ """
82
+ The default `asyncio` event loop policy only automatically creates
83
+ event loops in the main threads. Other threads must create event
84
+ loops explicitly or `asyncio.get_event_loop` (and therefore
85
+ `.IOLoop.current`) will fail. Installing this policy allows event
86
+ loops to be created automatically on any thread, matching the
87
+ behavior of Tornado versions prior to 5.0 (or 5.0 on Python 2).
88
+ """
89
+
90
+ import asyncio
91
+
92
+ if sys.platform == "win32" and hasattr(asyncio, "WindowsSelectorEventLoopPolicy"):
93
+ # "Any thread" and "selector" should be orthogonal, but there's not a clean
94
+ # interface for composing policies so pick the right base.
95
+ _BasePolicy = asyncio.WindowsSelectorEventLoopPolicy # type: ignore
96
+ else:
97
+ _BasePolicy = asyncio.DefaultEventLoopPolicy
98
+
99
+ class AnyThreadEventLoopPolicy(_BasePolicy): # type: ignore
100
+ """Event loop policy that allows loop creation on any thread.
101
+ Usage::
102
+
103
+ asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
104
+ """
105
+
106
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
107
+ try:
108
+ return super().get_event_loop()
109
+ except (RuntimeError, AssertionError):
110
+ # This was an AssertionError in python 3.4.2 (which ships with debian jessie)
111
+ # and changed to a RuntimeError in 3.4.3.
112
+ # "There is no current event loop in thread %r"
113
+ loop = self.new_event_loop()
114
+ self.set_event_loop(loop)
115
+ return loop
116
+
117
+ asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
118
+
119
+
120
+ def check_versions():
121
+ if shared.cmd_opts.skip_version_check:
122
+ return
123
+
124
+ expected_torch_version = "2.0.0"
125
+
126
+ if version.parse(torch.__version__) < version.parse(expected_torch_version):
127
+ errors.print_error_explanation(f"""
128
+ You are running torch {torch.__version__}.
129
+ The program is tested to work with torch {expected_torch_version}.
130
+ To reinstall the desired version, run with commandline flag --reinstall-torch.
131
+ Beware that this will cause a lot of large files to be downloaded, as well as
132
+ there are reports of issues with training tab on the latest version.
133
+
134
+ Use --skip-version-check commandline argument to disable this check.
135
+ """.strip())
136
+
137
+ expected_xformers_version = "0.0.17"
138
+ if shared.xformers_available:
139
+ import xformers
140
+
141
+ if version.parse(xformers.__version__) < version.parse(expected_xformers_version):
142
+ errors.print_error_explanation(f"""
143
+ You are running xformers {xformers.__version__}.
144
+ The program is tested to work with xformers {expected_xformers_version}.
145
+ To reinstall the desired version, run with commandline flag --reinstall-xformers.
146
+
147
+ Use --skip-version-check commandline argument to disable this check.
148
+ """.strip())
149
+
150
+
151
+ def restore_config_state_file():
152
+ config_state_file = shared.opts.restore_config_state_file
153
+ if config_state_file == "":
154
+ return
155
+
156
+ shared.opts.restore_config_state_file = ""
157
+ shared.opts.save(shared.config_filename)
158
+
159
+ if os.path.isfile(config_state_file):
160
+ print(f"*** About to restore extension state from file: {config_state_file}")
161
+ with open(config_state_file, "r", encoding="utf-8") as f:
162
+ config_state = json.load(f)
163
+ config_states.restore_extension_config(config_state)
164
+ startup_timer.record("restore extension config")
165
+ elif config_state_file:
166
+ print(f"!!! Config state backup not found: {config_state_file}")
167
+
168
+
169
+ def validate_tls_options():
170
+ if not (cmd_opts.tls_keyfile and cmd_opts.tls_certfile):
171
+ return
172
+
173
+ try:
174
+ if not os.path.exists(cmd_opts.tls_keyfile):
175
+ print("Invalid path to TLS keyfile given")
176
+ if not os.path.exists(cmd_opts.tls_certfile):
177
+ print(f"Invalid path to TLS certfile: '{cmd_opts.tls_certfile}'")
178
+ except TypeError:
179
+ cmd_opts.tls_keyfile = cmd_opts.tls_certfile = None
180
+ print("TLS setup invalid, running webui without TLS")
181
+ else:
182
+ print("Running with TLS")
183
+ startup_timer.record("TLS")
184
+
185
+
186
+ def get_gradio_auth_creds() -> Iterable[tuple[str, ...]]:
187
+ """
188
+ Convert the gradio_auth and gradio_auth_path commandline arguments into
189
+ an iterable of (username, password) tuples.
190
+ """
191
+ def process_credential_line(s) -> tuple[str, ...] | None:
192
+ s = s.strip()
193
+ if not s:
194
+ return None
195
+ return tuple(s.split(':', 1))
196
+
197
+ if cmd_opts.gradio_auth:
198
+ for cred in cmd_opts.gradio_auth.split(','):
199
+ cred = process_credential_line(cred)
200
+ if cred:
201
+ yield cred
202
+
203
+ if cmd_opts.gradio_auth_path:
204
+ with open(cmd_opts.gradio_auth_path, 'r', encoding="utf8") as file:
205
+ for line in file.readlines():
206
+ for cred in line.strip().split(','):
207
+ cred = process_credential_line(cred)
208
+ if cred:
209
+ yield cred
210
+
211
+
212
+ def configure_sigint_handler():
213
+ # make the program just exit at ctrl+c without waiting for anything
214
+ def sigint_handler(sig, frame):
215
+ print(f'Interrupted with signal {sig} in {frame}')
216
+ os._exit(0)
217
+
218
+ if not os.environ.get("COVERAGE_RUN"):
219
+ # Don't install the immediate-quit handler when running under coverage,
220
+ # as then the coverage report won't be generated.
221
+ signal.signal(signal.SIGINT, sigint_handler)
222
+
223
+
224
+ def configure_opts_onchange():
225
+ shared.opts.onchange("sd_model_checkpoint", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()), call=False)
226
+ shared.opts.onchange("sd_vae", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
227
+ shared.opts.onchange("sd_vae_as_default", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
228
+ shared.opts.onchange("temp_dir", ui_tempdir.on_tmpdir_changed)
229
+ shared.opts.onchange("gradio_theme", shared.reload_gradio_theme)
230
+ shared.opts.onchange("cross_attention_optimization", wrap_queued_call(lambda: modules.sd_hijack.model_hijack.redo_hijack(shared.sd_model)), call=False)
231
+ startup_timer.record("opts onchange")
232
+
233
+
234
+ def initialize():
235
+ fix_asyncio_event_loop_policy()
236
+ validate_tls_options()
237
+ configure_sigint_handler()
238
+ check_versions()
239
+ modelloader.cleanup_models()
240
+ configure_opts_onchange()
241
+
242
+ modules.sd_models.setup_model()
243
+ startup_timer.record("setup SD model")
244
+
245
+ codeformer.setup_model(cmd_opts.codeformer_models_path)
246
+ startup_timer.record("setup codeformer")
247
+
248
+ gfpgan.setup_model(cmd_opts.gfpgan_models_path)
249
+ startup_timer.record("setup gfpgan")
250
+
251
+ initialize_rest(reload_script_modules=False)
252
+
253
+
254
+ def initialize_rest(*, reload_script_modules=False):
255
+ """
256
+ Called both from initialize() and when reloading the webui.
257
+ """
258
+ sd_samplers.set_samplers()
259
+ extensions.list_extensions()
260
+ startup_timer.record("list extensions")
261
+
262
+ restore_config_state_file()
263
+
264
+ if cmd_opts.ui_debug_mode:
265
+ shared.sd_upscalers = upscaler.UpscalerLanczos().scalers
266
+ modules.scripts.load_scripts()
267
+ return
268
+
269
+ modules.sd_models.list_models()
270
+ startup_timer.record("list SD models")
271
+
272
+ localization.list_localizations(cmd_opts.localizations_dir)
273
+
274
+ modules.scripts.load_scripts()
275
+ startup_timer.record("load scripts")
276
+
277
+ if reload_script_modules:
278
+ for module in [module for name, module in sys.modules.items() if name.startswith("modules.ui")]:
279
+ importlib.reload(module)
280
+ startup_timer.record("reload script modules")
281
+
282
+ modelloader.load_upscalers()
283
+ startup_timer.record("load upscalers")
284
+
285
+ modules.sd_vae.refresh_vae_list()
286
+ startup_timer.record("refresh VAE")
287
+ modules.textual_inversion.textual_inversion.list_textual_inversion_templates()
288
+ startup_timer.record("refresh textual inversion templates")
289
+
290
+ modules.script_callbacks.on_list_optimizers(modules.sd_hijack_optimizations.list_optimizers)
291
+ modules.sd_hijack.list_optimizers()
292
+ startup_timer.record("scripts list_optimizers")
293
+
294
+ def load_model():
295
+ """
296
+ Accesses shared.sd_model property to load model.
297
+ After it's available, if it has been loaded before this access by some extension,
298
+ its optimization may be None because the list of optimizaers has neet been filled
299
+ by that time, so we apply optimization again.
300
+ """
301
+
302
+ shared.sd_model # noqa: B018
303
+
304
+ if modules.sd_hijack.current_optimizer is None:
305
+ modules.sd_hijack.apply_optimizations()
306
+
307
+ Thread(target=load_model).start()
308
+
309
+ shared.reload_hypernetworks()
310
+ startup_timer.record("reload hypernetworks")
311
+
312
+ ui_extra_networks.initialize()
313
+ ui_extra_networks.register_default_pages()
314
+
315
+ extra_networks.initialize()
316
+ extra_networks.register_default_extra_networks()
317
+ startup_timer.record("initialize extra networks")
318
+
319
+
320
+ def setup_middleware(app):
321
+ app.middleware_stack = None # reset current middleware to allow modifying user provided list
322
+ app.add_middleware(GZipMiddleware, minimum_size=1000)
323
+ configure_cors_middleware(app)
324
+ app.build_middleware_stack() # rebuild middleware stack on-the-fly
325
+
326
+
327
+ def configure_cors_middleware(app):
328
+ cors_options = {
329
+ "allow_methods": ["*"],
330
+ "allow_headers": ["*"],
331
+ "allow_credentials": True,
332
+ }
333
+ if cmd_opts.cors_allow_origins:
334
+ cors_options["allow_origins"] = cmd_opts.cors_allow_origins.split(',')
335
+ if cmd_opts.cors_allow_origins_regex:
336
+ cors_options["allow_origin_regex"] = cmd_opts.cors_allow_origins_regex
337
+ app.add_middleware(CORSMiddleware, **cors_options)
338
+
339
+
340
+ def create_api(app):
341
+ from modules.api.api import Api
342
+ api = Api(app, queue_lock)
343
+ return api
344
+
345
+
346
+ def api_only():
347
+ initialize()
348
+
349
+ app = FastAPI()
350
+ setup_middleware(app)
351
+ api = create_api(app)
352
+
353
+ modules.script_callbacks.app_started_callback(None, app)
354
+
355
+ print(f"Startup time: {startup_timer.summary()}.")
356
+ api.launch(server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1", port=cmd_opts.port if cmd_opts.port else 7861)
357
+
358
+
359
+ def stop_route(request):
360
+ shared.state.server_command = "stop"
361
+ return Response("Stopping.")
362
+
363
+
364
+ def webui():
365
+ launch_api = cmd_opts.api
366
+ initialize()
367
+
368
+ while 1:
369
+ modules.script_callbacks.before_ui_callback()
370
+
371
+ shared.demo = modules.ui.create_ui()
372
+
373
+ app, local_url, share_url = shared.demo.launch(
374
+ height=3000,
375
+ prevent_thread_lock=True
376
+ )
377
+
378
+ # gradio uses a very open CORS policy via app.user_middleware, which makes it possible for
379
+ # an attacker to trick the user into opening a malicious HTML page, which makes a request to the
380
+ # running web ui and do whatever the attacker wants, including installing an extension and
381
+ # running its code. We disable this here. Suggested by RyotaK.
382
+ app.user_middleware = [x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware']
383
+
384
+ setup_middleware(app)
385
+
386
+ modules.progress.setup_progress_api(app)
387
+ modules.ui.setup_ui_api(app)
388
+
389
+ ui_extra_networks.add_pages_to_demo(app)
390
+
391
+ modules.script_callbacks.app_started_callback(shared.demo, app)
392
+ startup_timer.record("scripts app_started_callback")
393
+
394
+ print(f"Startup time: {startup_timer.summary()}.")
395
+
396
+ try:
397
+ while True:
398
+ server_command = shared.state.wait_for_server_command(timeout=5)
399
+ if server_command:
400
+ if server_command in ("stop", "restart"):
401
+ break
402
+ else:
403
+ print(f"Unknown server command: {server_command}")
404
+ except KeyboardInterrupt:
405
+ print('Caught KeyboardInterrupt, stopping...')
406
+ server_command = "stop"
407
+
408
+ if server_command == "stop":
409
+ print("Stopping server...")
410
+ # If we catch a keyboard interrupt, we want to stop the server and exit.
411
+ shared.demo.close()
412
+ break
413
+ print('Restarting UI...')
414
+ shared.demo.close()
415
+ time.sleep(0.5)
416
+ startup_timer.reset()
417
+ modules.script_callbacks.app_reload_callback()
418
+ startup_timer.record("app reload callback")
419
+ modules.script_callbacks.script_unloaded_callback()
420
+ startup_timer.record("scripts unloaded callback")
421
+ initialize_rest(reload_script_modules=True)
422
+
423
+ modules.script_callbacks.on_list_optimizers(modules.sd_hijack_optimizations.list_optimizers)
424
+ modules.sd_hijack.list_optimizers()
425
+ startup_timer.record("scripts list_optimizers")
426
+
427
+
428
+ if __name__ == "__main__":
429
+ if cmd_opts.nowebui:
430
+ api_only()
431
+ else:
432
+ webui()
direct/v1.3.2/launch_utils.py ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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()
direct/v1.3.2/lib.zst ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3e68801503f843c88eaa1c7c5a42868f4213f3d23d61e4ca7c648c2de4b4b562
3
+ size 271209817
direct/v1.3.2/repositories.tar ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5fdfbbaad51cd35bc127489f424132d4bc594433a68260c850ec797010fdc602
3
+ size 254102016
direct/v1.4.1/directui.py ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import sys
5
+ import time
6
+ import importlib
7
+ import signal
8
+ import re
9
+ import warnings
10
+ import json
11
+ from threading import Thread
12
+ from typing import Iterable
13
+
14
+ from fastapi import FastAPI, Response
15
+ from fastapi.middleware.cors import CORSMiddleware
16
+ from fastapi.middleware.gzip import GZipMiddleware
17
+ from packaging import version
18
+
19
+ import logging
20
+
21
+ logging.getLogger("xformers").addFilter(lambda record: 'A matching Triton is not available' not in record.getMessage())
22
+
23
+ from modules import paths, timer, import_hook, errors, devices # noqa: F401
24
+
25
+ startup_timer = timer.startup_timer
26
+
27
+ import torch
28
+ import pytorch_lightning # noqa: F401 # pytorch_lightning should be imported after torch, but it re-enables warnings on import so import once to disable them
29
+ warnings.filterwarnings(action="ignore", category=DeprecationWarning, module="pytorch_lightning")
30
+ warnings.filterwarnings(action="ignore", category=UserWarning, module="torchvision")
31
+
32
+
33
+ startup_timer.record("import torch")
34
+
35
+ import gradio
36
+ startup_timer.record("import gradio")
37
+
38
+ import ldm.modules.encoders.modules # noqa: F401
39
+ startup_timer.record("import ldm")
40
+
41
+ from modules import extra_networks
42
+ from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, queue_lock # noqa: F401
43
+
44
+ # Truncate version number of nightly/local build of PyTorch to not cause exceptions with CodeFormer or Safetensors
45
+ if ".dev" in torch.__version__ or "+git" in torch.__version__:
46
+ torch.__long_version__ = torch.__version__
47
+ torch.__version__ = re.search(r'[\d.]+[\d]', torch.__version__).group(0)
48
+
49
+ from modules import shared, sd_samplers, upscaler, extensions, localization, ui_tempdir, ui_extra_networks, config_states
50
+ import modules.codeformer_model as codeformer
51
+ import modules.face_restoration
52
+ import modules.gfpgan_model as gfpgan
53
+ import modules.img2img
54
+
55
+ import modules.lowvram
56
+ import modules.scripts
57
+ import modules.sd_hijack
58
+ import modules.sd_hijack_optimizations
59
+ import modules.sd_models
60
+ import modules.sd_vae
61
+ import modules.sd_unet
62
+ import modules.txt2img
63
+ import modules.script_callbacks
64
+ import modules.textual_inversion.textual_inversion
65
+ import modules.progress
66
+
67
+ import modules.ui
68
+ from modules import modelloader
69
+ from modules.shared import cmd_opts
70
+ import modules.hypernetworks.hypernetwork
71
+
72
+ startup_timer.record("other imports")
73
+
74
+
75
+ if cmd_opts.server_name:
76
+ server_name = cmd_opts.server_name
77
+ else:
78
+ server_name = "0.0.0.0" if cmd_opts.listen else None
79
+
80
+
81
+ def fix_asyncio_event_loop_policy():
82
+ """
83
+ The default `asyncio` event loop policy only automatically creates
84
+ event loops in the main threads. Other threads must create event
85
+ loops explicitly or `asyncio.get_event_loop` (and therefore
86
+ `.IOLoop.current`) will fail. Installing this policy allows event
87
+ loops to be created automatically on any thread, matching the
88
+ behavior of Tornado versions prior to 5.0 (or 5.0 on Python 2).
89
+ """
90
+
91
+ import asyncio
92
+
93
+ if sys.platform == "win32" and hasattr(asyncio, "WindowsSelectorEventLoopPolicy"):
94
+ # "Any thread" and "selector" should be orthogonal, but there's not a clean
95
+ # interface for composing policies so pick the right base.
96
+ _BasePolicy = asyncio.WindowsSelectorEventLoopPolicy # type: ignore
97
+ else:
98
+ _BasePolicy = asyncio.DefaultEventLoopPolicy
99
+
100
+ class AnyThreadEventLoopPolicy(_BasePolicy): # type: ignore
101
+ """Event loop policy that allows loop creation on any thread.
102
+ Usage::
103
+
104
+ asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
105
+ """
106
+
107
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
108
+ try:
109
+ return super().get_event_loop()
110
+ except (RuntimeError, AssertionError):
111
+ # This was an AssertionError in python 3.4.2 (which ships with debian jessie)
112
+ # and changed to a RuntimeError in 3.4.3.
113
+ # "There is no current event loop in thread %r"
114
+ loop = self.new_event_loop()
115
+ self.set_event_loop(loop)
116
+ return loop
117
+
118
+ asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
119
+
120
+
121
+ def check_versions():
122
+ if shared.cmd_opts.skip_version_check:
123
+ return
124
+
125
+ expected_torch_version = "2.0.0"
126
+
127
+ if version.parse(torch.__version__) < version.parse(expected_torch_version):
128
+ errors.print_error_explanation(f"""
129
+ You are running torch {torch.__version__}.
130
+ The program is tested to work with torch {expected_torch_version}.
131
+ To reinstall the desired version, run with commandline flag --reinstall-torch.
132
+ Beware that this will cause a lot of large files to be downloaded, as well as
133
+ there are reports of issues with training tab on the latest version.
134
+
135
+ Use --skip-version-check commandline argument to disable this check.
136
+ """.strip())
137
+
138
+ expected_xformers_version = "0.0.20"
139
+ if shared.xformers_available:
140
+ import xformers
141
+
142
+ if version.parse(xformers.__version__) < version.parse(expected_xformers_version):
143
+ errors.print_error_explanation(f"""
144
+ You are running xformers {xformers.__version__}.
145
+ The program is tested to work with xformers {expected_xformers_version}.
146
+ To reinstall the desired version, run with commandline flag --reinstall-xformers.
147
+
148
+ Use --skip-version-check commandline argument to disable this check.
149
+ """.strip())
150
+
151
+
152
+ def restore_config_state_file():
153
+ config_state_file = shared.opts.restore_config_state_file
154
+ if config_state_file == "":
155
+ return
156
+
157
+ shared.opts.restore_config_state_file = ""
158
+ shared.opts.save(shared.config_filename)
159
+
160
+ if os.path.isfile(config_state_file):
161
+ print(f"*** About to restore extension state from file: {config_state_file}")
162
+ with open(config_state_file, "r", encoding="utf-8") as f:
163
+ config_state = json.load(f)
164
+ config_states.restore_extension_config(config_state)
165
+ startup_timer.record("restore extension config")
166
+ elif config_state_file:
167
+ print(f"!!! Config state backup not found: {config_state_file}")
168
+
169
+
170
+ def validate_tls_options():
171
+ if not (cmd_opts.tls_keyfile and cmd_opts.tls_certfile):
172
+ return
173
+
174
+ try:
175
+ if not os.path.exists(cmd_opts.tls_keyfile):
176
+ print("Invalid path to TLS keyfile given")
177
+ if not os.path.exists(cmd_opts.tls_certfile):
178
+ print(f"Invalid path to TLS certfile: '{cmd_opts.tls_certfile}'")
179
+ except TypeError:
180
+ cmd_opts.tls_keyfile = cmd_opts.tls_certfile = None
181
+ print("TLS setup invalid, running webui without TLS")
182
+ else:
183
+ print("Running with TLS")
184
+ startup_timer.record("TLS")
185
+
186
+
187
+ def get_gradio_auth_creds() -> Iterable[tuple[str, ...]]:
188
+ """
189
+ Convert the gradio_auth and gradio_auth_path commandline arguments into
190
+ an iterable of (username, password) tuples.
191
+ """
192
+ def process_credential_line(s) -> tuple[str, ...] | None:
193
+ s = s.strip()
194
+ if not s:
195
+ return None
196
+ return tuple(s.split(':', 1))
197
+
198
+ if cmd_opts.gradio_auth:
199
+ for cred in cmd_opts.gradio_auth.split(','):
200
+ cred = process_credential_line(cred)
201
+ if cred:
202
+ yield cred
203
+
204
+ if cmd_opts.gradio_auth_path:
205
+ with open(cmd_opts.gradio_auth_path, 'r', encoding="utf8") as file:
206
+ for line in file.readlines():
207
+ for cred in line.strip().split(','):
208
+ cred = process_credential_line(cred)
209
+ if cred:
210
+ yield cred
211
+
212
+
213
+ def configure_sigint_handler():
214
+ # make the program just exit at ctrl+c without waiting for anything
215
+ def sigint_handler(sig, frame):
216
+ print(f'Interrupted with signal {sig} in {frame}')
217
+ os._exit(0)
218
+
219
+ if not os.environ.get("COVERAGE_RUN"):
220
+ # Don't install the immediate-quit handler when running under coverage,
221
+ # as then the coverage report won't be generated.
222
+ signal.signal(signal.SIGINT, sigint_handler)
223
+
224
+
225
+ def configure_opts_onchange():
226
+ shared.opts.onchange("sd_model_checkpoint", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()), call=False)
227
+ shared.opts.onchange("sd_vae", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
228
+ shared.opts.onchange("sd_vae_as_default", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
229
+ shared.opts.onchange("temp_dir", ui_tempdir.on_tmpdir_changed)
230
+ shared.opts.onchange("gradio_theme", shared.reload_gradio_theme)
231
+ shared.opts.onchange("cross_attention_optimization", wrap_queued_call(lambda: modules.sd_hijack.model_hijack.redo_hijack(shared.sd_model)), call=False)
232
+ startup_timer.record("opts onchange")
233
+
234
+
235
+ def initialize():
236
+ fix_asyncio_event_loop_policy()
237
+ validate_tls_options()
238
+ configure_sigint_handler()
239
+ check_versions()
240
+ modelloader.cleanup_models()
241
+ configure_opts_onchange()
242
+
243
+ modules.sd_models.setup_model()
244
+ startup_timer.record("setup SD model")
245
+
246
+ codeformer.setup_model(cmd_opts.codeformer_models_path)
247
+ startup_timer.record("setup codeformer")
248
+
249
+ gfpgan.setup_model(cmd_opts.gfpgan_models_path)
250
+ startup_timer.record("setup gfpgan")
251
+
252
+ initialize_rest(reload_script_modules=False)
253
+
254
+
255
+ def initialize_rest(*, reload_script_modules=False):
256
+ """
257
+ Called both from initialize() and when reloading the webui.
258
+ """
259
+ sd_samplers.set_samplers()
260
+ extensions.list_extensions()
261
+ startup_timer.record("list extensions")
262
+
263
+ restore_config_state_file()
264
+
265
+ if cmd_opts.ui_debug_mode:
266
+ shared.sd_upscalers = upscaler.UpscalerLanczos().scalers
267
+ modules.scripts.load_scripts()
268
+ return
269
+
270
+ modules.sd_models.list_models()
271
+ startup_timer.record("list SD models")
272
+
273
+ localization.list_localizations(cmd_opts.localizations_dir)
274
+
275
+ with startup_timer.subcategory("load scripts"):
276
+ modules.scripts.load_scripts()
277
+
278
+ if reload_script_modules:
279
+ for module in [module for name, module in sys.modules.items() if name.startswith("modules.ui")]:
280
+ importlib.reload(module)
281
+ startup_timer.record("reload script modules")
282
+
283
+ modelloader.load_upscalers()
284
+ startup_timer.record("load upscalers")
285
+
286
+ modules.sd_vae.refresh_vae_list()
287
+ startup_timer.record("refresh VAE")
288
+ modules.textual_inversion.textual_inversion.list_textual_inversion_templates()
289
+ startup_timer.record("refresh textual inversion templates")
290
+
291
+ modules.script_callbacks.on_list_optimizers(modules.sd_hijack_optimizations.list_optimizers)
292
+ modules.sd_hijack.list_optimizers()
293
+ startup_timer.record("scripts list_optimizers")
294
+
295
+ modules.sd_unet.list_unets()
296
+ startup_timer.record("scripts list_unets")
297
+
298
+ def load_model():
299
+ """
300
+ Accesses shared.sd_model property to load model.
301
+ After it's available, if it has been loaded before this access by some extension,
302
+ its optimization may be None because the list of optimizaers has neet been filled
303
+ by that time, so we apply optimization again.
304
+ """
305
+
306
+ shared.sd_model # noqa: B018
307
+
308
+ if modules.sd_hijack.current_optimizer is None:
309
+ modules.sd_hijack.apply_optimizations()
310
+
311
+ Thread(target=load_model).start()
312
+
313
+ Thread(target=devices.first_time_calculation).start()
314
+
315
+ shared.reload_hypernetworks()
316
+ startup_timer.record("reload hypernetworks")
317
+
318
+ ui_extra_networks.initialize()
319
+ ui_extra_networks.register_default_pages()
320
+
321
+ extra_networks.initialize()
322
+ extra_networks.register_default_extra_networks()
323
+ startup_timer.record("initialize extra networks")
324
+
325
+
326
+ def setup_middleware(app):
327
+ app.middleware_stack = None # reset current middleware to allow modifying user provided list
328
+ app.add_middleware(GZipMiddleware, minimum_size=1000)
329
+ configure_cors_middleware(app)
330
+ app.build_middleware_stack() # rebuild middleware stack on-the-fly
331
+
332
+
333
+ def configure_cors_middleware(app):
334
+ cors_options = {
335
+ "allow_methods": ["*"],
336
+ "allow_headers": ["*"],
337
+ "allow_credentials": True,
338
+ }
339
+ if cmd_opts.cors_allow_origins:
340
+ cors_options["allow_origins"] = cmd_opts.cors_allow_origins.split(',')
341
+ if cmd_opts.cors_allow_origins_regex:
342
+ cors_options["allow_origin_regex"] = cmd_opts.cors_allow_origins_regex
343
+ app.add_middleware(CORSMiddleware, **cors_options)
344
+
345
+
346
+ def create_api(app):
347
+ from modules.api.api import Api
348
+ api = Api(app, queue_lock)
349
+ return api
350
+
351
+
352
+ def api_only():
353
+ initialize()
354
+
355
+ app = FastAPI()
356
+ setup_middleware(app)
357
+ api = create_api(app)
358
+
359
+ modules.script_callbacks.app_started_callback(None, app)
360
+
361
+ print(f"Startup time: {startup_timer.summary()}.")
362
+ api.launch(server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1", port=cmd_opts.port if cmd_opts.port else 7861)
363
+
364
+
365
+ def stop_route(request):
366
+ shared.state.server_command = "stop"
367
+ return Response("Stopping.")
368
+
369
+
370
+ def webui():
371
+ launch_api = cmd_opts.api
372
+ initialize()
373
+
374
+ while 1:
375
+ if shared.opts.clean_temp_dir_at_start:
376
+ ui_tempdir.cleanup_tmpdr()
377
+ startup_timer.record("cleanup temp dir")
378
+
379
+ modules.script_callbacks.before_ui_callback()
380
+
381
+ shared.demo = modules.ui.create_ui()
382
+
383
+ app, local_url, share_url = shared.demo.launch(
384
+ height=3000,
385
+ prevent_thread_lock=True
386
+ )
387
+
388
+ # gradio uses a very open CORS policy via app.user_middleware, which makes it possible for
389
+ # an attacker to trick the user into opening a malicious HTML page, which makes a request to the
390
+ # running web ui and do whatever the attacker wants, including installing an extension and
391
+ # running its code. We disable this here. Suggested by RyotaK.
392
+ app.user_middleware = [x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware']
393
+
394
+ setup_middleware(app)
395
+
396
+ modules.progress.setup_progress_api(app)
397
+ modules.ui.setup_ui_api(app)
398
+
399
+ if launch_api:
400
+ create_api(app)
401
+
402
+ ui_extra_networks.add_pages_to_demo(app)
403
+
404
+ startup_timer.record("add APIs")
405
+
406
+ with startup_timer.subcategory("app_started_callback"):
407
+ modules.script_callbacks.app_started_callback(shared.demo, app)
408
+
409
+ timer.startup_record = startup_timer.dump()
410
+ print(f"Startup time: {startup_timer.summary()}.")
411
+
412
+ if cmd_opts.subpath:
413
+ redirector = FastAPI()
414
+ redirector.get("/")
415
+ gradio.mount_gradio_app(redirector, shared.demo, path=f"/{cmd_opts.subpath}")
416
+
417
+ try:
418
+ while True:
419
+ server_command = shared.state.wait_for_server_command(timeout=5)
420
+ if server_command:
421
+ if server_command in ("stop", "restart"):
422
+ break
423
+ else:
424
+ print(f"Unknown server command: {server_command}")
425
+ except KeyboardInterrupt:
426
+ print('Caught KeyboardInterrupt, stopping...')
427
+ server_command = "stop"
428
+
429
+ if server_command == "stop":
430
+ print("Stopping server...")
431
+ # If we catch a keyboard interrupt, we want to stop the server and exit.
432
+ shared.demo.close()
433
+ break
434
+
435
+ print('Restarting UI...')
436
+ shared.demo.close()
437
+ time.sleep(0.5)
438
+ startup_timer.reset()
439
+ modules.script_callbacks.app_reload_callback()
440
+ startup_timer.record("app reload callback")
441
+ modules.script_callbacks.script_unloaded_callback()
442
+ startup_timer.record("scripts unloaded callback")
443
+ initialize_rest(reload_script_modules=True)
444
+
445
+
446
+ if __name__ == "__main__":
447
+ if cmd_opts.nowebui:
448
+ api_only()
449
+ else:
450
+ webui()
direct/v1.4.1/launch_utils.py ADDED
@@ -0,0 +1,344 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, errors
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
+ try:
72
+ from pathlib import Path
73
+ changelog_md = Path(__file__).parent.parent / "CHANGELOG.md"
74
+ with changelog_md.open(encoding="utf-8") as file:
75
+ return next((line.strip() for line in file if line.strip()), "<none>")
76
+ except Exception:
77
+ return "<none>"
78
+
79
+
80
+ def run(command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live) -> str:
81
+ if desc is not None:
82
+ print(desc)
83
+
84
+ run_kwargs = {
85
+ "args": command,
86
+ "shell": True,
87
+ "env": os.environ if custom_env is None else custom_env,
88
+ "encoding": 'utf8',
89
+ "errors": 'ignore',
90
+ }
91
+
92
+ if not live:
93
+ run_kwargs["stdout"] = run_kwargs["stderr"] = subprocess.PIPE
94
+
95
+ result = subprocess.run(**run_kwargs)
96
+
97
+ if result.returncode != 0:
98
+ error_bits = [
99
+ f"{errdesc or 'Error running command'}.",
100
+ f"Command: {command}",
101
+ f"Error code: {result.returncode}",
102
+ ]
103
+ if result.stdout:
104
+ error_bits.append(f"stdout: {result.stdout}")
105
+ if result.stderr:
106
+ error_bits.append(f"stderr: {result.stderr}")
107
+ raise RuntimeError("\n".join(error_bits))
108
+
109
+ return (result.stdout or "")
110
+
111
+
112
+ def is_installed(package):
113
+ try:
114
+ spec = importlib.util.find_spec(package)
115
+ except ModuleNotFoundError:
116
+ return False
117
+
118
+ return spec is not None
119
+
120
+
121
+ def repo_dir(name):
122
+ return os.path.join(script_path, dir_repos, name)
123
+
124
+
125
+ def run_pip(command, desc=None, live=default_command_live):
126
+ if args.skip_install:
127
+ return
128
+
129
+ index_url_line = f' --index-url {index_url}' if index_url != '' else ''
130
+ return run(f'"{python}" -m pip {command} --prefer-binary{index_url_line}', desc=f"Installing {desc}", errdesc=f"Couldn't install {desc}", live=live)
131
+
132
+
133
+ def check_run_python(code: str) -> bool:
134
+ result = subprocess.run([python, "-c", code], capture_output=True, shell=False)
135
+ return result.returncode == 0
136
+
137
+
138
+ def git_clone(url, dir, name, commithash=None):
139
+ # TODO clone into temporary dir and move if successful
140
+
141
+ if os.path.exists(dir):
142
+ if commithash is None:
143
+ return
144
+
145
+ current_hash = run(f'"{git}" -C "{dir}" rev-parse HEAD', None, f"Couldn't determine {name}'s hash: {commithash}").strip()
146
+ if current_hash == commithash:
147
+ return
148
+
149
+ run(f'"{git}" -C "{dir}" fetch', f"Fetching updates for {name}...", f"Couldn't fetch {name}")
150
+ 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}")
151
+ return
152
+
153
+ run(f'"{git}" clone "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}")
154
+
155
+ if commithash is not None:
156
+ run(f'"{git}" -C "{dir}" reset --hard {commithash}', None, "Couldn't checkout {name}'s hash: {commithash}")
157
+
158
+
159
+ def git_pull_recursive(dir):
160
+ for subdir, _, _ in os.walk(dir):
161
+ if os.path.exists(os.path.join(subdir, '.git')):
162
+ try:
163
+ output = subprocess.check_output([git, '-C', subdir, 'pull', '--autostash'])
164
+ print(f"Pulled changes for repository in '{subdir}':\n{output.decode('utf-8').strip()}\n")
165
+ except subprocess.CalledProcessError as e:
166
+ print(f"Couldn't perform 'git pull' on repository in '{subdir}':\n{e.output.decode('utf-8').strip()}\n")
167
+
168
+
169
+ def version_check(commit):
170
+ try:
171
+ import requests
172
+ commits = requests.get('https://api.github.com/repos/AUTOMATIC1111/stable-diffusion-webui/branches/master').json()
173
+ if commit != "<none>" and commits['commit']['sha'] != commit:
174
+ print("--------------------------------------------------------")
175
+ print("| You are not up to date with the most recent release. |")
176
+ print("| Consider running `git pull` to update. |")
177
+ print("--------------------------------------------------------")
178
+ elif commits['commit']['sha'] == commit:
179
+ print("You are up to date with the most recent release.")
180
+ else:
181
+ print("Not a git clone, can't perform version check.")
182
+ except Exception as e:
183
+ print("version check failed", e)
184
+
185
+
186
+ def run_extension_installer(extension_dir):
187
+ path_installer = os.path.join(extension_dir, "install.py")
188
+ if not os.path.isfile(path_installer):
189
+ return
190
+
191
+ try:
192
+ env = os.environ.copy()
193
+ env['PYTHONPATH'] = os.path.abspath(".")
194
+
195
+ print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env))
196
+ except Exception as e:
197
+ errors.report(str(e))
198
+
199
+
200
+ def list_extensions(settings_file):
201
+ settings = {}
202
+
203
+ try:
204
+ if os.path.isfile(settings_file):
205
+ with open(settings_file, "r", encoding="utf8") as file:
206
+ settings = json.load(file)
207
+ except Exception:
208
+ errors.report("Could not load settings", exc_info=True)
209
+
210
+ disabled_extensions = set(settings.get('disabled_extensions', []))
211
+ disable_all_extensions = settings.get('disable_all_extensions', 'none')
212
+
213
+ if disable_all_extensions != 'none':
214
+ return []
215
+
216
+ return [x for x in os.listdir(extensions_dir) if x not in disabled_extensions]
217
+
218
+
219
+ def run_extensions_installers(settings_file):
220
+ if not os.path.isdir(extensions_dir):
221
+ return
222
+
223
+ for dirname_extension in list_extensions(settings_file):
224
+ run_extension_installer(os.path.join(extensions_dir, dirname_extension))
225
+
226
+
227
+ def prepare_environment():
228
+ torch_index_url = os.environ.get('TORCH_INDEX_URL', "https://download.pytorch.org/whl/cu118")
229
+ torch_command = os.environ.get('TORCH_COMMAND', f"pip install torch==2.0.1 torchvision==0.15.2 --extra-index-url {torch_index_url}")
230
+ requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")
231
+
232
+ xformers_package = os.environ.get('XFORMERS_PACKAGE', 'xformers==0.0.20')
233
+ gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "https://github.com/TencentARC/GFPGAN/archive/8d2447a2d918f8eba5a4a01463fd48e45126a379.zip")
234
+ clip_package = os.environ.get('CLIP_PACKAGE', "https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip")
235
+ openclip_package = os.environ.get('OPENCLIP_PACKAGE', "https://github.com/mlfoundations/open_clip/archive/bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b.zip")
236
+
237
+ stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/Stability-AI/stablediffusion.git")
238
+ k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')
239
+ codeformer_repo = os.environ.get('CODEFORMER_REPO', 'https://github.com/sczhou/CodeFormer.git')
240
+ blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')
241
+
242
+ stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf")
243
+ k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "c9fe758757e022f05ca5a53fa8fac28889e4f1cf")
244
+ codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH', "c5b4593074ba6214284d6acd5f1719b6c5d739af")
245
+ blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH', "48211a1594f1321b00f14c9f7a5b4813144b2fb9")
246
+
247
+ try:
248
+ # the existance of this file is a signal to webui.sh/bat that webui needs to be restarted when it stops execution
249
+ os.remove(os.path.join(script_path, "tmp", "restart"))
250
+ os.environ.setdefault('SD_WEBUI_RESTARTING ', '1')
251
+ except OSError:
252
+ pass
253
+
254
+ if not args.skip_python_version_check:
255
+ check_python_version()
256
+
257
+ commit = commit_hash()
258
+ tag = git_tag()
259
+
260
+ print(f"Python {sys.version}")
261
+ print(f"Version: {tag}")
262
+ print(f"Commit hash: {commit}")
263
+
264
+ if args.reinstall_torch or not is_installed("torch") or not is_installed("torchvision"):
265
+ run(f'"{python}" -m {torch_command}', "Installing torch and torchvision", "Couldn't install torch", live=True)
266
+
267
+ if not args.skip_torch_cuda_test and not check_run_python("import torch; assert torch.cuda.is_available()"):
268
+ raise RuntimeError(
269
+ 'Torch is not able to use GPU; '
270
+ 'add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check'
271
+ )
272
+
273
+ if not is_installed("gfpgan"):
274
+ run_pip(f"install {gfpgan_package}", "gfpgan")
275
+
276
+ if not is_installed("clip"):
277
+ run_pip(f"install {clip_package}", "clip")
278
+
279
+ if not is_installed("open_clip"):
280
+ run_pip(f"install {openclip_package}", "open_clip")
281
+
282
+ if (not is_installed("xformers") or args.reinstall_xformers) and args.xformers:
283
+ if platform.system() == "Windows":
284
+ if platform.python_version().startswith("3.10"):
285
+ run_pip(f"install -U -I --no-deps {xformers_package}", "xformers", live=True)
286
+ else:
287
+ print("Installation of xformers is not supported in this version of Python.")
288
+ print("You can also check this and build manually: https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers#building-xformers-on-windows-by-duckness")
289
+ if not is_installed("xformers"):
290
+ exit(0)
291
+ elif platform.system() == "Linux":
292
+ run_pip(f"install -U -I --no-deps {xformers_package}", "xformers")
293
+
294
+ if not is_installed("ngrok") and args.ngrok:
295
+ run_pip("install ngrok", "ngrok")
296
+
297
+ os.makedirs(os.path.join(script_path, dir_repos), exist_ok=True)
298
+
299
+ git_clone(stable_diffusion_repo, repo_dir('stable-diffusion-stability-ai'), "Stable Diffusion", stable_diffusion_commit_hash)
300
+ git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
301
+ git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
302
+ git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash)
303
+
304
+ if not is_installed("lpips"):
305
+ run_pip(f"install -r \"{os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}\"", "requirements for CodeFormer")
306
+
307
+ if not os.path.isfile(requirements_file):
308
+ requirements_file = os.path.join(script_path, requirements_file)
309
+ run_pip(f"install -r \"{requirements_file}\"", "requirements")
310
+
311
+ run_extensions_installers(settings_file=args.ui_settings_file)
312
+
313
+ if args.update_check:
314
+ version_check(commit)
315
+
316
+ if args.update_all_extensions:
317
+ git_pull_recursive(extensions_dir)
318
+
319
+ if "--exit" in sys.argv:
320
+ print("Exiting because of --exit argument")
321
+ exit(0)
322
+
323
+
324
+ def configure_for_tests():
325
+ if "--api" not in sys.argv:
326
+ sys.argv.append("--api")
327
+ if "--ckpt" not in sys.argv:
328
+ sys.argv.append("--ckpt")
329
+ sys.argv.append(os.path.join(script_path, "test/test_files/empty.pt"))
330
+ if "--skip-torch-cuda-test" not in sys.argv:
331
+ sys.argv.append("--skip-torch-cuda-test")
332
+ if "--disable-nan-check" not in sys.argv:
333
+ sys.argv.append("--disable-nan-check")
334
+
335
+ os.environ['COMMANDLINE_ARGS'] = ""
336
+
337
+
338
+ def start():
339
+ print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")
340
+ import webui
341
+ if '--nowebui' in sys.argv:
342
+ webui.api_only()
343
+ else:
344
+ webui.webui()
direct/v1.4.1/lib.zst ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:56113b7a5d827478ee26ffa58dd203232fb020f6ee1037341ede10b27f6d6001
3
+ size 271208491
direct/v1.4.1/repositories.tar ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c9c9ada9852c5cefcb45c6ed0d984c11909214d73693440563d4667ae62a180f
3
+ size 201369600
direct/v1.5.2/directui.py ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import sys
5
+ import time
6
+ import importlib
7
+ import signal
8
+ import re
9
+ import warnings
10
+ import json
11
+ from threading import Thread
12
+ from typing import Iterable
13
+
14
+ from fastapi import FastAPI
15
+ from fastapi.middleware.cors import CORSMiddleware
16
+ from fastapi.middleware.gzip import GZipMiddleware
17
+ from packaging import version
18
+
19
+ import logging
20
+
21
+ # We can't use cmd_opts for this because it will not have been initialized at this point.
22
+ log_level = os.environ.get("SD_WEBUI_LOG_LEVEL")
23
+ if log_level:
24
+ log_level = getattr(logging, log_level.upper(), None) or logging.INFO
25
+ logging.basicConfig(
26
+ level=log_level,
27
+ format='%(asctime)s %(levelname)s [%(name)s] %(message)s',
28
+ datefmt='%Y-%m-%d %H:%M:%S',
29
+ )
30
+
31
+ logging.getLogger("torch.distributed.nn").setLevel(logging.ERROR) # sshh...
32
+ logging.getLogger("xformers").addFilter(lambda record: 'A matching Triton is not available' not in record.getMessage())
33
+
34
+ from modules import timer
35
+ startup_timer = timer.startup_timer
36
+ startup_timer.record("launcher")
37
+
38
+ import torch
39
+ import pytorch_lightning # noqa: F401 # pytorch_lightning should be imported after torch, but it re-enables warnings on import so import once to disable them
40
+ warnings.filterwarnings(action="ignore", category=DeprecationWarning, module="pytorch_lightning")
41
+ warnings.filterwarnings(action="ignore", category=UserWarning, module="torchvision")
42
+ startup_timer.record("import torch")
43
+
44
+ import gradio # noqa: F401
45
+ startup_timer.record("import gradio")
46
+
47
+ from modules import paths, timer, import_hook, errors, devices # noqa: F401
48
+ startup_timer.record("setup paths")
49
+
50
+ import ldm.modules.encoders.modules # noqa: F401
51
+ startup_timer.record("import ldm")
52
+
53
+ from modules import extra_networks
54
+ from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, queue_lock # noqa: F401
55
+
56
+ # Truncate version number of nightly/local build of PyTorch to not cause exceptions with CodeFormer or Safetensors
57
+ if ".dev" in torch.__version__ or "+git" in torch.__version__:
58
+ torch.__long_version__ = torch.__version__
59
+ torch.__version__ = re.search(r'[\d.]+[\d]', torch.__version__).group(0)
60
+
61
+ from modules import shared, sd_samplers, upscaler, extensions, localization, ui_tempdir, ui_extra_networks, config_states
62
+ import modules.codeformer_model as codeformer
63
+ import modules.face_restoration
64
+ import modules.gfpgan_model as gfpgan
65
+ import modules.img2img
66
+
67
+ import modules.lowvram
68
+ import modules.scripts
69
+ import modules.sd_hijack
70
+ import modules.sd_hijack_optimizations
71
+ import modules.sd_models
72
+ import modules.sd_vae
73
+ import modules.sd_unet
74
+ import modules.txt2img
75
+ import modules.script_callbacks
76
+ import modules.textual_inversion.textual_inversion
77
+ import modules.progress
78
+
79
+ import modules.ui
80
+ from modules import modelloader
81
+ from modules.shared import cmd_opts
82
+ import modules.hypernetworks.hypernetwork
83
+
84
+ startup_timer.record("other imports")
85
+
86
+
87
+ if cmd_opts.server_name:
88
+ server_name = cmd_opts.server_name
89
+ else:
90
+ server_name = "0.0.0.0" if cmd_opts.listen else None
91
+
92
+
93
+ def fix_asyncio_event_loop_policy():
94
+ """
95
+ The default `asyncio` event loop policy only automatically creates
96
+ event loops in the main threads. Other threads must create event
97
+ loops explicitly or `asyncio.get_event_loop` (and therefore
98
+ `.IOLoop.current`) will fail. Installing this policy allows event
99
+ loops to be created automatically on any thread, matching the
100
+ behavior of Tornado versions prior to 5.0 (or 5.0 on Python 2).
101
+ """
102
+
103
+ import asyncio
104
+
105
+ if sys.platform == "win32" and hasattr(asyncio, "WindowsSelectorEventLoopPolicy"):
106
+ # "Any thread" and "selector" should be orthogonal, but there's not a clean
107
+ # interface for composing policies so pick the right base.
108
+ _BasePolicy = asyncio.WindowsSelectorEventLoopPolicy # type: ignore
109
+ else:
110
+ _BasePolicy = asyncio.DefaultEventLoopPolicy
111
+
112
+ class AnyThreadEventLoopPolicy(_BasePolicy): # type: ignore
113
+ """Event loop policy that allows loop creation on any thread.
114
+ Usage::
115
+
116
+ asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
117
+ """
118
+
119
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
120
+ try:
121
+ return super().get_event_loop()
122
+ except (RuntimeError, AssertionError):
123
+ # This was an AssertionError in python 3.4.2 (which ships with debian jessie)
124
+ # and changed to a RuntimeError in 3.4.3.
125
+ # "There is no current event loop in thread %r"
126
+ loop = self.new_event_loop()
127
+ self.set_event_loop(loop)
128
+ return loop
129
+
130
+ asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
131
+
132
+
133
+ def check_versions():
134
+ if shared.cmd_opts.skip_version_check:
135
+ return
136
+
137
+ expected_torch_version = "2.0.0"
138
+
139
+ if version.parse(torch.__version__) < version.parse(expected_torch_version):
140
+ errors.print_error_explanation(f"""
141
+ You are running torch {torch.__version__}.
142
+ The program is tested to work with torch {expected_torch_version}.
143
+ To reinstall the desired version, run with commandline flag --reinstall-torch.
144
+ Beware that this will cause a lot of large files to be downloaded, as well as
145
+ there are reports of issues with training tab on the latest version.
146
+
147
+ Use --skip-version-check commandline argument to disable this check.
148
+ """.strip())
149
+
150
+ expected_xformers_version = "0.0.20"
151
+ if shared.xformers_available:
152
+ import xformers
153
+
154
+ if version.parse(xformers.__version__) < version.parse(expected_xformers_version):
155
+ errors.print_error_explanation(f"""
156
+ You are running xformers {xformers.__version__}.
157
+ The program is tested to work with xformers {expected_xformers_version}.
158
+ To reinstall the desired version, run with commandline flag --reinstall-xformers.
159
+
160
+ Use --skip-version-check commandline argument to disable this check.
161
+ """.strip())
162
+
163
+
164
+ def restore_config_state_file():
165
+ config_state_file = shared.opts.restore_config_state_file
166
+ if config_state_file == "":
167
+ return
168
+
169
+ shared.opts.restore_config_state_file = ""
170
+ shared.opts.save(shared.config_filename)
171
+
172
+ if os.path.isfile(config_state_file):
173
+ print(f"*** About to restore extension state from file: {config_state_file}")
174
+ with open(config_state_file, "r", encoding="utf-8") as f:
175
+ config_state = json.load(f)
176
+ config_states.restore_extension_config(config_state)
177
+ startup_timer.record("restore extension config")
178
+ elif config_state_file:
179
+ print(f"!!! Config state backup not found: {config_state_file}")
180
+
181
+
182
+ def validate_tls_options():
183
+ if not (cmd_opts.tls_keyfile and cmd_opts.tls_certfile):
184
+ return
185
+
186
+ try:
187
+ if not os.path.exists(cmd_opts.tls_keyfile):
188
+ print("Invalid path to TLS keyfile given")
189
+ if not os.path.exists(cmd_opts.tls_certfile):
190
+ print(f"Invalid path to TLS certfile: '{cmd_opts.tls_certfile}'")
191
+ except TypeError:
192
+ cmd_opts.tls_keyfile = cmd_opts.tls_certfile = None
193
+ print("TLS setup invalid, running webui without TLS")
194
+ else:
195
+ print("Running with TLS")
196
+ startup_timer.record("TLS")
197
+
198
+
199
+ def get_gradio_auth_creds() -> Iterable[tuple[str, ...]]:
200
+ """
201
+ Convert the gradio_auth and gradio_auth_path commandline arguments into
202
+ an iterable of (username, password) tuples.
203
+ """
204
+ def process_credential_line(s) -> tuple[str, ...] | None:
205
+ s = s.strip()
206
+ if not s:
207
+ return None
208
+ return tuple(s.split(':', 1))
209
+
210
+ if cmd_opts.gradio_auth:
211
+ for cred in cmd_opts.gradio_auth.split(','):
212
+ cred = process_credential_line(cred)
213
+ if cred:
214
+ yield cred
215
+
216
+ if cmd_opts.gradio_auth_path:
217
+ with open(cmd_opts.gradio_auth_path, 'r', encoding="utf8") as file:
218
+ for line in file.readlines():
219
+ for cred in line.strip().split(','):
220
+ cred = process_credential_line(cred)
221
+ if cred:
222
+ yield cred
223
+
224
+
225
+ def configure_sigint_handler():
226
+ # make the program just exit at ctrl+c without waiting for anything
227
+ def sigint_handler(sig, frame):
228
+ print(f'Interrupted with signal {sig} in {frame}')
229
+ os._exit(0)
230
+
231
+ if not os.environ.get("COVERAGE_RUN"):
232
+ # Don't install the immediate-quit handler when running under coverage,
233
+ # as then the coverage report won't be generated.
234
+ signal.signal(signal.SIGINT, sigint_handler)
235
+
236
+
237
+ def configure_opts_onchange():
238
+ shared.opts.onchange("sd_model_checkpoint", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()), call=False)
239
+ shared.opts.onchange("sd_vae", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
240
+ shared.opts.onchange("sd_vae_as_default", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
241
+ shared.opts.onchange("temp_dir", ui_tempdir.on_tmpdir_changed)
242
+ shared.opts.onchange("gradio_theme", shared.reload_gradio_theme)
243
+ shared.opts.onchange("cross_attention_optimization", wrap_queued_call(lambda: modules.sd_hijack.model_hijack.redo_hijack(shared.sd_model)), call=False)
244
+ startup_timer.record("opts onchange")
245
+
246
+
247
+ def initialize():
248
+ fix_asyncio_event_loop_policy()
249
+ validate_tls_options()
250
+ configure_sigint_handler()
251
+ check_versions()
252
+ modelloader.cleanup_models()
253
+ configure_opts_onchange()
254
+
255
+ modules.sd_models.setup_model()
256
+ startup_timer.record("setup SD model")
257
+
258
+ codeformer.setup_model(cmd_opts.codeformer_models_path)
259
+ startup_timer.record("setup codeformer")
260
+
261
+ gfpgan.setup_model(cmd_opts.gfpgan_models_path)
262
+ startup_timer.record("setup gfpgan")
263
+
264
+ initialize_rest(reload_script_modules=False)
265
+
266
+
267
+ def initialize_rest(*, reload_script_modules=False):
268
+ """
269
+ Called both from initialize() and when reloading the webui.
270
+ """
271
+ sd_samplers.set_samplers()
272
+ extensions.list_extensions()
273
+ startup_timer.record("list extensions")
274
+
275
+ restore_config_state_file()
276
+
277
+ if cmd_opts.ui_debug_mode:
278
+ shared.sd_upscalers = upscaler.UpscalerLanczos().scalers
279
+ modules.scripts.load_scripts()
280
+ return
281
+
282
+ modules.sd_models.list_models()
283
+ startup_timer.record("list SD models")
284
+
285
+ localization.list_localizations(cmd_opts.localizations_dir)
286
+
287
+ with startup_timer.subcategory("load scripts"):
288
+ modules.scripts.load_scripts()
289
+
290
+ if reload_script_modules:
291
+ for module in [module for name, module in sys.modules.items() if name.startswith("modules.ui")]:
292
+ importlib.reload(module)
293
+ startup_timer.record("reload script modules")
294
+
295
+ modelloader.load_upscalers()
296
+ startup_timer.record("load upscalers")
297
+
298
+ modules.sd_vae.refresh_vae_list()
299
+ startup_timer.record("refresh VAE")
300
+ modules.textual_inversion.textual_inversion.list_textual_inversion_templates()
301
+ startup_timer.record("refresh textual inversion templates")
302
+
303
+ modules.script_callbacks.on_list_optimizers(modules.sd_hijack_optimizations.list_optimizers)
304
+ modules.sd_hijack.list_optimizers()
305
+ startup_timer.record("scripts list_optimizers")
306
+
307
+ modules.sd_unet.list_unets()
308
+ startup_timer.record("scripts list_unets")
309
+
310
+ def load_model():
311
+ """
312
+ Accesses shared.sd_model property to load model.
313
+ After it's available, if it has been loaded before this access by some extension,
314
+ its optimization may be None because the list of optimizaers has neet been filled
315
+ by that time, so we apply optimization again.
316
+ """
317
+
318
+ shared.sd_model # noqa: B018
319
+
320
+ if modules.sd_hijack.current_optimizer is None:
321
+ modules.sd_hijack.apply_optimizations()
322
+
323
+ Thread(target=load_model).start()
324
+
325
+ Thread(target=devices.first_time_calculation).start()
326
+
327
+ shared.reload_hypernetworks()
328
+ startup_timer.record("reload hypernetworks")
329
+
330
+ ui_extra_networks.initialize()
331
+ ui_extra_networks.register_default_pages()
332
+
333
+ extra_networks.initialize()
334
+ extra_networks.register_default_extra_networks()
335
+ startup_timer.record("initialize extra networks")
336
+
337
+
338
+ def setup_middleware(app):
339
+ app.middleware_stack = None # reset current middleware to allow modifying user provided list
340
+ app.add_middleware(GZipMiddleware, minimum_size=1000)
341
+ configure_cors_middleware(app)
342
+ app.build_middleware_stack() # rebuild middleware stack on-the-fly
343
+
344
+
345
+ def configure_cors_middleware(app):
346
+ cors_options = {
347
+ "allow_methods": ["*"],
348
+ "allow_headers": ["*"],
349
+ "allow_credentials": True,
350
+ }
351
+ if cmd_opts.cors_allow_origins:
352
+ cors_options["allow_origins"] = cmd_opts.cors_allow_origins.split(',')
353
+ if cmd_opts.cors_allow_origins_regex:
354
+ cors_options["allow_origin_regex"] = cmd_opts.cors_allow_origins_regex
355
+ app.add_middleware(CORSMiddleware, **cors_options)
356
+
357
+
358
+ def create_api(app):
359
+ from modules.api.api import Api
360
+ api = Api(app, queue_lock)
361
+ return api
362
+
363
+
364
+ def api_only():
365
+ initialize()
366
+
367
+ app = FastAPI()
368
+ setup_middleware(app)
369
+ api = create_api(app)
370
+
371
+ modules.script_callbacks.app_started_callback(None, app)
372
+
373
+ print(f"Startup time: {startup_timer.summary()}.")
374
+ api.launch(
375
+ server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1",
376
+ port=cmd_opts.port if cmd_opts.port else 7861,
377
+ root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else ""
378
+ )
379
+
380
+
381
+ def webui():
382
+ launch_api = cmd_opts.api
383
+ initialize()
384
+
385
+ while 1:
386
+ if shared.opts.clean_temp_dir_at_start:
387
+ ui_tempdir.cleanup_tmpdr()
388
+ startup_timer.record("cleanup temp dir")
389
+
390
+ modules.script_callbacks.before_ui_callback()
391
+
392
+ shared.demo = modules.ui.create_ui()
393
+
394
+ app, local_url, share_url = shared.demo.launch(
395
+ height=3000,
396
+ prevent_thread_lock=True
397
+ )
398
+
399
+ # gradio uses a very open CORS policy via app.user_middleware, which makes it possible for
400
+ # an attacker to trick the user into opening a malicious HTML page, which makes a request to the
401
+ # running web ui and do whatever the attacker wants, including installing an extension and
402
+ # running its code. We disable this here. Suggested by RyotaK.
403
+ app.user_middleware = [x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware']
404
+
405
+ setup_middleware(app)
406
+
407
+ modules.progress.setup_progress_api(app)
408
+ modules.ui.setup_ui_api(app)
409
+
410
+ if launch_api:
411
+ create_api(app)
412
+
413
+ ui_extra_networks.add_pages_to_demo(app)
414
+
415
+ startup_timer.record("add APIs")
416
+
417
+ with startup_timer.subcategory("app_started_callback"):
418
+ modules.script_callbacks.app_started_callback(shared.demo, app)
419
+
420
+ timer.startup_record = startup_timer.dump()
421
+ print(f"Startup time: {startup_timer.summary()}.")
422
+
423
+ try:
424
+ while True:
425
+ server_command = shared.state.wait_for_server_command(timeout=5)
426
+ if server_command:
427
+ if server_command in ("stop", "restart"):
428
+ break
429
+ else:
430
+ print(f"Unknown server command: {server_command}")
431
+ except KeyboardInterrupt:
432
+ print('Caught KeyboardInterrupt, stopping...')
433
+ server_command = "stop"
434
+
435
+ if server_command == "stop":
436
+ print("Stopping server...")
437
+ # If we catch a keyboard interrupt, we want to stop the server and exit.
438
+ shared.demo.close()
439
+ break
440
+
441
+ print('Restarting UI...')
442
+ shared.demo.close()
443
+ time.sleep(0.5)
444
+ startup_timer.reset()
445
+ modules.script_callbacks.app_reload_callback()
446
+ startup_timer.record("app reload callback")
447
+ modules.script_callbacks.script_unloaded_callback()
448
+ startup_timer.record("scripts unloaded callback")
449
+ initialize_rest(reload_script_modules=True)
450
+
451
+
452
+ if __name__ == "__main__":
453
+ if cmd_opts.nowebui:
454
+ api_only()
455
+ else:
456
+ webui()
direct/v1.5.2/launch_utils.py ADDED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this scripts installs necessary requirements and launches main program in webui.py
2
+ import re
3
+ import subprocess
4
+ import os
5
+ import sys
6
+ import importlib.util
7
+ import platform
8
+ import json
9
+ from functools import lru_cache
10
+
11
+ from modules import cmd_args, errors
12
+ from modules.paths_internal import script_path, extensions_dir
13
+ from modules import timer
14
+
15
+ timer.startup_timer.record("start")
16
+
17
+ args, _ = cmd_args.parser.parse_known_args()
18
+
19
+ python = sys.executable
20
+ git = os.environ.get('GIT', "git")
21
+ index_url = os.environ.get('INDEX_URL', "")
22
+ dir_repos = "repositories"
23
+
24
+ # Whether to default to printing command output
25
+ default_command_live = (os.environ.get('WEBUI_LAUNCH_LIVE_OUTPUT') == "1")
26
+
27
+ if 'GRADIO_ANALYTICS_ENABLED' not in os.environ:
28
+ os.environ['GRADIO_ANALYTICS_ENABLED'] = 'False'
29
+
30
+
31
+ def check_python_version():
32
+ is_windows = platform.system() == "Windows"
33
+ major = sys.version_info.major
34
+ minor = sys.version_info.minor
35
+ micro = sys.version_info.micro
36
+
37
+ if is_windows:
38
+ supported_minors = [10]
39
+ else:
40
+ supported_minors = [7, 8, 9, 10, 11]
41
+
42
+ if not (major == 3 and minor in supported_minors):
43
+ import modules.errors
44
+
45
+ modules.errors.print_error_explanation(f"""
46
+ INCOMPATIBLE PYTHON VERSION
47
+
48
+ This program is tested with 3.10.6 Python, but you have {major}.{minor}.{micro}.
49
+ If you encounter an error with "RuntimeError: Couldn't install torch." message,
50
+ or any other error regarding unsuccessful package (library) installation,
51
+ please downgrade (or upgrade) to the latest version of 3.10 Python
52
+ and delete current Python and "venv" folder in WebUI's directory.
53
+
54
+ You can download 3.10 Python from here: https://www.python.org/downloads/release/python-3106/
55
+
56
+ {"Alternatively, use a binary release of WebUI: https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases" if is_windows else ""}
57
+
58
+ Use --skip-python-version-check to suppress this warning.
59
+ """)
60
+
61
+
62
+ @lru_cache()
63
+ def commit_hash():
64
+ try:
65
+ return subprocess.check_output([git, "rev-parse", "HEAD"], shell=False, encoding='utf8').strip()
66
+ except Exception:
67
+ return "<none>"
68
+
69
+
70
+ @lru_cache()
71
+ def git_tag():
72
+ try:
73
+ return subprocess.check_output([git, "describe", "--tags"], shell=False, encoding='utf8').strip()
74
+ except Exception:
75
+ try:
76
+
77
+ changelog_md = os.path.join(os.path.dirname(os.path.dirname(__file__)), "CHANGELOG.md")
78
+ with open(changelog_md, "r", encoding="utf-8") as file:
79
+ line = next((line.strip() for line in file if line.strip()), "<none>")
80
+ line = line.replace("## ", "")
81
+ return line
82
+ except Exception:
83
+ return "<none>"
84
+
85
+
86
+ def run(command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live) -> str:
87
+ if desc is not None:
88
+ print(desc)
89
+
90
+ run_kwargs = {
91
+ "args": command,
92
+ "shell": True,
93
+ "env": os.environ if custom_env is None else custom_env,
94
+ "encoding": 'utf8',
95
+ "errors": 'ignore',
96
+ }
97
+
98
+ if not live:
99
+ run_kwargs["stdout"] = run_kwargs["stderr"] = subprocess.PIPE
100
+
101
+ result = subprocess.run(**run_kwargs)
102
+
103
+ if result.returncode != 0:
104
+ error_bits = [
105
+ f"{errdesc or 'Error running command'}.",
106
+ f"Command: {command}",
107
+ f"Error code: {result.returncode}",
108
+ ]
109
+ if result.stdout:
110
+ error_bits.append(f"stdout: {result.stdout}")
111
+ if result.stderr:
112
+ error_bits.append(f"stderr: {result.stderr}")
113
+ raise RuntimeError("\n".join(error_bits))
114
+
115
+ return (result.stdout or "")
116
+
117
+
118
+ def is_installed(package):
119
+ try:
120
+ spec = importlib.util.find_spec(package)
121
+ except ModuleNotFoundError:
122
+ return False
123
+
124
+ return spec is not None
125
+
126
+
127
+ def repo_dir(name):
128
+ return os.path.join(script_path, dir_repos, name)
129
+
130
+
131
+ def run_pip(command, desc=None, live=default_command_live):
132
+ if args.skip_install:
133
+ return
134
+
135
+ index_url_line = f' --index-url {index_url}' if index_url != '' else ''
136
+ return run(f'"{python}" -m pip {command} --prefer-binary{index_url_line}', desc=f"Installing {desc}", errdesc=f"Couldn't install {desc}", live=live)
137
+
138
+
139
+ def check_run_python(code: str) -> bool:
140
+ result = subprocess.run([python, "-c", code], capture_output=True, shell=False)
141
+ return result.returncode == 0
142
+
143
+
144
+ def git_clone(url, dir, name, commithash=None):
145
+ # TODO clone into temporary dir and move if successful
146
+
147
+ if os.path.exists(dir):
148
+ if commithash is None:
149
+ return
150
+
151
+ current_hash = run(f'"{git}" -C "{dir}" rev-parse HEAD', None, f"Couldn't determine {name}'s hash: {commithash}", live=False).strip()
152
+ if current_hash == commithash:
153
+ return
154
+
155
+ run(f'"{git}" -C "{dir}" fetch', f"Fetching updates for {name}...", f"Couldn't fetch {name}")
156
+ 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}", live=True)
157
+ return
158
+
159
+ run(f'"{git}" clone "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}", live=True)
160
+
161
+ if commithash is not None:
162
+ run(f'"{git}" -C "{dir}" reset --hard {commithash}', None, "Couldn't checkout {name}'s hash: {commithash}")
163
+
164
+
165
+ def git_pull_recursive(dir):
166
+ for subdir, _, _ in os.walk(dir):
167
+ if os.path.exists(os.path.join(subdir, '.git')):
168
+ try:
169
+ output = subprocess.check_output([git, '-C', subdir, 'pull', '--autostash'])
170
+ print(f"Pulled changes for repository in '{subdir}':\n{output.decode('utf-8').strip()}\n")
171
+ except subprocess.CalledProcessError as e:
172
+ print(f"Couldn't perform 'git pull' on repository in '{subdir}':\n{e.output.decode('utf-8').strip()}\n")
173
+
174
+
175
+ def version_check(commit):
176
+ try:
177
+ import requests
178
+ commits = requests.get('https://api.github.com/repos/AUTOMATIC1111/stable-diffusion-webui/branches/master').json()
179
+ if commit != "<none>" and commits['commit']['sha'] != commit:
180
+ print("--------------------------------------------------------")
181
+ print("| You are not up to date with the most recent release. |")
182
+ print("| Consider running `git pull` to update. |")
183
+ print("--------------------------------------------------------")
184
+ elif commits['commit']['sha'] == commit:
185
+ print("You are up to date with the most recent release.")
186
+ else:
187
+ print("Not a git clone, can't perform version check.")
188
+ except Exception as e:
189
+ print("version check failed", e)
190
+
191
+
192
+ def run_extension_installer(extension_dir):
193
+ path_installer = os.path.join(extension_dir, "install.py")
194
+ if not os.path.isfile(path_installer):
195
+ return
196
+
197
+ try:
198
+ env = os.environ.copy()
199
+ env['PYTHONPATH'] = f"{os.path.abspath('.')}{os.pathsep}{env.get('PYTHONPATH', '')}"
200
+
201
+ print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env))
202
+ except Exception as e:
203
+ errors.report(str(e))
204
+
205
+
206
+ def list_extensions(settings_file):
207
+ settings = {}
208
+
209
+ try:
210
+ if os.path.isfile(settings_file):
211
+ with open(settings_file, "r", encoding="utf8") as file:
212
+ settings = json.load(file)
213
+ except Exception:
214
+ errors.report("Could not load settings", exc_info=True)
215
+
216
+ disabled_extensions = set(settings.get('disabled_extensions', []))
217
+ disable_all_extensions = settings.get('disable_all_extensions', 'none')
218
+
219
+ if disable_all_extensions != 'none':
220
+ return []
221
+
222
+ return [x for x in os.listdir(extensions_dir) if x not in disabled_extensions]
223
+
224
+
225
+ def run_extensions_installers(settings_file):
226
+ if not os.path.isdir(extensions_dir):
227
+ return
228
+
229
+ for dirname_extension in list_extensions(settings_file):
230
+ run_extension_installer(os.path.join(extensions_dir, dirname_extension))
231
+
232
+
233
+ re_requirement = re.compile(r"\s*([-_a-zA-Z0-9]+)\s*(?:==\s*([-+_.a-zA-Z0-9]+))?\s*")
234
+
235
+
236
+ def requirements_met(requirements_file):
237
+ """
238
+ Does a simple parse of a requirements.txt file to determine if all rerqirements in it
239
+ are already installed. Returns True if so, False if not installed or parsing fails.
240
+ """
241
+
242
+ import importlib.metadata
243
+ import packaging.version
244
+
245
+ with open(requirements_file, "r", encoding="utf8") as file:
246
+ for line in file:
247
+ if line.strip() == "":
248
+ continue
249
+
250
+ m = re.match(re_requirement, line)
251
+ if m is None:
252
+ return False
253
+
254
+ package = m.group(1).strip()
255
+ version_required = (m.group(2) or "").strip()
256
+
257
+ if version_required == "":
258
+ continue
259
+
260
+ try:
261
+ version_installed = importlib.metadata.version(package)
262
+ except Exception:
263
+ return False
264
+
265
+ if packaging.version.parse(version_required) != packaging.version.parse(version_installed):
266
+ return False
267
+
268
+ return True
269
+
270
+
271
+ def prepare_environment():
272
+ torch_index_url = os.environ.get('TORCH_INDEX_URL', "https://download.pytorch.org/whl/cu118")
273
+ torch_command = os.environ.get('TORCH_COMMAND', f"pip install torch==2.0.1 torchvision==0.15.2 --extra-index-url {torch_index_url}")
274
+ requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")
275
+
276
+ xformers_package = os.environ.get('XFORMERS_PACKAGE', 'xformers==0.0.20')
277
+ gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "https://github.com/TencentARC/GFPGAN/archive/8d2447a2d918f8eba5a4a01463fd48e45126a379.zip")
278
+ clip_package = os.environ.get('CLIP_PACKAGE', "https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip")
279
+ openclip_package = os.environ.get('OPENCLIP_PACKAGE', "https://github.com/mlfoundations/open_clip/archive/bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b.zip")
280
+
281
+ stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/Stability-AI/stablediffusion.git")
282
+ stable_diffusion_xl_repo = os.environ.get('STABLE_DIFFUSION_XL_REPO', "https://github.com/Stability-AI/generative-models.git")
283
+ k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')
284
+ codeformer_repo = os.environ.get('CODEFORMER_REPO', 'https://github.com/sczhou/CodeFormer.git')
285
+ blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')
286
+
287
+ stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf")
288
+ stable_diffusion_xl_commit_hash = os.environ.get('STABLE_DIFFUSION_XL_COMMIT_HASH', "5c10deee76adad0032b412294130090932317a87")
289
+ k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "c9fe758757e022f05ca5a53fa8fac28889e4f1cf")
290
+ codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH', "c5b4593074ba6214284d6acd5f1719b6c5d739af")
291
+ blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH', "48211a1594f1321b00f14c9f7a5b4813144b2fb9")
292
+
293
+ try:
294
+ # the existance of this file is a signal to webui.sh/bat that webui needs to be restarted when it stops execution
295
+ os.remove(os.path.join(script_path, "tmp", "restart"))
296
+ os.environ.setdefault('SD_WEBUI_RESTARTING', '1')
297
+ except OSError:
298
+ pass
299
+
300
+ if not args.skip_python_version_check:
301
+ check_python_version()
302
+
303
+ commit = commit_hash()
304
+ tag = git_tag()
305
+
306
+ print(f"Python {sys.version}")
307
+ print(f"Version: {tag}")
308
+ print(f"Commit hash: {commit}")
309
+
310
+ if args.reinstall_torch or not is_installed("torch") or not is_installed("torchvision"):
311
+ run(f'"{python}" -m {torch_command}', "Installing torch and torchvision", "Couldn't install torch", live=True)
312
+
313
+ if not args.skip_torch_cuda_test and not check_run_python("import torch; assert torch.cuda.is_available()"):
314
+ raise RuntimeError(
315
+ 'Torch is not able to use GPU; '
316
+ 'add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check'
317
+ )
318
+
319
+ if not is_installed("gfpgan"):
320
+ run_pip(f"install {gfpgan_package}", "gfpgan")
321
+
322
+ if not is_installed("clip"):
323
+ run_pip(f"install {clip_package}", "clip")
324
+
325
+ if not is_installed("open_clip"):
326
+ run_pip(f"install {openclip_package}", "open_clip")
327
+
328
+ if (not is_installed("xformers") or args.reinstall_xformers) and args.xformers:
329
+ if platform.system() == "Windows":
330
+ if platform.python_version().startswith("3.10"):
331
+ run_pip(f"install -U -I --no-deps {xformers_package}", "xformers", live=True)
332
+ else:
333
+ print("Installation of xformers is not supported in this version of Python.")
334
+ print("You can also check this and build manually: https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers#building-xformers-on-windows-by-duckness")
335
+ if not is_installed("xformers"):
336
+ exit(0)
337
+ elif platform.system() == "Linux":
338
+ run_pip(f"install -U -I --no-deps {xformers_package}", "xformers")
339
+
340
+ if not is_installed("ngrok") and args.ngrok:
341
+ run_pip("install ngrok", "ngrok")
342
+
343
+ os.makedirs(os.path.join(script_path, dir_repos), exist_ok=True)
344
+
345
+ git_clone(stable_diffusion_repo, repo_dir('stable-diffusion-stability-ai'), "Stable Diffusion", stable_diffusion_commit_hash)
346
+ git_clone(stable_diffusion_xl_repo, repo_dir('generative-models'), "Stable Diffusion XL", stable_diffusion_xl_commit_hash)
347
+ git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
348
+ git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
349
+ git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash)
350
+
351
+ if not is_installed("lpips"):
352
+ run_pip(f"install -r \"{os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}\"", "requirements for CodeFormer")
353
+
354
+ if not os.path.isfile(requirements_file):
355
+ requirements_file = os.path.join(script_path, requirements_file)
356
+
357
+ if not requirements_met(requirements_file):
358
+ run_pip(f"install -r \"{requirements_file}\"", "requirements")
359
+
360
+ run_extensions_installers(settings_file=args.ui_settings_file)
361
+
362
+ if args.update_check:
363
+ version_check(commit)
364
+
365
+ if args.update_all_extensions:
366
+ git_pull_recursive(extensions_dir)
367
+
368
+ if "--exit" in sys.argv:
369
+ print("Exiting because of --exit argument")
370
+ exit(0)
371
+
372
+
373
+
374
+ def configure_for_tests():
375
+ if "--api" not in sys.argv:
376
+ sys.argv.append("--api")
377
+ if "--ckpt" not in sys.argv:
378
+ sys.argv.append("--ckpt")
379
+ sys.argv.append(os.path.join(script_path, "test/test_files/empty.pt"))
380
+ if "--skip-torch-cuda-test" not in sys.argv:
381
+ sys.argv.append("--skip-torch-cuda-test")
382
+ if "--disable-nan-check" not in sys.argv:
383
+ sys.argv.append("--disable-nan-check")
384
+
385
+ os.environ['COMMANDLINE_ARGS'] = ""
386
+
387
+
388
+ def start():
389
+ print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")
390
+ import webui
391
+ if '--nowebui' in sys.argv:
392
+ webui.api_only()
393
+ else:
394
+ webui.webui()
direct/v1.5.2/lib.zst ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:41e5b3d4cd7898aa86ce1f590e7247bdc08b22d9fc957b45bad792a2004583a9
3
+ size 271539969
direct/v1.5.2/repositories.tar ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b9c7204789a2fc3b0e751f47751f27252f939d7e308cb0bfc67ab8c0ac66b21a
3
+ size 266485760
direct/v1.6.0/directui.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import time
5
+
6
+ from modules import timer
7
+ from modules import initialize_util
8
+ from modules import initialize
9
+
10
+ startup_timer = timer.startup_timer
11
+
12
+ initialize.imports()
13
+
14
+ initialize.check_versions()
15
+
16
+
17
+ def create_api(app):
18
+ from modules.api.api import Api
19
+ from modules.call_queue import queue_lock
20
+
21
+ api = Api(app, queue_lock)
22
+ return api
23
+
24
+
25
+ def api_only():
26
+ from fastapi import FastAPI
27
+ from modules.shared_cmd_options import cmd_opts
28
+
29
+ initialize.initialize()
30
+
31
+ app = FastAPI()
32
+ initialize_util.setup_middleware(app)
33
+ api = create_api(app)
34
+
35
+ from modules import script_callbacks
36
+ script_callbacks.before_ui_callback()
37
+ script_callbacks.app_started_callback(None, app)
38
+
39
+ print(f"Startup time: {startup_timer.summary()}.")
40
+ api.launch(
41
+ server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1",
42
+ port=cmd_opts.port if cmd_opts.port else 7861,
43
+ root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else ""
44
+ )
45
+
46
+
47
+ def webui():
48
+ from modules.shared_cmd_options import cmd_opts
49
+
50
+ launch_api = cmd_opts.api
51
+ initialize.initialize()
52
+
53
+ from modules import shared, ui_tempdir, script_callbacks, ui, progress, ui_extra_networks
54
+
55
+ while 1:
56
+ if shared.opts.clean_temp_dir_at_start:
57
+ ui_tempdir.cleanup_tmpdr()
58
+
59
+ script_callbacks.before_ui_callback()
60
+
61
+ shared.demo = ui.create_ui()
62
+
63
+ app, local_url, share_url = shared.demo.launch(
64
+ height=3000,
65
+ prevent_thread_lock=True
66
+ )
67
+
68
+ app.user_middleware = [x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware']
69
+ initialize_util.setup_middleware(app)
70
+ progress.setup_progress_api(app)
71
+ ui.setup_ui_api(app)
72
+
73
+ with startup_timer.subcategory("app_started_callback"):
74
+ script_callbacks.app_started_callback(shared.demo, app)
75
+
76
+ timer.startup_record = startup_timer.dump()
77
+ print(f"Startup time: {startup_timer.summary()}.")
78
+
79
+ try:
80
+ while True:
81
+ server_command = shared.state.wait_for_server_command(timeout=5)
82
+ if server_command:
83
+ if server_command in ("stop", "restart"):
84
+ break
85
+ else:
86
+ print(f"Unknown server command: {server_command}")
87
+ except KeyboardInterrupt:
88
+ print('Caught KeyboardInterrupt, stopping...')
89
+ server_command = "stop"
90
+
91
+ if server_command == "stop":
92
+ print("Stopping server...")
93
+ # If we catch a keyboard interrupt, we want to stop the server and exit.
94
+ shared.demo.close()
95
+ break
96
+
97
+ print('Restarting UI...')
98
+ shared.demo.close()
99
+ time.sleep(0.5)
100
+ startup_timer.reset()
101
+ script_callbacks.app_reload_callback()
102
+ script_callbacks.script_unloaded_callback()
103
+ initialize.initialize_rest(reload_script_modules=True)
104
+
105
+
106
+ if __name__ == "__main__":
107
+ from modules.shared_cmd_options import cmd_opts
108
+
109
+ if cmd_opts.nowebui:
110
+ api_only()
111
+ else:
112
+ webui()
direct/v1.6.0/launch_utils.py ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this scripts installs necessary requirements and launches main program in webui.py
2
+ import logging
3
+ import re
4
+ import subprocess
5
+ import os
6
+ import shutil
7
+ import sys
8
+ import importlib.util
9
+ import platform
10
+ import json
11
+ from functools import lru_cache
12
+
13
+ from modules import cmd_args, errors
14
+ from modules.paths_internal import script_path, extensions_dir
15
+ from modules.timer import startup_timer
16
+ from modules import logging_config
17
+
18
+ args, _ = cmd_args.parser.parse_known_args()
19
+ logging_config.setup_logging(args.loglevel)
20
+
21
+ python = sys.executable
22
+ git = os.environ.get('GIT', "git")
23
+ index_url = os.environ.get('INDEX_URL', "")
24
+ dir_repos = "repositories"
25
+
26
+ # Whether to default to printing command output
27
+ default_command_live = (os.environ.get('WEBUI_LAUNCH_LIVE_OUTPUT') == "1")
28
+
29
+ if 'GRADIO_ANALYTICS_ENABLED' not in os.environ:
30
+ os.environ['GRADIO_ANALYTICS_ENABLED'] = 'False'
31
+
32
+
33
+ def check_python_version():
34
+ is_windows = platform.system() == "Windows"
35
+ major = sys.version_info.major
36
+ minor = sys.version_info.minor
37
+ micro = sys.version_info.micro
38
+
39
+ if is_windows:
40
+ supported_minors = [10]
41
+ else:
42
+ supported_minors = [7, 8, 9, 10, 11]
43
+
44
+ if not (major == 3 and minor in supported_minors):
45
+ import modules.errors
46
+
47
+ modules.errors.print_error_explanation(f"""
48
+ INCOMPATIBLE PYTHON VERSION
49
+
50
+ This program is tested with 3.10.6 Python, but you have {major}.{minor}.{micro}.
51
+ If you encounter an error with "RuntimeError: Couldn't install torch." message,
52
+ or any other error regarding unsuccessful package (library) installation,
53
+ please downgrade (or upgrade) to the latest version of 3.10 Python
54
+ and delete current Python and "venv" folder in WebUI's directory.
55
+
56
+ You can download 3.10 Python from here: https://www.python.org/downloads/release/python-3106/
57
+
58
+ {"Alternatively, use a binary release of WebUI: https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases" if is_windows else ""}
59
+
60
+ Use --skip-python-version-check to suppress this warning.
61
+ """)
62
+
63
+
64
+ @lru_cache()
65
+ def commit_hash():
66
+ try:
67
+ return subprocess.check_output([git, "rev-parse", "HEAD"], shell=False, encoding='utf8').strip()
68
+ except Exception:
69
+ return "<none>"
70
+
71
+
72
+ @lru_cache()
73
+ def git_tag():
74
+ try:
75
+ return subprocess.check_output([git, "describe", "--tags"], shell=False, encoding='utf8').strip()
76
+ except Exception:
77
+ try:
78
+
79
+ changelog_md = os.path.join(os.path.dirname(os.path.dirname(__file__)), "CHANGELOG.md")
80
+ with open(changelog_md, "r", encoding="utf-8") as file:
81
+ line = next((line.strip() for line in file if line.strip()), "<none>")
82
+ line = line.replace("## ", "")
83
+ return line
84
+ except Exception:
85
+ return "<none>"
86
+
87
+
88
+ def run(command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live) -> str:
89
+ if desc is not None:
90
+ print(desc)
91
+
92
+ run_kwargs = {
93
+ "args": command,
94
+ "shell": True,
95
+ "env": os.environ if custom_env is None else custom_env,
96
+ "encoding": 'utf8',
97
+ "errors": 'ignore',
98
+ }
99
+
100
+ if not live:
101
+ run_kwargs["stdout"] = run_kwargs["stderr"] = subprocess.PIPE
102
+
103
+ result = subprocess.run(**run_kwargs)
104
+
105
+ if result.returncode != 0:
106
+ error_bits = [
107
+ f"{errdesc or 'Error running command'}.",
108
+ f"Command: {command}",
109
+ f"Error code: {result.returncode}",
110
+ ]
111
+ if result.stdout:
112
+ error_bits.append(f"stdout: {result.stdout}")
113
+ if result.stderr:
114
+ error_bits.append(f"stderr: {result.stderr}")
115
+ raise RuntimeError("\n".join(error_bits))
116
+
117
+ return (result.stdout or "")
118
+
119
+
120
+ def is_installed(package):
121
+ try:
122
+ spec = importlib.util.find_spec(package)
123
+ except ModuleNotFoundError:
124
+ return False
125
+
126
+ return spec is not None
127
+
128
+
129
+ def repo_dir(name):
130
+ return os.path.join(script_path, dir_repos, name)
131
+
132
+
133
+ def run_pip(command, desc=None, live=default_command_live):
134
+ if args.skip_install:
135
+ return
136
+
137
+ index_url_line = f' --index-url {index_url}' if index_url != '' else ''
138
+ return run(f'"{python}" -m pip {command} --prefer-binary{index_url_line}', desc=f"Installing {desc}", errdesc=f"Couldn't install {desc}", live=live)
139
+
140
+
141
+ def check_run_python(code: str) -> bool:
142
+ result = subprocess.run([python, "-c", code], capture_output=True, shell=False)
143
+ return result.returncode == 0
144
+
145
+
146
+ def git_fix_workspace(dir, name):
147
+ run(f'"{git}" -C "{dir}" fetch --refetch --no-auto-gc', f"Fetching all contents for {name}", f"Couldn't fetch {name}", live=True)
148
+ run(f'"{git}" -C "{dir}" gc --aggressive --prune=now', f"Pruning {name}", f"Couldn't prune {name}", live=True)
149
+ return
150
+
151
+
152
+ def run_git(dir, name, command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live, autofix=True):
153
+ try:
154
+ return run(f'"{git}" -C "{dir}" {command}', desc=desc, errdesc=errdesc, custom_env=custom_env, live=live)
155
+ except RuntimeError:
156
+ if not autofix:
157
+ raise
158
+
159
+ print(f"{errdesc}, attempting autofix...")
160
+ git_fix_workspace(dir, name)
161
+
162
+ return run(f'"{git}" -C "{dir}" {command}', desc=desc, errdesc=errdesc, custom_env=custom_env, live=live)
163
+
164
+
165
+ def git_clone(url, dir, name, commithash=None):
166
+ # TODO clone into temporary dir and move if successful
167
+
168
+ if os.path.exists(dir):
169
+ if commithash is None:
170
+ return
171
+
172
+ current_hash = run_git(dir, name, 'rev-parse HEAD', None, f"Couldn't determine {name}'s hash: {commithash}", live=False).strip()
173
+ if current_hash == commithash:
174
+ return
175
+
176
+ if run_git(dir, name, 'config --get remote.origin.url', None, f"Couldn't determine {name}'s origin URL", live=False).strip() != url:
177
+ run_git(dir, name, f'remote set-url origin "{url}"', None, f"Failed to set {name}'s origin URL", live=False)
178
+
179
+ run_git(dir, name, 'fetch', f"Fetching updates for {name}...", f"Couldn't fetch {name}", autofix=False)
180
+
181
+ run_git(dir, name, f'reset --hard {commithash}', f"Checking out commit for {name} with hash: {commithash}...", f"Couldn't checkout commit {commithash} for {name}", live=True)
182
+
183
+ return
184
+
185
+ try:
186
+ run(f'"{git}" clone "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}", live=True)
187
+ except RuntimeError:
188
+ shutil.rmtree(dir, ignore_errors=True)
189
+ raise
190
+
191
+ if commithash is not None:
192
+ run(f'"{git}" -C "{dir}" reset --hard {commithash}', None, "Couldn't checkout {name}'s hash: {commithash}")
193
+
194
+
195
+ def git_pull_recursive(dir):
196
+ for subdir, _, _ in os.walk(dir):
197
+ if os.path.exists(os.path.join(subdir, '.git')):
198
+ try:
199
+ output = subprocess.check_output([git, '-C', subdir, 'pull', '--autostash'])
200
+ print(f"Pulled changes for repository in '{subdir}':\n{output.decode('utf-8').strip()}\n")
201
+ except subprocess.CalledProcessError as e:
202
+ print(f"Couldn't perform 'git pull' on repository in '{subdir}':\n{e.output.decode('utf-8').strip()}\n")
203
+
204
+
205
+ def version_check(commit):
206
+ try:
207
+ import requests
208
+ commits = requests.get('https://api.github.com/repos/AUTOMATIC1111/stable-diffusion-webui/branches/master').json()
209
+ if commit != "<none>" and commits['commit']['sha'] != commit:
210
+ print("--------------------------------------------------------")
211
+ print("| You are not up to date with the most recent release. |")
212
+ print("| Consider running `git pull` to update. |")
213
+ print("--------------------------------------------------------")
214
+ elif commits['commit']['sha'] == commit:
215
+ print("You are up to date with the most recent release.")
216
+ else:
217
+ print("Not a git clone, can't perform version check.")
218
+ except Exception as e:
219
+ print("version check failed", e)
220
+
221
+
222
+ def run_extension_installer(extension_dir):
223
+ path_installer = os.path.join(extension_dir, "install.py")
224
+ if not os.path.isfile(path_installer):
225
+ return
226
+
227
+ try:
228
+ env = os.environ.copy()
229
+ env['PYTHONPATH'] = f"{os.path.abspath('.')}{os.pathsep}{env.get('PYTHONPATH', '')}"
230
+
231
+ stdout = run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env).strip()
232
+ if stdout:
233
+ print(stdout)
234
+ except Exception as e:
235
+ errors.report(str(e))
236
+
237
+
238
+ def list_extensions(settings_file):
239
+ settings = {}
240
+
241
+ try:
242
+ if os.path.isfile(settings_file):
243
+ with open(settings_file, "r", encoding="utf8") as file:
244
+ settings = json.load(file)
245
+ except Exception:
246
+ errors.report("Could not load settings", exc_info=True)
247
+
248
+ disabled_extensions = set(settings.get('disabled_extensions', []))
249
+ disable_all_extensions = settings.get('disable_all_extensions', 'none')
250
+
251
+ if disable_all_extensions != 'none' or args.disable_extra_extensions or args.disable_all_extensions or not os.path.isdir(extensions_dir):
252
+ return []
253
+
254
+ return [x for x in os.listdir(extensions_dir) if x not in disabled_extensions]
255
+
256
+
257
+ def run_extensions_installers(settings_file):
258
+ if not os.path.isdir(extensions_dir):
259
+ return
260
+
261
+ with startup_timer.subcategory("run extensions installers"):
262
+ for dirname_extension in list_extensions(settings_file):
263
+ logging.debug(f"Installing {dirname_extension}")
264
+
265
+ path = os.path.join(extensions_dir, dirname_extension)
266
+
267
+ if os.path.isdir(path):
268
+ run_extension_installer(path)
269
+ startup_timer.record(dirname_extension)
270
+
271
+
272
+ re_requirement = re.compile(r"\s*([-_a-zA-Z0-9]+)\s*(?:==\s*([-+_.a-zA-Z0-9]+))?\s*")
273
+
274
+
275
+ def requirements_met(requirements_file):
276
+ """
277
+ Does a simple parse of a requirements.txt file to determine if all rerqirements in it
278
+ are already installed. Returns True if so, False if not installed or parsing fails.
279
+ """
280
+
281
+ import importlib.metadata
282
+ import packaging.version
283
+
284
+ with open(requirements_file, "r", encoding="utf8") as file:
285
+ for line in file:
286
+ if line.strip() == "":
287
+ continue
288
+
289
+ m = re.match(re_requirement, line)
290
+ if m is None:
291
+ return False
292
+
293
+ package = m.group(1).strip()
294
+ version_required = (m.group(2) or "").strip()
295
+
296
+ if version_required == "":
297
+ continue
298
+
299
+ try:
300
+ version_installed = importlib.metadata.version(package)
301
+ except Exception:
302
+ return False
303
+
304
+ if packaging.version.parse(version_required) != packaging.version.parse(version_installed):
305
+ return False
306
+
307
+ return True
308
+
309
+
310
+ def prepare_environment():
311
+ torch_index_url = os.environ.get('TORCH_INDEX_URL', "https://download.pytorch.org/whl/cu118")
312
+ torch_command = os.environ.get('TORCH_COMMAND', f"pip install torch==2.0.1 torchvision==0.15.2 --extra-index-url {torch_index_url}")
313
+ requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")
314
+
315
+ xformers_package = os.environ.get('XFORMERS_PACKAGE', 'xformers==0.0.20')
316
+ clip_package = os.environ.get('CLIP_PACKAGE', "https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip")
317
+ openclip_package = os.environ.get('OPENCLIP_PACKAGE', "https://github.com/mlfoundations/open_clip/archive/bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b.zip")
318
+
319
+ stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/Stability-AI/stablediffusion.git")
320
+ stable_diffusion_xl_repo = os.environ.get('STABLE_DIFFUSION_XL_REPO', "https://github.com/Stability-AI/generative-models.git")
321
+ k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')
322
+ codeformer_repo = os.environ.get('CODEFORMER_REPO', 'https://github.com/sczhou/CodeFormer.git')
323
+ blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')
324
+
325
+ stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf")
326
+ stable_diffusion_xl_commit_hash = os.environ.get('STABLE_DIFFUSION_XL_COMMIT_HASH', "45c443b316737a4ab6e40413d7794a7f5657c19f")
327
+ k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "ab527a9a6d347f364e3d185ba6d714e22d80cb3c")
328
+ codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH', "c5b4593074ba6214284d6acd5f1719b6c5d739af")
329
+ blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH', "48211a1594f1321b00f14c9f7a5b4813144b2fb9")
330
+
331
+ try:
332
+ # the existence of this file is a signal to webui.sh/bat that webui needs to be restarted when it stops execution
333
+ os.remove(os.path.join(script_path, "tmp", "restart"))
334
+ os.environ.setdefault('SD_WEBUI_RESTARTING', '1')
335
+ except OSError:
336
+ pass
337
+
338
+ if not args.skip_python_version_check:
339
+ check_python_version()
340
+
341
+ startup_timer.record("checks")
342
+
343
+ commit = commit_hash()
344
+ tag = git_tag()
345
+ startup_timer.record("git version info")
346
+
347
+ print(f"Python {sys.version}")
348
+ print(f"Version: {tag}")
349
+ print(f"Commit hash: {commit}")
350
+
351
+ if args.reinstall_torch or not is_installed("torch") or not is_installed("torchvision"):
352
+ run(f'"{python}" -m {torch_command}', "Installing torch and torchvision", "Couldn't install torch", live=True)
353
+ startup_timer.record("install torch")
354
+
355
+ if not args.skip_torch_cuda_test and not check_run_python("import torch; assert torch.cuda.is_available()"):
356
+ raise RuntimeError(
357
+ 'Torch is not able to use GPU; '
358
+ 'add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check'
359
+ )
360
+ startup_timer.record("torch GPU test")
361
+
362
+ if not is_installed("clip"):
363
+ run_pip(f"install {clip_package}", "clip")
364
+ startup_timer.record("install clip")
365
+
366
+ if not is_installed("open_clip"):
367
+ run_pip(f"install {openclip_package}", "open_clip")
368
+ startup_timer.record("install open_clip")
369
+
370
+ if (not is_installed("xformers") or args.reinstall_xformers) and args.xformers:
371
+ run_pip(f"install -U -I --no-deps {xformers_package}", "xformers")
372
+ startup_timer.record("install xformers")
373
+
374
+ if not is_installed("ngrok") and args.ngrok:
375
+ run_pip("install ngrok", "ngrok")
376
+ startup_timer.record("install ngrok")
377
+
378
+ os.makedirs(os.path.join(script_path, dir_repos), exist_ok=True)
379
+
380
+ git_clone(stable_diffusion_repo, repo_dir('stable-diffusion-stability-ai'), "Stable Diffusion", stable_diffusion_commit_hash)
381
+ git_clone(stable_diffusion_xl_repo, repo_dir('generative-models'), "Stable Diffusion XL", stable_diffusion_xl_commit_hash)
382
+ git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
383
+ git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
384
+ git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash)
385
+
386
+ startup_timer.record("clone repositores")
387
+
388
+ if not is_installed("lpips"):
389
+ run_pip(f"install -r \"{os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}\"", "requirements for CodeFormer")
390
+ startup_timer.record("install CodeFormer requirements")
391
+
392
+ if not os.path.isfile(requirements_file):
393
+ requirements_file = os.path.join(script_path, requirements_file)
394
+
395
+ if not requirements_met(requirements_file):
396
+ run_pip(f"install -r \"{requirements_file}\"", "requirements")
397
+ startup_timer.record("install requirements")
398
+
399
+ if not args.skip_install:
400
+ run_extensions_installers(settings_file=args.ui_settings_file)
401
+
402
+ if args.update_check:
403
+ version_check(commit)
404
+ startup_timer.record("check version")
405
+
406
+ if args.update_all_extensions:
407
+ git_pull_recursive(extensions_dir)
408
+ startup_timer.record("update extensions")
409
+
410
+ if "--exit" in sys.argv:
411
+ print("Exiting because of --exit argument")
412
+ exit(0)
413
+
414
+
415
+
416
+ def configure_for_tests():
417
+ if "--api" not in sys.argv:
418
+ sys.argv.append("--api")
419
+ if "--ckpt" not in sys.argv:
420
+ sys.argv.append("--ckpt")
421
+ sys.argv.append(os.path.join(script_path, "test/test_files/empty.pt"))
422
+ if "--skip-torch-cuda-test" not in sys.argv:
423
+ sys.argv.append("--skip-torch-cuda-test")
424
+ if "--disable-nan-check" not in sys.argv:
425
+ sys.argv.append("--disable-nan-check")
426
+
427
+ os.environ['COMMANDLINE_ARGS'] = ""
428
+
429
+
430
+ def start():
431
+ print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")
432
+ import webui
433
+ if '--nowebui' in sys.argv:
434
+ webui.api_only()
435
+ else:
436
+ webui.webui()
437
+
438
+
439
+ def dump_sysinfo():
440
+ from modules import sysinfo
441
+ import datetime
442
+
443
+ text = sysinfo.get()
444
+ filename = f"sysinfo-{datetime.datetime.utcnow().strftime('%Y-%m-%d-%H-%M')}.txt"
445
+
446
+ with open(filename, "w", encoding="utf8") as file:
447
+ file.write(text)
448
+
449
+ return filename
direct/v1.6.0/lib.zst ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7206c1a52280e5df3d4c7d78fdf2018a2835ae3b08fe68ce3c43ef922502e486
3
+ size 275382089
direct/v1.6.0/repositories.tar ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:04be1ab31d5a8d4d2e020f50506e3267dcb780787319f91bbdaed943cb65c3d9
3
+ size 252610560
direct/v1.7.0/directui.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import time
5
+
6
+ from modules import timer
7
+ from modules import initialize_util
8
+ from modules import initialize
9
+
10
+ startup_timer = timer.startup_timer
11
+ startup_timer.record("launcher")
12
+
13
+ initialize.imports()
14
+
15
+ initialize.check_versions()
16
+
17
+
18
+ def create_api(app):
19
+ from modules.api.api import Api
20
+ from modules.call_queue import queue_lock
21
+
22
+ api = Api(app, queue_lock)
23
+ return api
24
+
25
+
26
+ def api_only():
27
+ from fastapi import FastAPI
28
+ from modules.shared_cmd_options import cmd_opts
29
+
30
+ initialize.initialize()
31
+
32
+ app = FastAPI()
33
+ initialize_util.setup_middleware(app)
34
+ api = create_api(app)
35
+
36
+ from modules import script_callbacks
37
+
38
+ script_callbacks.before_ui_callback()
39
+ script_callbacks.app_started_callback(None, app)
40
+
41
+ print(f"Startup time: {startup_timer.summary()}.")
42
+ api.launch(
43
+ server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1",
44
+ port=cmd_opts.port if cmd_opts.port else 7861,
45
+ root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else "",
46
+ )
47
+
48
+
49
+ def webui():
50
+ from modules.shared_cmd_options import cmd_opts
51
+
52
+ launch_api = cmd_opts.api
53
+ initialize.initialize()
54
+
55
+ from modules import (
56
+ shared,
57
+ ui_tempdir,
58
+ script_callbacks,
59
+ ui,
60
+ progress,
61
+ ui_extra_networks,
62
+ )
63
+
64
+ while 1:
65
+ if shared.opts.clean_temp_dir_at_start:
66
+ ui_tempdir.cleanup_tmpdr()
67
+ startup_timer.record("cleanup temp dir")
68
+
69
+ script_callbacks.before_ui_callback()
70
+ startup_timer.record("scripts before_ui_callback")
71
+
72
+ shared.demo = ui.create_ui()
73
+ startup_timer.record("create ui")
74
+
75
+ app, local_url, share_url = shared.demo.launch(
76
+ height=3000, prevent_thread_lock=True
77
+ )
78
+
79
+ startup_timer.record("gradio launch")
80
+
81
+ # gradio uses a very open CORS policy via app.user_middleware, which makes it possible for
82
+ # an attacker to trick the user into opening a malicious HTML page, which makes a request to the
83
+ # running web ui and do whatever the attacker wants, including installing an extension and
84
+ # running its code. We disable this here. Suggested by RyotaK.
85
+ app.user_middleware = [
86
+ x for x in app.user_middleware if x.cls.__name__ != "CORSMiddleware"
87
+ ]
88
+
89
+ initialize_util.setup_middleware(app)
90
+
91
+ progress.setup_progress_api(app)
92
+ ui.setup_ui_api(app)
93
+
94
+ if launch_api:
95
+ create_api(app)
96
+
97
+ ui_extra_networks.add_pages_to_demo(app)
98
+
99
+ startup_timer.record("add APIs")
100
+
101
+ with startup_timer.subcategory("app_started_callback"):
102
+ script_callbacks.app_started_callback(shared.demo, app)
103
+
104
+ timer.startup_record = startup_timer.dump()
105
+ print(f"Startup time: {startup_timer.summary()}.")
106
+
107
+ try:
108
+ while True:
109
+ server_command = shared.state.wait_for_server_command(timeout=5)
110
+ if server_command:
111
+ if server_command in ("stop", "restart"):
112
+ break
113
+ else:
114
+ print(f"Unknown server command: {server_command}")
115
+ except KeyboardInterrupt:
116
+ print("Caught KeyboardInterrupt, stopping...")
117
+ server_command = "stop"
118
+
119
+ if server_command == "stop":
120
+ print("Stopping server...")
121
+ # If we catch a keyboard interrupt, we want to stop the server and exit.
122
+ shared.demo.close()
123
+ break
124
+
125
+ # disable auto launch webui in browser for subsequent UI Reload
126
+ os.environ.setdefault("SD_WEBUI_RESTARTING", "1")
127
+
128
+ print("Restarting UI...")
129
+ shared.demo.close()
130
+ time.sleep(0.5)
131
+ startup_timer.reset()
132
+ script_callbacks.app_reload_callback()
133
+ startup_timer.record("app reload callback")
134
+ script_callbacks.script_unloaded_callback()
135
+ startup_timer.record("scripts unloaded callback")
136
+ initialize.initialize_rest(reload_script_modules=True)
137
+
138
+
139
+ if __name__ == "__main__":
140
+ from modules.shared_cmd_options import cmd_opts
141
+
142
+ if cmd_opts.nowebui:
143
+ api_only()
144
+ else:
145
+ webui()
direct/v1.7.0/launch_utils.py ADDED
@@ -0,0 +1,663 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this scripts installs necessary requirements and launches main program in webui.py
2
+ import logging
3
+ import re
4
+ import subprocess
5
+ import os
6
+ import shutil
7
+ import sys
8
+ import importlib.util
9
+ import importlib.metadata
10
+ import platform
11
+ import json
12
+ from functools import lru_cache
13
+
14
+ from modules import cmd_args, errors
15
+ from modules.paths_internal import script_path, extensions_dir
16
+ from modules.timer import startup_timer
17
+ from modules import logging_config
18
+
19
+ args, _ = cmd_args.parser.parse_known_args()
20
+ logging_config.setup_logging(args.loglevel)
21
+
22
+ python = sys.executable
23
+ git = os.environ.get("GIT", "git")
24
+ index_url = os.environ.get("INDEX_URL", "")
25
+ dir_repos = "repositories"
26
+
27
+ # Whether to default to printing command output
28
+ default_command_live = os.environ.get("WEBUI_LAUNCH_LIVE_OUTPUT") == "1"
29
+
30
+ if "GRADIO_ANALYTICS_ENABLED" not in os.environ:
31
+ os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
32
+
33
+
34
+ def check_python_version():
35
+ is_windows = platform.system() == "Windows"
36
+ major = sys.version_info.major
37
+ minor = sys.version_info.minor
38
+ micro = sys.version_info.micro
39
+
40
+ if is_windows:
41
+ supported_minors = [10]
42
+ else:
43
+ supported_minors = [7, 8, 9, 10, 11]
44
+
45
+ if not (major == 3 and minor in supported_minors):
46
+ import modules.errors
47
+
48
+ modules.errors.print_error_explanation(
49
+ f"""
50
+ INCOMPATIBLE PYTHON VERSION
51
+
52
+ This program is tested with 3.10.6 Python, but you have {major}.{minor}.{micro}.
53
+ If you encounter an error with "RuntimeError: Couldn't install torch." message,
54
+ or any other error regarding unsuccessful package (library) installation,
55
+ please downgrade (or upgrade) to the latest version of 3.10 Python
56
+ and delete current Python and "venv" folder in WebUI's directory.
57
+
58
+ You can download 3.10 Python from here: https://www.python.org/downloads/release/python-3106/
59
+
60
+ {"Alternatively, use a binary release of WebUI: https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases" if is_windows else ""}
61
+
62
+ Use --skip-python-version-check to suppress this warning.
63
+ """
64
+ )
65
+
66
+
67
+ @lru_cache()
68
+ def commit_hash():
69
+ try:
70
+ return subprocess.check_output(
71
+ [git, "-C", script_path, "rev-parse", "HEAD"], shell=False, encoding="utf8"
72
+ ).strip()
73
+ except Exception:
74
+ return "<none>"
75
+
76
+
77
+ @lru_cache()
78
+ def git_tag():
79
+ try:
80
+ return subprocess.check_output(
81
+ [git, "-C", script_path, "describe", "--tags"], shell=False, encoding="utf8"
82
+ ).strip()
83
+ except Exception:
84
+ try:
85
+ changelog_md = os.path.join(
86
+ os.path.dirname(os.path.dirname(__file__)), "CHANGELOG.md"
87
+ )
88
+ with open(changelog_md, "r", encoding="utf-8") as file:
89
+ line = next((line.strip() for line in file if line.strip()), "<none>")
90
+ line = line.replace("## ", "")
91
+ return line
92
+ except Exception:
93
+ return "<none>"
94
+
95
+
96
+ def run(
97
+ command, desc=None, errdesc=None, custom_env=None, live: bool = default_command_live
98
+ ) -> str:
99
+ if desc is not None:
100
+ print(desc)
101
+
102
+ run_kwargs = {
103
+ "args": command,
104
+ "shell": True,
105
+ "env": os.environ if custom_env is None else custom_env,
106
+ "encoding": "utf8",
107
+ "errors": "ignore",
108
+ }
109
+
110
+ if not live:
111
+ run_kwargs["stdout"] = run_kwargs["stderr"] = subprocess.PIPE
112
+
113
+ result = subprocess.run(**run_kwargs)
114
+
115
+ if result.returncode != 0:
116
+ error_bits = [
117
+ f"{errdesc or 'Error running command'}.",
118
+ f"Command: {command}",
119
+ f"Error code: {result.returncode}",
120
+ ]
121
+ if result.stdout:
122
+ error_bits.append(f"stdout: {result.stdout}")
123
+ if result.stderr:
124
+ error_bits.append(f"stderr: {result.stderr}")
125
+ raise RuntimeError("\n".join(error_bits))
126
+
127
+ return result.stdout or ""
128
+
129
+
130
+ def is_installed(package):
131
+ try:
132
+ dist = importlib.metadata.distribution(package)
133
+ except importlib.metadata.PackageNotFoundError:
134
+ try:
135
+ spec = importlib.util.find_spec(package)
136
+ except ModuleNotFoundError:
137
+ return False
138
+
139
+ return spec is not None
140
+
141
+ return dist is not None
142
+
143
+
144
+ def repo_dir(name):
145
+ return os.path.join(script_path, dir_repos, name)
146
+
147
+
148
+ def run_pip(command, desc=None, live=default_command_live):
149
+ if args.skip_install:
150
+ return
151
+
152
+ index_url_line = f" --index-url {index_url}" if index_url != "" else ""
153
+ return run(
154
+ f'"{python}" -m pip {command} --prefer-binary{index_url_line}',
155
+ desc=f"Installing {desc}",
156
+ errdesc=f"Couldn't install {desc}",
157
+ live=live,
158
+ )
159
+
160
+
161
+ def check_run_python(code: str) -> bool:
162
+ result = subprocess.run([python, "-c", code], capture_output=True, shell=False)
163
+ return result.returncode == 0
164
+
165
+
166
+ def git_fix_workspace(dir, name):
167
+ run(
168
+ f'"{git}" -C "{dir}" fetch --refetch --no-auto-gc',
169
+ f"Fetching all contents for {name}",
170
+ f"Couldn't fetch {name}",
171
+ live=True,
172
+ )
173
+ run(
174
+ f'"{git}" -C "{dir}" gc --aggressive --prune=now',
175
+ f"Pruning {name}",
176
+ f"Couldn't prune {name}",
177
+ live=True,
178
+ )
179
+ return
180
+
181
+
182
+ def run_git(
183
+ dir,
184
+ name,
185
+ command,
186
+ desc=None,
187
+ errdesc=None,
188
+ custom_env=None,
189
+ live: bool = default_command_live,
190
+ autofix=True,
191
+ ):
192
+ try:
193
+ return run(
194
+ f'"{git}" -C "{dir}" {command}',
195
+ desc=desc,
196
+ errdesc=errdesc,
197
+ custom_env=custom_env,
198
+ live=live,
199
+ )
200
+ except RuntimeError:
201
+ if not autofix:
202
+ raise
203
+
204
+ print(f"{errdesc}, attempting autofix...")
205
+ git_fix_workspace(dir, name)
206
+
207
+ return run(
208
+ f'"{git}" -C "{dir}" {command}',
209
+ desc=desc,
210
+ errdesc=errdesc,
211
+ custom_env=custom_env,
212
+ live=live,
213
+ )
214
+
215
+
216
+ def git_clone(url, dir, name, commithash=None):
217
+ # TODO clone into temporary dir and move if successful
218
+
219
+ if os.path.exists(dir):
220
+ if commithash is None:
221
+ return
222
+
223
+ current_hash = run_git(
224
+ dir,
225
+ name,
226
+ "rev-parse HEAD",
227
+ None,
228
+ f"Couldn't determine {name}'s hash: {commithash}",
229
+ live=False,
230
+ ).strip()
231
+ if current_hash == commithash:
232
+ return
233
+
234
+ if (
235
+ run_git(
236
+ dir,
237
+ name,
238
+ "config --get remote.origin.url",
239
+ None,
240
+ f"Couldn't determine {name}'s origin URL",
241
+ live=False,
242
+ ).strip()
243
+ != url
244
+ ):
245
+ run_git(
246
+ dir,
247
+ name,
248
+ f'remote set-url origin "{url}"',
249
+ None,
250
+ f"Failed to set {name}'s origin URL",
251
+ live=False,
252
+ )
253
+
254
+ run_git(
255
+ dir,
256
+ name,
257
+ "fetch",
258
+ f"Fetching updates for {name}...",
259
+ f"Couldn't fetch {name}",
260
+ autofix=False,
261
+ )
262
+
263
+ run_git(
264
+ dir,
265
+ name,
266
+ f"reset --hard {commithash}",
267
+ f"Checking out commit for {name} with hash: {commithash}...",
268
+ f"Couldn't checkout commit {commithash} for {name}",
269
+ live=True,
270
+ )
271
+
272
+ return
273
+
274
+ try:
275
+ run(
276
+ f'"{git}" clone "{url}" "{dir}"',
277
+ f"Cloning {name} into {dir}...",
278
+ f"Couldn't clone {name}",
279
+ live=True,
280
+ )
281
+ except RuntimeError:
282
+ shutil.rmtree(dir, ignore_errors=True)
283
+ raise
284
+
285
+ if commithash is not None:
286
+ run(
287
+ f'"{git}" -C "{dir}" reset --hard {commithash}',
288
+ None,
289
+ "Couldn't checkout {name}'s hash: {commithash}",
290
+ )
291
+
292
+
293
+ def git_pull_recursive(dir):
294
+ for subdir, _, _ in os.walk(dir):
295
+ if os.path.exists(os.path.join(subdir, ".git")):
296
+ try:
297
+ output = subprocess.check_output(
298
+ [git, "-C", subdir, "pull", "--autostash"]
299
+ )
300
+ print(
301
+ f"Pulled changes for repository in '{subdir}':\n{output.decode('utf-8').strip()}\n"
302
+ )
303
+ except subprocess.CalledProcessError as e:
304
+ print(
305
+ f"Couldn't perform 'git pull' on repository in '{subdir}':\n{e.output.decode('utf-8').strip()}\n"
306
+ )
307
+
308
+
309
+ def version_check(commit):
310
+ try:
311
+ import requests
312
+
313
+ commits = requests.get(
314
+ "https://api.github.com/repos/AUTOMATIC1111/stable-diffusion-webui/branches/master"
315
+ ).json()
316
+ if commit != "<none>" and commits["commit"]["sha"] != commit:
317
+ print("--------------------------------------------------------")
318
+ print("| You are not up to date with the most recent release. |")
319
+ print("| Consider running `git pull` to update. |")
320
+ print("--------------------------------------------------------")
321
+ elif commits["commit"]["sha"] == commit:
322
+ print("You are up to date with the most recent release.")
323
+ else:
324
+ print("Not a git clone, can't perform version check.")
325
+ except Exception as e:
326
+ print("version check failed", e)
327
+
328
+
329
+ def run_extension_installer(extension_dir):
330
+ path_installer = os.path.join(extension_dir, "install.py")
331
+ if not os.path.isfile(path_installer):
332
+ return
333
+
334
+ try:
335
+ env = os.environ.copy()
336
+ env[
337
+ "PYTHONPATH"
338
+ ] = f"{os.path.abspath('.')}{os.pathsep}{env.get('PYTHONPATH', '')}"
339
+
340
+ stdout = run(
341
+ f'"{python}" "{path_installer}"',
342
+ errdesc=f"Error running install.py for extension {extension_dir}",
343
+ custom_env=env,
344
+ ).strip()
345
+ if stdout:
346
+ print(stdout)
347
+ except Exception as e:
348
+ errors.report(str(e))
349
+
350
+
351
+ def list_extensions(settings_file):
352
+ settings = {}
353
+
354
+ try:
355
+ if os.path.isfile(settings_file):
356
+ with open(settings_file, "r", encoding="utf8") as file:
357
+ settings = json.load(file)
358
+ except Exception:
359
+ errors.report("Could not load settings", exc_info=True)
360
+
361
+ disabled_extensions = set(settings.get("disabled_extensions", []))
362
+ disable_all_extensions = settings.get("disable_all_extensions", "none")
363
+
364
+ if (
365
+ disable_all_extensions != "none"
366
+ or args.disable_extra_extensions
367
+ or args.disable_all_extensions
368
+ or not os.path.isdir(extensions_dir)
369
+ ):
370
+ return []
371
+
372
+ return [x for x in os.listdir(extensions_dir) if x not in disabled_extensions]
373
+
374
+
375
+ def run_extensions_installers(settings_file):
376
+ if not os.path.isdir(extensions_dir):
377
+ return
378
+
379
+ with startup_timer.subcategory("run extensions installers"):
380
+ for dirname_extension in list_extensions(settings_file):
381
+ logging.debug(f"Installing {dirname_extension}")
382
+
383
+ path = os.path.join(extensions_dir, dirname_extension)
384
+
385
+ if os.path.isdir(path):
386
+ run_extension_installer(path)
387
+ startup_timer.record(dirname_extension)
388
+
389
+
390
+ re_requirement = re.compile(r"\s*([-_a-zA-Z0-9]+)\s*(?:==\s*([-+_.a-zA-Z0-9]+))?\s*")
391
+
392
+
393
+ def requirements_met(requirements_file):
394
+ """
395
+ Does a simple parse of a requirements.txt file to determine if all rerqirements in it
396
+ are already installed. Returns True if so, False if not installed or parsing fails.
397
+ """
398
+
399
+ import importlib.metadata
400
+ import packaging.version
401
+
402
+ with open(requirements_file, "r", encoding="utf8") as file:
403
+ for line in file:
404
+ if line.strip() == "":
405
+ continue
406
+
407
+ m = re.match(re_requirement, line)
408
+ if m is None:
409
+ return False
410
+
411
+ package = m.group(1).strip()
412
+ version_required = (m.group(2) or "").strip()
413
+
414
+ if version_required == "":
415
+ continue
416
+
417
+ try:
418
+ version_installed = importlib.metadata.version(package)
419
+ except Exception:
420
+ return False
421
+
422
+ if packaging.version.parse(version_required) != packaging.version.parse(
423
+ version_installed
424
+ ):
425
+ return False
426
+
427
+ return True
428
+
429
+
430
+ def prepare_environment():
431
+ torch_index_url = os.environ.get(
432
+ "TORCH_INDEX_URL", "https://download.pytorch.org/whl/cu118"
433
+ )
434
+ torch_command = os.environ.get(
435
+ "TORCH_COMMAND",
436
+ f"pip install torch==2.0.1 torchvision==0.15.2 --extra-index-url {torch_index_url}",
437
+ )
438
+ if args.use_ipex:
439
+ if platform.system() == "Windows":
440
+ # The "Nuullll/intel-extension-for-pytorch" wheels were built from IPEX source for Intel Arc GPU: https://github.com/intel/intel-extension-for-pytorch/tree/xpu-main
441
+ # This is NOT an Intel official release so please use it at your own risk!!
442
+ # See https://github.com/Nuullll/intel-extension-for-pytorch/releases/tag/v2.0.110%2Bxpu-master%2Bdll-bundle for details.
443
+ #
444
+ # Strengths (over official IPEX 2.0.110 windows release):
445
+ # - AOT build (for Arc GPU only) to eliminate JIT compilation overhead: https://github.com/intel/intel-extension-for-pytorch/issues/399
446
+ # - Bundles minimal oneAPI 2023.2 dependencies into the python wheels, so users don't need to install oneAPI for the whole system.
447
+ # - Provides a compatible torchvision wheel: https://github.com/intel/intel-extension-for-pytorch/issues/465
448
+ # Limitation:
449
+ # - Only works for python 3.10
450
+ url_prefix = "https://github.com/Nuullll/intel-extension-for-pytorch/releases/download/v2.0.110%2Bxpu-master%2Bdll-bundle"
451
+ torch_command = os.environ.get(
452
+ "TORCH_COMMAND",
453
+ f"pip install {url_prefix}/torch-2.0.0a0+gite9ebda2-cp310-cp310-win_amd64.whl {url_prefix}/torchvision-0.15.2a0+fa99a53-cp310-cp310-win_amd64.whl {url_prefix}/intel_extension_for_pytorch-2.0.110+gitc6ea20b-cp310-cp310-win_amd64.whl",
454
+ )
455
+ else:
456
+ # Using official IPEX release for linux since it's already an AOT build.
457
+ # However, users still have to install oneAPI toolkit and activate oneAPI environment manually.
458
+ # See https://intel.github.io/intel-extension-for-pytorch/index.html#installation for details.
459
+ torch_index_url = os.environ.get(
460
+ "TORCH_INDEX_URL",
461
+ "https://pytorch-extension.intel.com/release-whl/stable/xpu/us/",
462
+ )
463
+ torch_command = os.environ.get(
464
+ "TORCH_COMMAND",
465
+ f"pip install torch==2.0.0a0 intel-extension-for-pytorch==2.0.110+gitba7f6c1 --extra-index-url {torch_index_url}",
466
+ )
467
+ requirements_file = os.environ.get("REQS_FILE", "requirements_versions.txt")
468
+
469
+ xformers_package = os.environ.get("XFORMERS_PACKAGE", "xformers==0.0.20")
470
+ clip_package = os.environ.get(
471
+ "CLIP_PACKAGE",
472
+ "https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip",
473
+ )
474
+ openclip_package = os.environ.get(
475
+ "OPENCLIP_PACKAGE",
476
+ "https://github.com/mlfoundations/open_clip/archive/bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b.zip",
477
+ )
478
+
479
+ stable_diffusion_repo = os.environ.get(
480
+ "STABLE_DIFFUSION_REPO", "https://github.com/Stability-AI/stablediffusion.git"
481
+ )
482
+ stable_diffusion_xl_repo = os.environ.get(
483
+ "STABLE_DIFFUSION_XL_REPO",
484
+ "https://github.com/Stability-AI/generative-models.git",
485
+ )
486
+ k_diffusion_repo = os.environ.get(
487
+ "K_DIFFUSION_REPO", "https://github.com/crowsonkb/k-diffusion.git"
488
+ )
489
+ codeformer_repo = os.environ.get(
490
+ "CODEFORMER_REPO", "https://github.com/sczhou/CodeFormer.git"
491
+ )
492
+ blip_repo = os.environ.get("BLIP_REPO", "https://github.com/salesforce/BLIP.git")
493
+
494
+ stable_diffusion_commit_hash = os.environ.get(
495
+ "STABLE_DIFFUSION_COMMIT_HASH", "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf"
496
+ )
497
+ stable_diffusion_xl_commit_hash = os.environ.get(
498
+ "STABLE_DIFFUSION_XL_COMMIT_HASH", "45c443b316737a4ab6e40413d7794a7f5657c19f"
499
+ )
500
+ k_diffusion_commit_hash = os.environ.get(
501
+ "K_DIFFUSION_COMMIT_HASH", "ab527a9a6d347f364e3d185ba6d714e22d80cb3c"
502
+ )
503
+ codeformer_commit_hash = os.environ.get(
504
+ "CODEFORMER_COMMIT_HASH", "c5b4593074ba6214284d6acd5f1719b6c5d739af"
505
+ )
506
+ blip_commit_hash = os.environ.get(
507
+ "BLIP_COMMIT_HASH", "48211a1594f1321b00f14c9f7a5b4813144b2fb9"
508
+ )
509
+
510
+ try:
511
+ # the existence of this file is a signal to webui.sh/bat that webui needs to be restarted when it stops execution
512
+ os.remove(os.path.join(script_path, "tmp", "restart"))
513
+ os.environ.setdefault("SD_WEBUI_RESTARTING", "1")
514
+ except OSError:
515
+ pass
516
+
517
+ if not args.skip_python_version_check:
518
+ check_python_version()
519
+
520
+ startup_timer.record("checks")
521
+
522
+ commit = commit_hash()
523
+ tag = git_tag()
524
+ startup_timer.record("git version info")
525
+
526
+ print(f"Python {sys.version}")
527
+ print(f"Version: {tag}")
528
+ print(f"Commit hash: {commit}")
529
+
530
+ if (
531
+ args.reinstall_torch
532
+ or not is_installed("torch")
533
+ or not is_installed("torchvision")
534
+ ):
535
+ run(
536
+ f'"{python}" -m {torch_command}',
537
+ "Installing torch and torchvision",
538
+ "Couldn't install torch",
539
+ live=True,
540
+ )
541
+ startup_timer.record("install torch")
542
+
543
+ if args.use_ipex:
544
+ args.skip_torch_cuda_test = True
545
+ if not args.skip_torch_cuda_test and not check_run_python(
546
+ "import torch; assert torch.cuda.is_available()"
547
+ ):
548
+ raise RuntimeError(
549
+ "Torch is not able to use GPU; "
550
+ "add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check"
551
+ )
552
+ startup_timer.record("torch GPU test")
553
+
554
+ if not is_installed("clip"):
555
+ run_pip(f"install {clip_package}", "clip")
556
+ startup_timer.record("install clip")
557
+
558
+ if not is_installed("open_clip"):
559
+ run_pip(f"install {openclip_package}", "open_clip")
560
+ startup_timer.record("install open_clip")
561
+
562
+ if (not is_installed("xformers") or args.reinstall_xformers) and args.xformers:
563
+ run_pip(f"install -U -I --no-deps {xformers_package}", "xformers")
564
+ startup_timer.record("install xformers")
565
+
566
+ if not is_installed("ngrok") and args.ngrok:
567
+ run_pip("install ngrok", "ngrok")
568
+ startup_timer.record("install ngrok")
569
+
570
+ os.makedirs(os.path.join(script_path, dir_repos), exist_ok=True)
571
+
572
+ git_clone(
573
+ stable_diffusion_repo,
574
+ repo_dir("stable-diffusion-stability-ai"),
575
+ "Stable Diffusion",
576
+ stable_diffusion_commit_hash,
577
+ )
578
+ git_clone(
579
+ stable_diffusion_xl_repo,
580
+ repo_dir("generative-models"),
581
+ "Stable Diffusion XL",
582
+ stable_diffusion_xl_commit_hash,
583
+ )
584
+ git_clone(
585
+ k_diffusion_repo,
586
+ repo_dir("k-diffusion"),
587
+ "K-diffusion",
588
+ k_diffusion_commit_hash,
589
+ )
590
+ git_clone(
591
+ codeformer_repo, repo_dir("CodeFormer"), "CodeFormer", codeformer_commit_hash
592
+ )
593
+ git_clone(blip_repo, repo_dir("BLIP"), "BLIP", blip_commit_hash)
594
+
595
+ startup_timer.record("clone repositores")
596
+
597
+ if not is_installed("lpips"):
598
+ run_pip(
599
+ f"install -r \"{os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}\"",
600
+ "requirements for CodeFormer",
601
+ )
602
+ startup_timer.record("install CodeFormer requirements")
603
+
604
+ if not os.path.isfile(requirements_file):
605
+ requirements_file = os.path.join(script_path, requirements_file)
606
+
607
+ if not requirements_met(requirements_file):
608
+ run_pip(f'install -r "{requirements_file}"', "requirements")
609
+ startup_timer.record("install requirements")
610
+
611
+ if not args.skip_install:
612
+ run_extensions_installers(settings_file=args.ui_settings_file)
613
+
614
+ if args.update_check:
615
+ version_check(commit)
616
+ startup_timer.record("check version")
617
+
618
+ if args.update_all_extensions:
619
+ git_pull_recursive(extensions_dir)
620
+ startup_timer.record("update extensions")
621
+
622
+ if "--exit" in sys.argv:
623
+ print("Exiting because of --exit argument")
624
+ exit(0)
625
+
626
+
627
+ def configure_for_tests():
628
+ if "--api" not in sys.argv:
629
+ sys.argv.append("--api")
630
+ if "--ckpt" not in sys.argv:
631
+ sys.argv.append("--ckpt")
632
+ sys.argv.append(os.path.join(script_path, "test/test_files/empty.pt"))
633
+ if "--skip-torch-cuda-test" not in sys.argv:
634
+ sys.argv.append("--skip-torch-cuda-test")
635
+ if "--disable-nan-check" not in sys.argv:
636
+ sys.argv.append("--disable-nan-check")
637
+
638
+ os.environ["COMMANDLINE_ARGS"] = ""
639
+
640
+
641
+ def start():
642
+ print(
643
+ f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}"
644
+ )
645
+ import webui
646
+
647
+ if "--nowebui" in sys.argv:
648
+ webui.api_only()
649
+ else:
650
+ webui.webui()
651
+
652
+
653
+ def dump_sysinfo():
654
+ from modules import sysinfo
655
+ import datetime
656
+
657
+ text = sysinfo.get()
658
+ filename = f"sysinfo-{datetime.datetime.utcnow().strftime('%Y-%m-%d-%H-%M')}.json"
659
+
660
+ with open(filename, "w", encoding="utf8") as file:
661
+ file.write(text)
662
+
663
+ return filename
direct/v1.7.0/lib.zst ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6b77a7be1c45a9bb347c9de3a6fc8f15f1090257ff47b5ccea1b2bffc04fe518
3
+ size 274973117
direct/v1.7.0/repositories.tar ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a8564dd33ff15e041f0af893f9626966ae00430e41459ab0ca1745479fd939c5
3
+ size 426158080