mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-04-01 06:23:37 +08:00
203 lines
7.7 KiB
Python
203 lines
7.7 KiB
Python
from __future__ import annotations
|
|
import os
|
|
from typing import Any, Dict, Optional
|
|
|
|
from pyisolate import ProxiedSingleton
|
|
|
|
from .base import call_singleton_rpc
|
|
|
|
|
|
def _folder_paths():
|
|
import folder_paths
|
|
|
|
return folder_paths
|
|
|
|
|
|
def _is_child_process() -> bool:
|
|
return os.environ.get("PYISOLATE_CHILD") == "1"
|
|
|
|
|
|
def _serialize_folder_names_and_paths(data: dict[str, tuple[list[str], set[str]]]) -> dict[str, dict[str, list[str]]]:
|
|
return {
|
|
key: {"paths": list(paths), "extensions": sorted(list(extensions))}
|
|
for key, (paths, extensions) in data.items()
|
|
}
|
|
|
|
|
|
def _deserialize_folder_names_and_paths(data: dict[str, dict[str, list[str]]]) -> dict[str, tuple[list[str], set[str]]]:
|
|
return {
|
|
key: (list(value.get("paths", [])), set(value.get("extensions", [])))
|
|
for key, value in data.items()
|
|
}
|
|
|
|
|
|
class FolderPathsProxy(ProxiedSingleton):
|
|
"""
|
|
Dynamic proxy for folder_paths.
|
|
Uses __getattr__ for most lookups, with explicit handling for
|
|
mutable collections to ensure efficient by-value transfer.
|
|
"""
|
|
|
|
_rpc: Optional[Any] = None
|
|
|
|
@classmethod
|
|
def set_rpc(cls, rpc: Any) -> None:
|
|
cls._rpc = rpc.create_caller(cls, cls.get_remote_id())
|
|
|
|
@classmethod
|
|
def clear_rpc(cls) -> None:
|
|
cls._rpc = None
|
|
|
|
@classmethod
|
|
def _get_caller(cls) -> Any:
|
|
if cls._rpc is None:
|
|
raise RuntimeError("FolderPathsProxy RPC caller is not configured")
|
|
return cls._rpc
|
|
|
|
def __getattr__(self, name):
|
|
if _is_child_process():
|
|
property_rpc = {
|
|
"models_dir": "rpc_get_models_dir",
|
|
"folder_names_and_paths": "rpc_get_folder_names_and_paths",
|
|
"extension_mimetypes_cache": "rpc_get_extension_mimetypes_cache",
|
|
"filename_list_cache": "rpc_get_filename_list_cache",
|
|
}
|
|
rpc_name = property_rpc.get(name)
|
|
if rpc_name is not None:
|
|
return call_singleton_rpc(self._get_caller(), rpc_name)
|
|
raise AttributeError(name)
|
|
return getattr(_folder_paths(), name)
|
|
|
|
@property
|
|
def folder_names_and_paths(self) -> Dict:
|
|
if _is_child_process():
|
|
payload = call_singleton_rpc(self._get_caller(), "rpc_get_folder_names_and_paths")
|
|
return _deserialize_folder_names_and_paths(payload)
|
|
return _folder_paths().folder_names_and_paths
|
|
|
|
@property
|
|
def extension_mimetypes_cache(self) -> Dict:
|
|
if _is_child_process():
|
|
return dict(call_singleton_rpc(self._get_caller(), "rpc_get_extension_mimetypes_cache"))
|
|
return dict(_folder_paths().extension_mimetypes_cache)
|
|
|
|
@property
|
|
def filename_list_cache(self) -> Dict:
|
|
if _is_child_process():
|
|
return dict(call_singleton_rpc(self._get_caller(), "rpc_get_filename_list_cache"))
|
|
return dict(_folder_paths().filename_list_cache)
|
|
|
|
@property
|
|
def models_dir(self) -> str:
|
|
if _is_child_process():
|
|
return str(call_singleton_rpc(self._get_caller(), "rpc_get_models_dir"))
|
|
return _folder_paths().models_dir
|
|
|
|
def get_temp_directory(self) -> str:
|
|
if _is_child_process():
|
|
return call_singleton_rpc(self._get_caller(), "rpc_get_temp_directory")
|
|
return _folder_paths().get_temp_directory()
|
|
|
|
def get_input_directory(self) -> str:
|
|
if _is_child_process():
|
|
return call_singleton_rpc(self._get_caller(), "rpc_get_input_directory")
|
|
return _folder_paths().get_input_directory()
|
|
|
|
def get_output_directory(self) -> str:
|
|
if _is_child_process():
|
|
return call_singleton_rpc(self._get_caller(), "rpc_get_output_directory")
|
|
return _folder_paths().get_output_directory()
|
|
|
|
def get_user_directory(self) -> str:
|
|
if _is_child_process():
|
|
return call_singleton_rpc(self._get_caller(), "rpc_get_user_directory")
|
|
return _folder_paths().get_user_directory()
|
|
|
|
def get_annotated_filepath(self, name: str, default_dir: str | None = None) -> str:
|
|
if _is_child_process():
|
|
return call_singleton_rpc(
|
|
self._get_caller(), "rpc_get_annotated_filepath", name, default_dir
|
|
)
|
|
return _folder_paths().get_annotated_filepath(name, default_dir)
|
|
|
|
def exists_annotated_filepath(self, name: str) -> bool:
|
|
if _is_child_process():
|
|
return bool(
|
|
call_singleton_rpc(self._get_caller(), "rpc_exists_annotated_filepath", name)
|
|
)
|
|
return bool(_folder_paths().exists_annotated_filepath(name))
|
|
|
|
def add_model_folder_path(
|
|
self, folder_name: str, full_folder_path: str, is_default: bool = False
|
|
) -> None:
|
|
if _is_child_process():
|
|
call_singleton_rpc(
|
|
self._get_caller(),
|
|
"rpc_add_model_folder_path",
|
|
folder_name,
|
|
full_folder_path,
|
|
is_default,
|
|
)
|
|
return None
|
|
_folder_paths().add_model_folder_path(folder_name, full_folder_path, is_default)
|
|
return None
|
|
|
|
def get_folder_paths(self, folder_name: str) -> list[str]:
|
|
if _is_child_process():
|
|
return list(call_singleton_rpc(self._get_caller(), "rpc_get_folder_paths", folder_name))
|
|
return list(_folder_paths().get_folder_paths(folder_name))
|
|
|
|
def get_filename_list(self, folder_name: str) -> list[str]:
|
|
if _is_child_process():
|
|
return list(call_singleton_rpc(self._get_caller(), "rpc_get_filename_list", folder_name))
|
|
return list(_folder_paths().get_filename_list(folder_name))
|
|
|
|
def get_full_path(self, folder_name: str, filename: str) -> str | None:
|
|
if _is_child_process():
|
|
return call_singleton_rpc(self._get_caller(), "rpc_get_full_path", folder_name, filename)
|
|
return _folder_paths().get_full_path(folder_name, filename)
|
|
|
|
async def rpc_get_models_dir(self) -> str:
|
|
return _folder_paths().models_dir
|
|
|
|
async def rpc_get_folder_names_and_paths(self) -> dict[str, dict[str, list[str]]]:
|
|
return _serialize_folder_names_and_paths(_folder_paths().folder_names_and_paths)
|
|
|
|
async def rpc_get_extension_mimetypes_cache(self) -> dict[str, Any]:
|
|
return dict(_folder_paths().extension_mimetypes_cache)
|
|
|
|
async def rpc_get_filename_list_cache(self) -> dict[str, Any]:
|
|
return dict(_folder_paths().filename_list_cache)
|
|
|
|
async def rpc_get_temp_directory(self) -> str:
|
|
return _folder_paths().get_temp_directory()
|
|
|
|
async def rpc_get_input_directory(self) -> str:
|
|
return _folder_paths().get_input_directory()
|
|
|
|
async def rpc_get_output_directory(self) -> str:
|
|
return _folder_paths().get_output_directory()
|
|
|
|
async def rpc_get_user_directory(self) -> str:
|
|
return _folder_paths().get_user_directory()
|
|
|
|
async def rpc_get_annotated_filepath(self, name: str, default_dir: str | None = None) -> str:
|
|
return _folder_paths().get_annotated_filepath(name, default_dir)
|
|
|
|
async def rpc_exists_annotated_filepath(self, name: str) -> bool:
|
|
return _folder_paths().exists_annotated_filepath(name)
|
|
|
|
async def rpc_add_model_folder_path(
|
|
self, folder_name: str, full_folder_path: str, is_default: bool = False
|
|
) -> None:
|
|
_folder_paths().add_model_folder_path(folder_name, full_folder_path, is_default)
|
|
|
|
async def rpc_get_folder_paths(self, folder_name: str) -> list[str]:
|
|
return _folder_paths().get_folder_paths(folder_name)
|
|
|
|
async def rpc_get_filename_list(self, folder_name: str) -> list[str]:
|
|
return _folder_paths().get_filename_list(folder_name)
|
|
|
|
async def rpc_get_full_path(self, folder_name: str, filename: str) -> str | None:
|
|
return _folder_paths().get_full_path(folder_name, filename)
|