From d21b368109bbcbaaab3c2d1a1c799306e266f567 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Wed, 23 Nov 2022 22:15:21 -0500 Subject: [PATCH 1/6] Update scripts/configure_invokeai.py prevent crash if output exists Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com> --- scripts/configure_invokeai.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/configure_invokeai.py b/scripts/configure_invokeai.py index 46f652b15d2..930650bcce0 100755 --- a/scripts/configure_invokeai.py +++ b/scripts/configure_invokeai.py @@ -598,7 +598,7 @@ def initialize_rootdir(root:str,yes_to_all:bool=False): dest = os.path.join(root,src) if not os.path.samefile(src,dest): shutil.copytree(src,dest,dirs_exist_ok=True) - os.makedirs(outputs) + os.makedirs(outputs, exist_ok=True) init_file = os.path.expanduser(Globals.initfile) if not os.path.exists(init_file): From 854c0b5db056fbb1e6b9bf76617be66c02d5dd13 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Sat, 26 Nov 2022 13:38:40 +0000 Subject: [PATCH 2/6] implement changes requested by reviews --- installer/install.bat | 1 + installer/install.sh | 1 + scripts/configure_invokeai.py | 21 ++++++++++----------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/installer/install.bat b/installer/install.bat index 2ce9837358a..b414494e5f3 100644 --- a/installer/install.bat +++ b/installer/install.bat @@ -142,6 +142,7 @@ rd /s /q installer installer_files call .venv\Scripts\python scripts\configure_invokeai.py set err_msg=----- model download clone failed ----- if %errorlevel% neq 0 goto err_exit +deactivate echo ***** Finished downloading models ***** diff --git a/installer/install.sh b/installer/install.sh index 1af4bf7aefe..e267c442b56 100644 --- a/installer/install.sh +++ b/installer/install.sh @@ -209,6 +209,7 @@ rm -rf installer/ installer_files/ .venv/bin/python3 scripts/configure_invokeai.py _err_msg="\n----- model download clone failed -----\n" _err_exit $? _err_msg +deactivate echo -e "\n***** Finished downloading models *****\n" diff --git a/scripts/configure_invokeai.py b/scripts/configure_invokeai.py index 930650bcce0..caa7c7cc20c 100755 --- a/scripts/configure_invokeai.py +++ b/scripts/configure_invokeai.py @@ -578,7 +578,7 @@ def select_outputs(root:str,yes_to_all:bool=False): completer.set_default_dir(os.path.expanduser('~')) completer.complete_extensions(()) completer.set_line(default) - return input('Select the default directory for image outputs [{default}]: ') + return input(f'Select the default directory for image outputs [{default}]: ') #------------------------------------- def initialize_rootdir(root:str,yes_to_all:bool=False): @@ -587,14 +587,15 @@ def initialize_rootdir(root:str,yes_to_all:bool=False): print(f'** INITIALIZING INVOKEAI RUNTIME DIRECTORY **') root = root or select_root(yes_to_all) outputs = select_outputs(root,yes_to_all) - Globals.root = root + Globals.root = os.path.abspath(root) + outputs = outputs if os.path.isabs(outputs) else os.path.abspath(os.path.join(Globals.root,outputs)) print(f'InvokeAI models and configuration files will be placed into {root} and image outputs will be placed into {outputs}.') print(f'\nYou may change these values at any time by editing the --root and --output_dir options in "{Globals.initfile}",') print(f'You may also change the runtime directory by setting the environment variable INVOKEAI_ROOT.\n') - for name in ('models','configs','scripts','frontend/dist'): + for name in ['models','configs']: os.makedirs(os.path.join(root,name), exist_ok=True) - for src in ('configs','scripts','frontend/dist'): + for src in (['configs']): dest = os.path.join(root,src) if not os.path.samefile(src,dest): shutil.copytree(src,dest,dirs_exist_ok=True) @@ -610,7 +611,7 @@ def initialize_rootdir(root:str,yes_to_all:bool=False): # or renaming it and then running configure_invokeai.py again. # The --root option below points to the folder in which InvokeAI stores its models, configs and outputs. ---root="{root}" +--root="{Globals.root}" # the --outdir option controls the default location of image files. --outdir="{outputs}" @@ -673,12 +674,9 @@ def main(): try: introduction() - # We check for two files to see if the runtime directory is correctly initialized. - # 1. a key stable diffusion config file - # 2. the web front end static files + # We check for to see if the runtime directory is correctly initialized. if Globals.root == '' \ - or not os.path.exists(os.path.join(Globals.root,'configs/stable-diffusion/v1-inference.yaml')) \ - or not os.path.exists(os.path.join(Globals.root,'frontend/dist')): + or not os.path.exists(os.path.join(Globals.root,'configs/stable-diffusion/v1-inference.yaml')): initialize_rootdir(Globals.root,opt.yes_to_all) print(f'(Initializing with runtime root {Globals.root})\n') @@ -698,7 +696,8 @@ def main(): except KeyboardInterrupt: print('\nGoodbye! Come back soon.') except Exception as e: - print(f'\nA problem occurred during download.\nThe error was: "{str(e)}"') + print(f'\nA problem occurred during initialization.\nThe error was: "{str(e)}"') + print(traceback.format_exc()) #------------------------------------- if __name__ == '__main__': From 785d57ba9428e4e5260fb0164b058dc9bc6181fd Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Sat, 26 Nov 2022 23:04:11 +0000 Subject: [PATCH 3/6] default to correct root and output directory on Windows systems - Previously the script was relying on the readline buffer editing feature to set up the correct default. But this feature doesn't exist on windows. - This commit detects when user typed return with an empty directory value and replaces with the default directory. --- scripts/configure_invokeai.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/scripts/configure_invokeai.py b/scripts/configure_invokeai.py index 6e9ffd7ecb4..a11e3cee51f 100755 --- a/scripts/configure_invokeai.py +++ b/scripts/configure_invokeai.py @@ -561,14 +561,14 @@ def get_root(root:str=None)->str: return root #------------------------------------- -def select_root(yes_to_all:bool=False): - default = os.path.expanduser('~/invokeai') +def select_root(root:str, yes_to_all:bool=False): + default = root or os.path.expanduser('~/invokeai') if (yes_to_all): return default completer.set_default_dir(default) completer.complete_extensions(()) completer.set_line(default) - return input(f"Select a directory in which to install InvokeAI's models and configuration files [{default}]: ") + return input(f"Select a directory in which to install InvokeAI's models and configuration files [{default}]: ") or default #------------------------------------- def select_outputs(root:str,yes_to_all:bool=False): @@ -578,21 +578,28 @@ def select_outputs(root:str,yes_to_all:bool=False): completer.set_default_dir(os.path.expanduser('~')) completer.complete_extensions(()) completer.set_line(default) - return input(f'Select the default directory for image outputs [{default}]: ') + return input(f'Select the default directory for image outputs [{default}]: ') or default #------------------------------------- def initialize_rootdir(root:str,yes_to_all:bool=False): assert os.path.exists('./configs'),'Run this script from within the top level of the InvokeAI source code directory, "InvokeAI"' print(f'** INITIALIZING INVOKEAI RUNTIME DIRECTORY **') - root = root or select_root(yes_to_all) - outputs = select_outputs(root,yes_to_all) - Globals.root = os.path.abspath(root) - outputs = outputs if os.path.isabs(outputs) else os.path.abspath(os.path.join(Globals.root,outputs)) + root_selected = False + while not root_selected: + root = select_root(root,yes_to_all) + outputs = select_outputs(root,yes_to_all) + Globals.root = os.path.abspath(root) + outputs = outputs if os.path.isabs(outputs) else os.path.abspath(os.path.join(Globals.root,outputs)) + + print(f'\nInvokeAI models and configuration files will be placed into "{root}" and image outputs will be placed into "{outputs}".') + print(f'\nYou may change these values at any time by editing the --root and --output_dir options in "{Globals.initfile}",') + print(f'You may also change the runtime directory by setting the environment variable INVOKEAI_ROOT.\n') + if not yes_to_all: + root_selected = yes_or_no('accept these locations?') + else: + root_selected = True - print(f'InvokeAI models and configuration files will be placed into {root} and image outputs will be placed into {outputs}.') - print(f'\nYou may change these values at any time by editing the --root and --output_dir options in "{Globals.initfile}",') - print(f'You may also change the runtime directory by setting the environment variable INVOKEAI_ROOT.\n') for name in ['models','configs']: os.makedirs(os.path.join(root,name), exist_ok=True) for src in (['configs']): @@ -679,8 +686,6 @@ def main(): or not os.path.exists(os.path.join(Globals.root,'configs/stable-diffusion/v1-inference.yaml')): initialize_rootdir(Globals.root,opt.yes_to_all) - print(f'(Initializing with runtime root {Globals.root})\n') - if opt.interactive: print('** DOWNLOADING DIFFUSION WEIGHTS **') download_weights(opt) From 3579d906c3a1d31dab1c904912065af6406de4a9 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Sat, 26 Nov 2022 23:10:40 +0000 Subject: [PATCH 4/6] improved readability of directory choices --- scripts/configure_invokeai.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 scripts/configure_invokeai.py diff --git a/scripts/configure_invokeai.py b/scripts/configure_invokeai.py old mode 100644 new mode 100755 index a11e3cee51f..d1568ed622f --- a/scripts/configure_invokeai.py +++ b/scripts/configure_invokeai.py @@ -593,12 +593,13 @@ def initialize_rootdir(root:str,yes_to_all:bool=False): outputs = outputs if os.path.isabs(outputs) else os.path.abspath(os.path.join(Globals.root,outputs)) print(f'\nInvokeAI models and configuration files will be placed into "{root}" and image outputs will be placed into "{outputs}".') - print(f'\nYou may change these values at any time by editing the --root and --output_dir options in "{Globals.initfile}",') - print(f'You may also change the runtime directory by setting the environment variable INVOKEAI_ROOT.\n') if not yes_to_all: - root_selected = yes_or_no('accept these locations?') + root_selected = yes_or_no('Accept these locations?') else: root_selected = True + + print(f'\nYou may change the chosen directories at any time by editing the --root and --output_dir options in "{Globals.initfile}",') + print(f'You may also change the runtime directory by setting the environment variable INVOKEAI_ROOT.\n') for name in ['models','configs']: os.makedirs(os.path.join(root,name), exist_ok=True) From f04aeb4e8884c1dedd5c8b6717f6fedde82b435c Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Sun, 27 Nov 2022 09:45:17 -0500 Subject: [PATCH 5/6] Update scripts/configure_invokeai.py Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com> --- scripts/configure_invokeai.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/configure_invokeai.py b/scripts/configure_invokeai.py index d1568ed622f..38b08ac9543 100755 --- a/scripts/configure_invokeai.py +++ b/scripts/configure_invokeai.py @@ -598,7 +598,7 @@ def initialize_rootdir(root:str,yes_to_all:bool=False): else: root_selected = True - print(f'\nYou may change the chosen directories at any time by editing the --root and --output_dir options in "{Globals.initfile}",') + print(f'\nYou may change the chosen directories at any time by editing the --root and --outdir options in "{Globals.initfile}",') print(f'You may also change the runtime directory by setting the environment variable INVOKEAI_ROOT.\n') for name in ['models','configs']: From 26b2dd3ddd47ce4ce9446086a307380efc5002c1 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Sun, 27 Nov 2022 17:56:19 +0000 Subject: [PATCH 6/6] better error reporting at startup - If user tries to run the script outside of the repo or runtime directory, a more informative message will appear explaining the problem. --- scripts/configure_invokeai.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/configure_invokeai.py b/scripts/configure_invokeai.py index 38b08ac9543..4e55ed2ffdb 100755 --- a/scripts/configure_invokeai.py +++ b/scripts/configure_invokeai.py @@ -39,6 +39,8 @@ Default_config_file = './configs/models.yaml' SD_Configs = './configs/stable-diffusion' +assert os.path.exists(Dataset_path),"The configs directory cannot be found. Please run this script from within the InvokeAI distribution directory, or from within the invokeai runtime directory." + Datasets = OmegaConf.load(Dataset_path) completer = generic_completer(['yes','no'])