Fix #20 base path can now be set before folder paths are initialized, although all of this really has to be reworked

This commit is contained in:
doctorpangloss 2024-08-29 18:02:36 -07:00
parent fd503d8a96
commit 1bc96a7a1b
5 changed files with 92 additions and 28 deletions

View File

@ -2,31 +2,25 @@ from __future__ import annotations
import logging
import os
import sys
import time
from typing import Optional, List
from typing import Optional, List, Final
from ..cli_args import args
from .folder_paths_pre import get_base_path
from ..component_model.files import get_package_as_path
from ..component_model.folder_path_types import FolderPathsTuple, FolderNames, SaveImagePathResponse
from ..component_model.folder_path_types import supported_pt_extensions as _supported_pt_extensions
from ..component_model.module_property import module_property
supported_pt_extensions = _supported_pt_extensions
supported_pt_extensions: Final[frozenset[str]] = _supported_pt_extensions
# todo: this should be initialized elsewhere
if 'main.py' in sys.argv:
base_path = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../..")) # pylint: disable=used-before-assignment
elif args.cwd is not None:
if not os.path.exists(args.cwd):
try:
os.makedirs(args.cwd, exist_ok=True)
except:
logging.error("Failed to create custom working directory")
# wrap the path to prevent slashedness from glitching out common path checks
base_path = os.path.realpath(args.cwd)
else:
base_path = os.getcwd()
models_dir = os.path.join(base_path, "models")
# todo: this needs to be wrapped in a context and configurable
@module_property
def _base_path():
return get_base_path()
models_dir = os.path.join(get_base_path(), "models")
folder_names_and_paths = FolderNames(models_dir)
folder_names_and_paths["checkpoints"] = FolderPathsTuple("checkpoints", [os.path.join(models_dir, "checkpoints")], set(supported_pt_extensions))
folder_names_and_paths["configs"] = FolderPathsTuple("configs", [os.path.join(models_dir, "configs"), get_package_as_path("comfy.configs")], {".yaml"})
@ -42,17 +36,17 @@ folder_names_and_paths["vae_approx"] = FolderPathsTuple("vae_approx", [os.path.j
folder_names_and_paths["controlnet"] = FolderPathsTuple("controlnet", [os.path.join(models_dir, "controlnet"), os.path.join(models_dir, "t2i_adapter")], set(supported_pt_extensions))
folder_names_and_paths["gligen"] = FolderPathsTuple("gligen", [os.path.join(models_dir, "gligen")], set(supported_pt_extensions))
folder_names_and_paths["upscale_models"] = FolderPathsTuple("upscale_models", [os.path.join(models_dir, "upscale_models")], set(supported_pt_extensions))
folder_names_and_paths["custom_nodes"] = FolderPathsTuple("custom_nodes", [os.path.join(base_path, "custom_nodes")], set())
folder_names_and_paths["custom_nodes"] = FolderPathsTuple("custom_nodes", [os.path.join(get_base_path(), "custom_nodes")], set())
folder_names_and_paths["hypernetworks"] = FolderPathsTuple("hypernetworks", [os.path.join(models_dir, "hypernetworks")], set(supported_pt_extensions))
folder_names_and_paths["photomaker"] = FolderPathsTuple("photomaker", [os.path.join(models_dir, "photomaker")], set(supported_pt_extensions))
folder_names_and_paths["classifiers"] = FolderPathsTuple("classifiers", [os.path.join(models_dir, "classifiers")], {""})
folder_names_and_paths["huggingface"] = FolderPathsTuple("huggingface", [os.path.join(models_dir, "huggingface")], {""})
folder_names_and_paths["huggingface_cache"] = FolderPathsTuple("huggingface_cache", [os.path.join(models_dir, "huggingface_cache")], {""})
output_directory = os.path.join(base_path, "output")
temp_directory = os.path.join(base_path, "temp")
input_directory = os.path.join(base_path, "input")
user_directory = os.path.join(base_path, "user")
output_directory = os.path.join(get_base_path(), "output")
temp_directory = os.path.join(get_base_path(), "temp")
input_directory = os.path.join(get_base_path(), "input")
user_directory = os.path.join(get_base_path(), "user")
_filename_list_cache = {}

View File

@ -0,0 +1,31 @@
import logging
import os
from ..cli_args import args
_base_path = None
# todo: this should be initialized elsewhere in a context
def get_base_path() -> str:
global _base_path
if _base_path is None:
if args.cwd is not None:
if not os.path.exists(args.cwd):
try:
os.makedirs(args.cwd, exist_ok=True)
except:
logging.error("Failed to create custom working directory")
# wrap the path to prevent slashedness from glitching out common path checks
_base_path = os.path.realpath(args.cwd)
else:
_base_path = os.getcwd()
return _base_path
def set_base_path(value: str):
global _base_path
_base_path = value
__all__ = ["get_base_path", "set_base_path"]

View File

@ -6,6 +6,8 @@ import os
import shutil
import threading
import time
from pathlib import Path
from typing import Optional
from .extra_model_paths import load_extra_path_config
# main_pre must be the earliest import since it suppresses some spurious warnings
@ -107,7 +109,16 @@ def cuda_malloc_warning():
"\nWARNING: this card most likely does not support cuda-malloc, if you get \"CUDA error\" please run ComfyUI with: --disable-cuda-malloc\n")
async def main():
async def main(from_script_dir: Optional[Path] = None):
"""
Runs ComfyUI's frontend and backend like upstream.
:param from_script_dir: when set to a path, assumes that you are running ComfyUI's legacy main.py entrypoint at the root of the git repository located at the path
"""
if not from_script_dir:
os_getcwd = os.getcwd()
else:
os_getcwd = str(from_script_dir)
if args.temp_directory:
temp_dir = os.path.join(os.path.abspath(args.temp_directory), "temp")
logging.debug(f"Setting temp directory to: {temp_dir}")
@ -116,7 +127,7 @@ async def main():
# configure extra model paths earlier
try:
extra_model_paths_config_path = os.path.join(os.getcwd(), "extra_model_paths.yaml")
extra_model_paths_config_path = os.path.join(os_getcwd, "extra_model_paths.yaml")
if os.path.isfile(extra_model_paths_config_path):
load_extra_path_config(extra_model_paths_config_path)
except NameError:

View File

@ -0,0 +1,22 @@
import sys
def module_property(func):
"""Decorator to turn module functions into properties.
Function names must be prefixed with an underscore."""
module = sys.modules[func.__module__]
def base_getattr(name):
raise AttributeError(
f"module '{module.__name__}' has no attribute '{name}'")
old_getattr = getattr(module, '__getattr__', base_getattr)
def new_getattr(name):
if f'_{name}' == func.__name__:
return func()
else:
return old_getattr(name)
module.__getattr__ = new_getattr
return func

12
main.py
View File

@ -1,8 +1,14 @@
import asyncio
import warnings
from comfy.cmd.main import main
from pathlib import Path
if __name__ == "__main__":
from comfy.cmd.folder_paths_pre import set_base_path
warnings.warn("main.py is deprecated. Start comfyui by installing the package through the instructions in the README, not by cloning the repository.", DeprecationWarning)
asyncio.run(main())
this_file_parent_dir = Path(__file__).parent
set_base_path(str(this_file_parent_dir))
from comfy.cmd.main import main
asyncio.run(main(from_script_dir=this_file_parent_dir))