2023-09-13 11:38:20 -04:00
import comfy . options
comfy . options . enable_args_parsing ( )
2023-07-11 15:33:21 +09:00
import os
import importlib . util
2026-03-10 11:49:31 +09:00
import shutil
2026-03-08 13:25:30 -07:00
import importlib . metadata
2023-07-11 15:33:21 +09:00
import folder_paths
2023-07-13 13:01:45 -04:00
import time
2026-01-31 22:01:11 -08:00
from comfy . cli_args import args , enables_dynamic_vram
2024-08-30 12:46:37 -04:00
from app . logger import setup_logger
2026-04-21 19:59:31 -07:00
setup_logger ( log_level = args . verbose , use_stdout = args . log_stdout )
2026-03-24 20:48:55 -07:00
from app . assets . seeder import asset_seeder
from app . assets . services import register_output_files
2024-12-14 08:21:32 +09:00
import itertools
import utils . extra_config
2026-03-07 17:37:25 -08:00
from utils . mime_types import init_mime_types
2026-03-10 09:05:31 -07:00
import faulthandler
2024-12-14 08:21:32 +09:00
import logging
2025-04-12 18:58:20 -04:00
import sys
2025-07-10 11:46:19 -07:00
from comfy_execution . progress import get_progress_state
from comfy_execution . utils import get_executing_context
from comfy_api import feature_flags
2026-03-07 17:37:25 -08:00
from app . database . db import init_db , dependencies_available
2024-08-30 12:46:37 -04:00
2024-12-07 14:51:20 -05:00
if __name__ == " __main__ " :
2025-05-02 05:28:27 -04:00
#NOTE: These do not do anything on core ComfyUI, they are for custom nodes.
2024-12-07 14:51:20 -05:00
os . environ [ ' HF_HUB_DISABLE_TELEMETRY ' ] = ' 1 '
os . environ [ ' DO_NOT_TRACK ' ] = ' 1 '
2026-03-10 09:05:31 -07:00
faulthandler . enable ( file = sys . stderr , all_threads = False )
2026-03-03 08:51:15 -08:00
import comfy_aimdo . control
if enables_dynamic_vram ( ) :
comfy_aimdo . control . init ( )
2025-12-17 16:43:18 -08:00
if os . name == " nt " :
os . environ [ ' MIMALLOC_PURGE_DELAY ' ] = ' 0 '
if __name__ == " __main__ " :
os . environ [ ' TORCH_ROCM_AOTRITON_ENABLE_EXPERIMENTAL ' ] = ' 1 '
if args . default_device is not None :
default_dev = args . default_device
devices = list ( range ( 32 ) )
devices . remove ( default_dev )
devices . insert ( 0 , default_dev )
devices = ' , ' . join ( map ( str , devices ) )
os . environ [ ' CUDA_VISIBLE_DEVICES ' ] = str ( devices )
os . environ [ ' HIP_VISIBLE_DEVICES ' ] = str ( devices )
if args . cuda_device is not None :
os . environ [ ' CUDA_VISIBLE_DEVICES ' ] = str ( args . cuda_device )
os . environ [ ' HIP_VISIBLE_DEVICES ' ] = str ( args . cuda_device )
os . environ [ " ASCEND_RT_VISIBLE_DEVICES " ] = str ( args . cuda_device )
logging . info ( " Set cuda device to: {} " . format ( args . cuda_device ) )
if args . oneapi_device_selector is not None :
os . environ [ ' ONEAPI_DEVICE_SELECTOR ' ] = args . oneapi_device_selector
logging . info ( " Set oneapi device selector to: {} " . format ( args . oneapi_device_selector ) )
if args . deterministic :
if ' CUBLAS_WORKSPACE_CONFIG ' not in os . environ :
os . environ [ ' CUBLAS_WORKSPACE_CONFIG ' ] = " :4096:8 "
import cuda_malloc
if " rocm " in cuda_malloc . get_torch_version_noimport ( ) :
os . environ [ ' OCL_SET_SVM_SIZE ' ] = ' 262144 ' # set at the request of AMD
2025-12-02 12:32:52 +09:00
def handle_comfyui_manager_unavailable ( ) :
2026-03-10 11:49:31 +09:00
manager_req_path = os . path . join ( os . path . dirname ( os . path . abspath ( folder_paths . __file__ ) ) , " manager_requirements.txt " )
uv_available = shutil . which ( " uv " ) is not None
pip_cmd = f " { sys . executable } -m pip install -r { manager_req_path } "
msg = f " \n \n To use the `--enable-manager` feature, the `comfyui-manager` package must be installed first. \n command: \n \t { pip_cmd } "
if uv_available :
msg + = f " \n or using uv: \n \t uv pip install -r { manager_req_path } "
msg + = " \n "
logging . warning ( msg )
2025-12-02 12:32:52 +09:00
args . enable_manager = False
if args . enable_manager :
if importlib . util . find_spec ( " comfyui_manager " ) :
import comfyui_manager
if not comfyui_manager . __file__ or not comfyui_manager . __file__ . endswith ( ' __init__.py ' ) :
handle_comfyui_manager_unavailable ( )
else :
handle_comfyui_manager_unavailable ( )
2024-12-14 08:21:32 +09:00
def apply_custom_paths ( ) :
# extra model paths
extra_model_paths_config_path = os . path . join ( os . path . dirname ( os . path . realpath ( __file__ ) ) , " extra_model_paths.yaml " )
if os . path . isfile ( extra_model_paths_config_path ) :
utils . extra_config . load_extra_path_config ( extra_model_paths_config_path )
if args . extra_model_paths_config :
for config_path in itertools . chain ( * args . extra_model_paths_config ) :
utils . extra_config . load_extra_path_config ( config_path )
# --output-directory, --input-directory, --user-directory
if args . output_directory :
output_dir = os . path . abspath ( args . output_directory )
logging . info ( f " Setting output directory to: { output_dir } " )
folder_paths . set_output_directory ( output_dir )
# These are the default folders that checkpoints, clip and vae models will be saved to when using CheckpointSave, etc.. nodes
folder_paths . add_model_folder_path ( " checkpoints " , os . path . join ( folder_paths . get_output_directory ( ) , " checkpoints " ) )
folder_paths . add_model_folder_path ( " clip " , os . path . join ( folder_paths . get_output_directory ( ) , " clip " ) )
folder_paths . add_model_folder_path ( " vae " , os . path . join ( folder_paths . get_output_directory ( ) , " vae " ) )
folder_paths . add_model_folder_path ( " diffusion_models " ,
os . path . join ( folder_paths . get_output_directory ( ) , " diffusion_models " ) )
folder_paths . add_model_folder_path ( " loras " , os . path . join ( folder_paths . get_output_directory ( ) , " loras " ) )
if args . input_directory :
input_dir = os . path . abspath ( args . input_directory )
logging . info ( f " Setting input directory to: { input_dir } " )
folder_paths . set_input_directory ( input_dir )
if args . user_directory :
user_dir = os . path . abspath ( args . user_directory )
logging . info ( f " Setting user directory to: { user_dir } " )
folder_paths . set_user_directory ( user_dir )
2023-07-11 15:33:21 +09:00
def execute_prestartup_script ( ) :
2025-06-28 12:53:40 -07:00
if args . disable_all_custom_nodes and len ( args . whitelist_custom_nodes ) == 0 :
return
2023-07-11 15:33:21 +09:00
def execute_script ( script_path ) :
2023-07-13 13:01:45 -04:00
module_name = os . path . splitext ( script_path ) [ 0 ]
try :
spec = importlib . util . spec_from_file_location ( module_name , script_path )
module = importlib . util . module_from_spec ( spec )
spec . loader . exec_module ( module )
return True
except Exception as e :
2024-12-20 13:24:55 -08:00
logging . error ( f " Failed to execute startup-script: { script_path } / { e } " )
2023-07-13 13:01:45 -04:00
return False
2023-07-11 15:33:21 +09:00
node_paths = folder_paths . get_folder_paths ( " custom_nodes " )
for custom_node_path in node_paths :
possible_modules = os . listdir ( custom_node_path )
2023-07-13 13:01:45 -04:00
node_prestartup_times = [ ]
2023-07-11 15:33:21 +09:00
for possible_module in possible_modules :
module_path = os . path . join ( custom_node_path , possible_module )
2025-12-02 12:32:52 +09:00
if args . enable_manager :
if comfyui_manager . should_be_disabled ( module_path ) :
continue
2023-07-11 15:33:21 +09:00
if os . path . isfile ( module_path ) or module_path . endswith ( " .disabled " ) or module_path == " __pycache__ " :
continue
script_path = os . path . join ( module_path , " prestartup_script.py " )
2023-07-13 13:01:45 -04:00
if os . path . exists ( script_path ) :
2025-06-29 03:24:02 +08:00
if args . disable_all_custom_nodes and possible_module not in args . whitelist_custom_nodes :
logging . info ( f " Prestartup Skipping { possible_module } due to disable_all_custom_nodes and whitelist_custom_nodes " )
continue
2023-07-13 13:01:45 -04:00
time_before = time . perf_counter ( )
success = execute_script ( script_path )
node_prestartup_times . append ( ( time . perf_counter ( ) - time_before , module_path , success ) )
if len ( node_prestartup_times ) > 0 :
2024-12-20 13:24:55 -08:00
logging . info ( " \n Prestartup times for custom nodes: " )
2023-07-13 13:01:45 -04:00
for n in sorted ( node_prestartup_times ) :
if n [ 2 ] :
import_message = " "
else :
import_message = " (PRESTARTUP FAILED) "
2024-12-20 13:24:55 -08:00
logging . info ( " {:6.1f} seconds {} : {} " . format ( n [ 0 ] , import_message , n [ 1 ] ) )
logging . info ( " " )
2023-07-11 15:33:21 +09:00
2024-12-14 08:21:32 +09:00
apply_custom_paths ( )
2026-03-07 17:37:25 -08:00
init_mime_types ( )
2025-12-02 12:32:52 +09:00
if args . enable_manager :
comfyui_manager . prestartup ( )
2023-07-11 15:33:21 +09:00
execute_prestartup_script ( )
# Main code
2023-04-05 20:32:59 -04:00
import asyncio
2023-01-03 01:53:32 -05:00
import threading
2023-06-13 13:36:47 -04:00
import gc
2023-04-06 19:06:39 -04:00
2025-07-09 22:03:27 -07:00
if ' torch ' in sys . modules :
logging . warning ( " WARNING: Potential Error in code: Torch already imported, torch should never be imported before this point. " )
2026-01-31 22:01:11 -08:00
2023-07-17 11:00:14 -04:00
import comfy . utils
2023-03-29 23:28:21 -04:00
2023-03-13 11:36:48 -04:00
import execution
2023-04-05 20:32:59 -04:00
import server
2025-07-10 11:46:19 -07:00
from protocol import BinaryEventTypes
2024-07-04 21:43:23 -04:00
import nodes
2023-06-13 13:36:47 -04:00
import comfy . model_management
2025-01-25 15:03:57 -05:00
import comfyui_version
2025-03-12 07:13:40 -04:00
import app . logger
2025-04-26 17:52:56 -07:00
import hook_breaker_ac10a0
2023-03-13 11:36:48 -04:00
2026-01-31 22:01:11 -08:00
import comfy . memory_management
import comfy . model_patcher
2026-03-16 13:50:13 -07:00
if args . enable_dynamic_vram or ( enables_dynamic_vram ( ) and comfy . model_management . is_nvidia ( ) and not comfy . model_management . is_wsl ( ) ) :
if ( not args . enable_dynamic_vram ) and ( comfy . model_management . torch_version_numeric < ( 2 , 8 ) ) :
2026-02-03 18:39:19 -08:00
logging . warning ( " Unsupported Pytorch detected. DynamicVRAM support requires Pytorch version 2.8 or later. Falling back to legacy ModelPatcher. VRAM estimates may be unreliable especially on Windows " )
elif comfy_aimdo . control . init_device ( comfy . model_management . get_torch_device ( ) . index ) :
2026-01-31 22:01:11 -08:00
if args . verbose == ' DEBUG ' :
comfy_aimdo . control . set_log_debug ( )
elif args . verbose == ' CRITICAL ' :
comfy_aimdo . control . set_log_critical ( )
elif args . verbose == ' ERROR ' :
comfy_aimdo . control . set_log_error ( )
elif args . verbose == ' WARNING ' :
comfy_aimdo . control . set_log_warning ( )
else : #INFO
comfy_aimdo . control . set_log_info ( )
comfy . model_patcher . CoreModelPatcher = comfy . model_patcher . ModelPatcherDynamic
2026-02-21 10:52:57 -08:00
comfy . memory_management . aimdo_enabled = True
2026-01-31 22:01:11 -08:00
logging . info ( " DynamicVRAM support detected and enabled " )
else :
2026-02-03 18:39:19 -08:00
logging . warning ( " No working comfy-aimdo install detected. DynamicVRAM support disabled. Falling back to legacy ModelPatcher. VRAM estimates may be unreliable especially on Windows " )
2026-01-31 22:01:11 -08:00
2023-08-13 12:37:53 -04:00
def cuda_malloc_warning ( ) :
device = comfy . model_management . get_torch_device ( )
device_name = comfy . model_management . get_torch_device_name ( device )
cuda_malloc_warning = False
if " cudaMallocAsync " in device_name :
for b in cuda_malloc . blacklist :
if b in device_name :
cuda_malloc_warning = True
if cuda_malloc_warning :
2024-03-11 16:24:47 -04:00
logging . warning ( " \n WARNING: this card most likely does not support cuda-malloc, if you get \" CUDA error \" please run ComfyUI with: --disable-cuda-malloc \n " )
2023-08-13 12:37:53 -04:00
2024-12-24 14:38:52 +03:00
2026-03-24 20:48:55 -07:00
def _collect_output_absolute_paths ( history_result : dict ) - > list [ str ] :
""" Extract absolute file paths for output items from a history result. """
paths : list [ str ] = [ ]
seen : set [ str ] = set ( )
for node_output in history_result . get ( " outputs " , { } ) . values ( ) :
for items in node_output . values ( ) :
if not isinstance ( items , list ) :
continue
for item in items :
if not isinstance ( item , dict ) :
continue
item_type = item . get ( " type " )
if item_type not in ( " output " , " temp " ) :
continue
base_dir = folder_paths . get_directory_by_type ( item_type )
if base_dir is None :
continue
base_dir = os . path . abspath ( base_dir )
filename = item . get ( " filename " )
if not filename :
continue
abs_path = os . path . abspath (
os . path . join ( base_dir , item . get ( " subfolder " , " " ) , filename )
)
if not abs_path . startswith ( base_dir + os . sep ) and abs_path != base_dir :
continue
if abs_path not in seen :
seen . add ( abs_path )
paths . append ( abs_path )
return paths
2024-12-24 14:38:52 +03:00
def prompt_worker ( q , server_instance ) :
2024-12-12 15:48:21 -08:00
current_time : float = 0.0
2026-03-27 18:34:16 -07:00
cache_ram = args . cache_ram
if cache_ram < 0 :
cache_ram = min ( 32.0 , max ( 4.0 , comfy . model_management . total_ram * 0.25 / 1024.0 ) )
2025-04-11 07:16:52 -04:00
cache_type = execution . CacheType . CLASSIC
if args . cache_lru > 0 :
cache_type = execution . CacheType . LRU
2026-03-27 18:34:16 -07:00
elif cache_ram > 0 :
2025-10-31 07:39:02 +10:00
cache_type = execution . CacheType . RAM_PRESSURE
2025-04-11 07:16:52 -04:00
elif args . cache_none :
2025-10-23 05:49:05 +10:00
cache_type = execution . CacheType . NONE
2025-04-11 07:16:52 -04:00
2026-03-27 18:34:16 -07:00
e = execution . PromptExecutor ( server_instance , cache_type = cache_type , cache_args = { " lru " : args . cache_lru , " ram " : cache_ram } )
2023-11-28 14:20:56 -05:00
last_gc_collect = 0
2023-11-30 15:22:32 -05:00
need_gc = False
gc_collect_interval = 10.0
2023-01-03 01:53:32 -05:00
while True :
2024-01-04 14:28:11 -05:00
timeout = 1000.0
2023-11-30 15:22:32 -05:00
if need_gc :
timeout = max ( gc_collect_interval - ( current_time - last_gc_collect ) , 0.0 )
queue_item = q . get ( timeout = timeout )
if queue_item is not None :
item , item_id = queue_item
execution_start_time = time . perf_counter ( )
prompt_id = item [ 1 ]
2024-12-24 14:38:52 +03:00
server_instance . last_prompt_id = prompt_id
2024-01-01 14:27:56 -05:00
2025-10-28 00:23:52 -07:00
sensitive = item [ 5 ]
extra_data = item [ 3 ] . copy ( )
for k in sensitive :
extra_data [ k ] = sensitive [ k ]
2026-03-07 17:37:25 -08:00
asset_seeder . pause ( )
2025-10-28 00:23:52 -07:00
e . execute ( item [ 2 ] , prompt_id , extra_data , item [ 4 ] )
2026-03-24 20:48:55 -07:00
2023-11-30 15:22:32 -05:00
need_gc = True
2025-10-28 00:23:52 -07:00
remove_sensitive = lambda prompt : prompt [ : 5 ] + prompt [ 6 : ]
2024-01-11 08:38:18 -05:00
q . task_done ( item_id ,
2024-08-15 08:21:11 -07:00
e . history_result ,
2024-01-11 08:38:18 -05:00
status = execution . PromptQueue . ExecutionStatus (
status_str = ' success ' if e . success else ' error ' ,
completed = e . success ,
2025-10-28 00:23:52 -07:00
messages = e . status_messages ) , process_item = remove_sensitive )
2024-12-24 14:38:52 +03:00
if server_instance . client_id is not None :
server_instance . send_sync ( " executing " , { " node " : None , " prompt_id " : prompt_id } , server_instance . client_id )
2023-11-30 15:22:32 -05:00
current_time = time . perf_counter ( )
execution_time = current_time - execution_start_time
2025-06-21 00:30:39 -07:00
2025-06-21 00:04:55 -03:00
# Log Time in a more readable way after 10 minutes
if execution_time > 600 :
execution_time = time . strftime ( " % H: % M: % S " , time . gmtime ( execution_time ) )
logging . info ( f " Prompt executed in { execution_time } " )
else :
logging . info ( " Prompt executed in {:.2f} seconds " . format ( execution_time ) )
2023-11-30 15:22:32 -05:00
2026-03-24 20:48:55 -07:00
if not asset_seeder . is_disabled ( ) :
paths = _collect_output_absolute_paths ( e . history_result )
register_output_files ( paths , job_id = prompt_id )
2024-01-04 14:28:11 -05:00
flags = q . get_flags ( )
free_memory = flags . get ( " free_memory " , False )
if flags . get ( " unload_models " , free_memory ) :
comfy . model_management . unload_all_models ( )
need_gc = True
last_gc_collect = 0
if free_memory :
e . reset ( )
need_gc = True
last_gc_collect = 0
2023-11-30 15:22:32 -05:00
if need_gc :
current_time = time . perf_counter ( )
if ( current_time - last_gc_collect ) > gc_collect_interval :
gc . collect ( )
comfy . model_management . soft_empty_cache ( )
last_gc_collect = current_time
need_gc = False
2025-04-26 17:52:56 -07:00
hook_breaker_ac10a0 . restore_functions ( )
2026-03-24 20:48:55 -07:00
if not asset_seeder . is_disabled ( ) :
asset_seeder . enqueue_enrich ( roots = ( " output " , ) , compute_hashes = True )
2026-03-07 17:37:25 -08:00
asset_seeder . resume ( )
2023-06-07 15:15:38 +02:00
2024-12-24 14:38:52 +03:00
async def run ( server_instance , address = ' ' , port = 8188 , verbose = True , call_on_start = None ) :
2024-09-23 04:36:59 -04:00
addresses = [ ]
for addr in address . split ( " , " ) :
addresses . append ( ( addr , port ) )
2024-12-31 11:27:09 +03:00
await asyncio . gather (
server_instance . start_multi_address ( addresses , call_on_start , verbose ) , server_instance . publish_loop ( )
)
2023-01-03 01:53:32 -05:00
2024-12-24 14:38:52 +03:00
def hijack_progress ( server_instance ) :
2025-07-10 11:46:19 -07:00
def hook ( value , total , preview_image , prompt_id = None , node_id = None ) :
executing_context = get_executing_context ( )
if prompt_id is None and executing_context is not None :
prompt_id = executing_context . prompt_id
if node_id is None and executing_context is not None :
node_id = executing_context . node_id
2023-09-07 23:37:03 -04:00
comfy . model_management . throw_exception_if_processing_interrupted ( )
2025-07-10 11:46:19 -07:00
if prompt_id is None :
prompt_id = server_instance . last_prompt_id
if node_id is None :
node_id = server_instance . last_node_id
progress = { " value " : value , " max " : total , " prompt_id " : prompt_id , " node " : node_id }
get_progress_state ( ) . update_progress ( node_id , value , total , preview_image )
2024-01-01 14:27:56 -05:00
2024-12-24 14:38:52 +03:00
server_instance . send_sync ( " progress " , progress , server_instance . client_id )
2023-07-19 17:37:27 -04:00
if preview_image is not None :
2025-07-10 11:46:19 -07:00
# Only send old method if client doesn't support preview metadata
if not feature_flags . supports_feature (
server_instance . sockets_metadata ,
server_instance . client_id ,
" supports_preview_metadata " ,
) :
server_instance . send_sync (
BinaryEventTypes . UNENCODED_PREVIEW_IMAGE ,
preview_image ,
server_instance . client_id ,
)
2024-12-24 14:38:52 +03:00
2023-05-02 23:00:49 -04:00
comfy . utils . set_progress_bar_global_hook ( hook )
2023-01-03 01:53:32 -05:00
2023-06-07 15:15:38 +02:00
2023-03-13 19:34:05 +00:00
def cleanup_temp ( ) :
2023-08-11 05:00:25 -04:00
temp_dir = folder_paths . get_temp_directory ( )
2023-03-13 19:34:05 +00:00
if os . path . exists ( temp_dir ) :
2023-03-14 18:07:09 -04:00
shutil . rmtree ( temp_dir , ignore_errors = True )
2023-03-13 19:34:05 +00:00
2023-06-07 15:15:38 +02:00
2025-06-11 21:43:39 +01:00
def setup_database ( ) :
try :
if dependencies_available ( ) :
init_db ( )
2026-03-07 17:37:25 -08:00
if args . enable_assets :
if asset_seeder . start ( roots = ( " models " , " input " , " output " ) , prune_first = True , compute_hashes = True ) :
logging . info ( " Background asset scan initiated for models, input, output " )
2025-06-11 21:43:39 +01:00
except Exception as e :
2026-03-07 17:37:25 -08:00
if " database is locked " in str ( e ) :
logging . error (
" Database is locked. Another ComfyUI process is already using this database. \n "
" To resolve this, specify a separate database file for this instance: \n "
" --database-url sqlite:///path/to/another.db "
)
sys . exit ( 1 )
if args . enable_assets :
logging . error (
f " Failed to initialize database: { e } \n "
" The --enable-assets flag requires a working database connection. \n "
" To resolve this, try one of the following: \n "
" 1. Install the latest requirements: pip install -r requirements.txt \n "
" 2. Specify an alternative database URL: --database-url sqlite:///path/to/your.db \n "
" 3. Use an in-memory database: --database-url sqlite:///:memory: "
)
sys . exit ( 1 )
2025-06-11 21:43:39 +01:00
logging . error ( f " Failed to initialize database. Please ensure you have installed the latest requirements. If the error persists, please report this as in future the database will be required: { e } " )
2024-12-24 14:38:52 +03:00
def start_comfyui ( asyncio_loop = None ) :
"""
Starts the ComfyUI server using the provided asyncio event loop or creates a new one.
Returns the event loop, server instance, and a function to start the server asynchronously.
"""
2023-08-11 05:00:25 -04:00
if args . temp_directory :
temp_dir = os . path . join ( os . path . abspath ( args . temp_directory ) , " temp " )
2024-03-11 16:24:47 -04:00
logging . info ( f " Setting temp directory to: { temp_dir } " )
2023-08-11 05:00:25 -04:00
folder_paths . set_temp_directory ( temp_dir )
2023-03-13 19:34:05 +00:00
cleanup_temp ( )
2024-02-26 13:32:14 -05:00
if args . windows_standalone_build :
try :
import new_updater
new_updater . update_windows_updater ( )
except :
pass
2024-12-24 14:38:52 +03:00
if not asyncio_loop :
asyncio_loop = asyncio . new_event_loop ( )
asyncio . set_event_loop ( asyncio_loop )
prompt_server = server . PromptServer ( asyncio_loop )
2023-02-12 15:53:48 +00:00
2025-12-02 12:32:52 +09:00
if args . enable_manager and not args . disable_manager_ui :
comfyui_manager . start ( )
2025-04-26 17:52:56 -07:00
hook_breaker_ac10a0 . save_functions ( )
2025-07-29 19:17:22 -07:00
asyncio_loop . run_until_complete ( nodes . init_extra_nodes (
2025-06-28 12:53:40 -07:00
init_custom_nodes = ( not args . disable_all_custom_nodes ) or len ( args . whitelist_custom_nodes ) > 0 ,
2025-06-29 03:24:02 +08:00
init_api_nodes = not args . disable_api_nodes
2025-07-29 19:17:22 -07:00
) )
2025-04-26 17:52:56 -07:00
hook_breaker_ac10a0 . restore_functions ( )
2023-08-13 12:37:53 -04:00
cuda_malloc_warning ( )
2025-06-11 21:43:39 +01:00
setup_database ( )
2023-08-13 12:37:53 -04:00
2024-12-24 14:38:52 +03:00
prompt_server . add_routes ( )
hijack_progress ( prompt_server )
2023-02-21 19:29:49 +00:00
2025-05-21 05:14:17 -04:00
threading . Thread ( target = prompt_worker , daemon = True , args = ( prompt_server . prompt_queue , prompt_server , ) ) . start ( )
2023-02-07 21:57:17 -05:00
2023-04-05 20:32:59 -04:00
if args . quick_test_for_ci :
2023-03-14 23:02:57 -04:00
exit ( 0 )
2024-09-18 09:39:43 -04:00
os . makedirs ( folder_paths . get_temp_directory ( ) , exist_ok = True )
2023-03-12 15:44:16 -04:00
call_on_start = None
2023-05-06 16:59:40 -04:00
if args . auto_launch :
2024-04-30 20:17:02 -04:00
def startup_server ( scheme , address , port ) :
2023-03-12 15:44:16 -04:00
import webbrowser
2023-08-01 01:14:17 -04:00
if os . name == ' nt ' and address == ' 0.0.0.0 ' :
address = ' 127.0.0.1 '
2024-09-23 04:36:59 -04:00
if ' : ' in address :
address = " [ {} ] " . format ( address )
2024-04-30 20:17:02 -04:00
webbrowser . open ( f " { scheme } :// { address } : { port } " )
2023-03-12 15:44:16 -04:00
call_on_start = startup_server
2024-12-24 14:38:52 +03:00
async def start_all ( ) :
await prompt_server . setup ( )
await run ( prompt_server , address = args . listen , port = args . port , verbose = not args . dont_print_server , call_on_start = call_on_start )
# Returning these so that other code can integrate with the ComfyUI loop and server
return asyncio_loop , prompt_server , start_all
if __name__ == " __main__ " :
# Running directly, just start ComfyUI.
2025-04-12 18:58:20 -04:00
logging . info ( " Python version: {} " . format ( sys . version ) )
2025-01-25 15:03:57 -05:00
logging . info ( " ComfyUI version: {} " . format ( comfyui_version . __version__ ) )
2026-03-08 13:25:30 -07:00
for package in ( " comfy-aimdo " , " comfy-kitchen " ) :
try :
logging . info ( " {} version: {} " . format ( package , importlib . metadata . version ( package ) ) )
except :
pass
2025-03-07 19:53:07 -05:00
2025-06-12 12:38:33 -07:00
if sys . version_info . major == 3 and sys . version_info . minor < 10 :
logging . warning ( " WARNING: You are using a python version older than 3.10, please upgrade to a newer one. 3.12 and above is recommended. " )
2026-03-22 15:46:18 -07:00
if args . disable_dynamic_vram :
logging . warning ( " Dynamic vram disabled with argument. If you have any issues with dynamic vram enabled please give us a detailed reports as this argument will be removed soon. " )
2024-12-24 14:38:52 +03:00
event_loop , _ , start_all_func = start_comfyui ( )
2023-06-07 15:15:38 +02:00
try :
2025-03-08 03:51:36 -05:00
x = start_all_func ( )
2025-03-12 07:13:40 -04:00
app . logger . print_startup_warnings ( )
2025-03-08 03:51:36 -05:00
event_loop . run_until_complete ( x )
2023-06-07 15:15:38 +02:00
except KeyboardInterrupt :
2024-03-11 16:24:47 -04:00
logging . info ( " \n Stopped server " )
2026-03-07 17:37:25 -08:00
finally :
asset_seeder . shutdown ( )
cleanup_temp ( )