mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-12-17 10:02:59 +08:00
comfy_api: remove usage of "Type","List" and "Dict" types (#11238)
This commit is contained in:
parent
dbd330454a
commit
43e0d4e3cc
@ -5,12 +5,12 @@ This module handles capability negotiation between frontend and backend,
|
|||||||
allowing graceful protocol evolution while maintaining backward compatibility.
|
allowing graceful protocol evolution while maintaining backward compatibility.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Any, Dict
|
from typing import Any
|
||||||
|
|
||||||
from comfy.cli_args import args
|
from comfy.cli_args import args
|
||||||
|
|
||||||
# Default server capabilities
|
# Default server capabilities
|
||||||
SERVER_FEATURE_FLAGS: Dict[str, Any] = {
|
SERVER_FEATURE_FLAGS: dict[str, Any] = {
|
||||||
"supports_preview_metadata": True,
|
"supports_preview_metadata": True,
|
||||||
"max_upload_size": args.max_upload_size * 1024 * 1024, # Convert MB to bytes
|
"max_upload_size": args.max_upload_size * 1024 * 1024, # Convert MB to bytes
|
||||||
"extension": {"manager": {"supports_v4": True}},
|
"extension": {"manager": {"supports_v4": True}},
|
||||||
@ -18,7 +18,7 @@ SERVER_FEATURE_FLAGS: Dict[str, Any] = {
|
|||||||
|
|
||||||
|
|
||||||
def get_connection_feature(
|
def get_connection_feature(
|
||||||
sockets_metadata: Dict[str, Dict[str, Any]],
|
sockets_metadata: dict[str, dict[str, Any]],
|
||||||
sid: str,
|
sid: str,
|
||||||
feature_name: str,
|
feature_name: str,
|
||||||
default: Any = False
|
default: Any = False
|
||||||
@ -42,7 +42,7 @@ def get_connection_feature(
|
|||||||
|
|
||||||
|
|
||||||
def supports_feature(
|
def supports_feature(
|
||||||
sockets_metadata: Dict[str, Dict[str, Any]],
|
sockets_metadata: dict[str, dict[str, Any]],
|
||||||
sid: str,
|
sid: str,
|
||||||
feature_name: str
|
feature_name: str
|
||||||
) -> bool:
|
) -> bool:
|
||||||
@ -60,7 +60,7 @@ def supports_feature(
|
|||||||
return get_connection_feature(sockets_metadata, sid, feature_name, False) is True
|
return get_connection_feature(sockets_metadata, sid, feature_name, False) is True
|
||||||
|
|
||||||
|
|
||||||
def get_server_features() -> Dict[str, Any]:
|
def get_server_features() -> dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Get the server's feature flags.
|
Get the server's feature flags.
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from typing import Type, List, NamedTuple
|
from typing import NamedTuple
|
||||||
from comfy_api.internal.singleton import ProxiedSingleton
|
from comfy_api.internal.singleton import ProxiedSingleton
|
||||||
from packaging import version as packaging_version
|
from packaging import version as packaging_version
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ class ComfyAPIBase(ProxiedSingleton):
|
|||||||
|
|
||||||
class ComfyAPIWithVersion(NamedTuple):
|
class ComfyAPIWithVersion(NamedTuple):
|
||||||
version: str
|
version: str
|
||||||
api_class: Type[ComfyAPIBase]
|
api_class: type[ComfyAPIBase]
|
||||||
|
|
||||||
|
|
||||||
def parse_version(version_str: str) -> packaging_version.Version:
|
def parse_version(version_str: str) -> packaging_version.Version:
|
||||||
@ -23,16 +23,16 @@ def parse_version(version_str: str) -> packaging_version.Version:
|
|||||||
return packaging_version.parse(version_str)
|
return packaging_version.parse(version_str)
|
||||||
|
|
||||||
|
|
||||||
registered_versions: List[ComfyAPIWithVersion] = []
|
registered_versions: list[ComfyAPIWithVersion] = []
|
||||||
|
|
||||||
|
|
||||||
def register_versions(versions: List[ComfyAPIWithVersion]):
|
def register_versions(versions: list[ComfyAPIWithVersion]):
|
||||||
versions.sort(key=lambda x: parse_version(x.version))
|
versions.sort(key=lambda x: parse_version(x.version))
|
||||||
global registered_versions
|
global registered_versions
|
||||||
registered_versions = versions
|
registered_versions = versions
|
||||||
|
|
||||||
|
|
||||||
def get_all_versions() -> List[ComfyAPIWithVersion]:
|
def get_all_versions() -> list[ComfyAPIWithVersion]:
|
||||||
"""
|
"""
|
||||||
Returns a list of all registered ComfyAPI versions.
|
Returns a list of all registered ComfyAPI versions.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import os
|
|||||||
import textwrap
|
import textwrap
|
||||||
import threading
|
import threading
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Optional, Type, get_origin, get_args, get_type_hints
|
from typing import Optional, get_origin, get_args, get_type_hints
|
||||||
|
|
||||||
|
|
||||||
class TypeTracker:
|
class TypeTracker:
|
||||||
@ -193,7 +193,7 @@ class AsyncToSyncConverter:
|
|||||||
return result_container["result"]
|
return result_container["result"]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_sync_class(cls, async_class: Type, thread_pool_size=10) -> Type:
|
def create_sync_class(cls, async_class: type, thread_pool_size=10) -> type:
|
||||||
"""
|
"""
|
||||||
Creates a new class with synchronous versions of all async methods.
|
Creates a new class with synchronous versions of all async methods.
|
||||||
|
|
||||||
@ -563,7 +563,7 @@ class AsyncToSyncConverter:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _generate_imports(
|
def _generate_imports(
|
||||||
cls, async_class: Type, type_tracker: TypeTracker
|
cls, async_class: type, type_tracker: TypeTracker
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
"""Generate import statements for the stub file."""
|
"""Generate import statements for the stub file."""
|
||||||
imports = []
|
imports = []
|
||||||
@ -628,7 +628,7 @@ class AsyncToSyncConverter:
|
|||||||
return imports
|
return imports
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_class_attributes(cls, async_class: Type) -> list[tuple[str, Type]]:
|
def _get_class_attributes(cls, async_class: type) -> list[tuple[str, type]]:
|
||||||
"""Extract class attributes that are classes themselves."""
|
"""Extract class attributes that are classes themselves."""
|
||||||
class_attributes = []
|
class_attributes = []
|
||||||
|
|
||||||
@ -654,7 +654,7 @@ class AsyncToSyncConverter:
|
|||||||
def _generate_inner_class_stub(
|
def _generate_inner_class_stub(
|
||||||
cls,
|
cls,
|
||||||
name: str,
|
name: str,
|
||||||
attr: Type,
|
attr: type,
|
||||||
indent: str = " ",
|
indent: str = " ",
|
||||||
type_tracker: Optional[TypeTracker] = None,
|
type_tracker: Optional[TypeTracker] = None,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
@ -782,7 +782,7 @@ class AsyncToSyncConverter:
|
|||||||
return processed
|
return processed
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_stub_file(cls, async_class: Type, sync_class: Type) -> None:
|
def generate_stub_file(cls, async_class: type, sync_class: type) -> None:
|
||||||
"""
|
"""
|
||||||
Generate a .pyi stub file for the sync class to help IDEs with type checking.
|
Generate a .pyi stub file for the sync class to help IDEs with type checking.
|
||||||
"""
|
"""
|
||||||
@ -988,7 +988,7 @@ class AsyncToSyncConverter:
|
|||||||
logging.error(traceback.format_exc())
|
logging.error(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
def create_sync_class(async_class: Type, thread_pool_size=10) -> Type:
|
def create_sync_class(async_class: type, thread_pool_size=10) -> type:
|
||||||
"""
|
"""
|
||||||
Creates a sync version of an async class
|
Creates a sync version of an async class
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from typing import Type, TypeVar
|
from typing import TypeVar
|
||||||
|
|
||||||
class SingletonMetaclass(type):
|
class SingletonMetaclass(type):
|
||||||
T = TypeVar("T", bound="SingletonMetaclass")
|
T = TypeVar("T", bound="SingletonMetaclass")
|
||||||
@ -11,13 +11,13 @@ class SingletonMetaclass(type):
|
|||||||
)
|
)
|
||||||
return cls._instances[cls]
|
return cls._instances[cls]
|
||||||
|
|
||||||
def inject_instance(cls: Type[T], instance: T) -> None:
|
def inject_instance(cls: type[T], instance: T) -> None:
|
||||||
assert cls not in SingletonMetaclass._instances, (
|
assert cls not in SingletonMetaclass._instances, (
|
||||||
"Cannot inject instance after first instantiation"
|
"Cannot inject instance after first instantiation"
|
||||||
)
|
)
|
||||||
SingletonMetaclass._instances[cls] = instance
|
SingletonMetaclass._instances[cls] = instance
|
||||||
|
|
||||||
def get_instance(cls: Type[T], *args, **kwargs) -> T:
|
def get_instance(cls: type[T], *args, **kwargs) -> T:
|
||||||
"""
|
"""
|
||||||
Gets the singleton instance of the class, creating it if it doesn't exist.
|
Gets the singleton instance of the class, creating it if it doesn't exist.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Type, TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from comfy_api.internal import ComfyAPIBase
|
from comfy_api.internal import ComfyAPIBase
|
||||||
from comfy_api.internal.singleton import ProxiedSingleton
|
from comfy_api.internal.singleton import ProxiedSingleton
|
||||||
from comfy_api.internal.async_to_sync import create_sync_class
|
from comfy_api.internal.async_to_sync import create_sync_class
|
||||||
@ -113,7 +113,7 @@ ComfyAPI = ComfyAPI_latest
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import comfy_api.latest.generated.ComfyAPISyncStub # type: ignore
|
import comfy_api.latest.generated.ComfyAPISyncStub # type: ignore
|
||||||
|
|
||||||
ComfyAPISync: Type[comfy_api.latest.generated.ComfyAPISyncStub.ComfyAPISyncStub]
|
ComfyAPISync: type[comfy_api.latest.generated.ComfyAPISyncStub.ComfyAPISyncStub]
|
||||||
ComfyAPISync = create_sync_class(ComfyAPI_latest)
|
ComfyAPISync = create_sync_class(ComfyAPI_latest)
|
||||||
|
|
||||||
# create new aliases for io and ui
|
# create new aliases for io and ui
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import torch
|
import torch
|
||||||
from typing import TypedDict, List, Optional
|
from typing import TypedDict, Optional
|
||||||
|
|
||||||
ImageInput = torch.Tensor
|
ImageInput = torch.Tensor
|
||||||
"""
|
"""
|
||||||
@ -39,4 +39,4 @@ class LatentInput(TypedDict):
|
|||||||
Optional noise mask tensor in the same format as samples.
|
Optional noise mask tensor in the same format as samples.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
batch_index: Optional[List[int]]
|
batch_index: Optional[list[int]]
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import os
|
|||||||
import random
|
import random
|
||||||
import uuid
|
import uuid
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Type
|
|
||||||
|
|
||||||
import av
|
import av
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -83,7 +82,7 @@ class ImageSaveHelper:
|
|||||||
return PILImage.fromarray(np.clip(255.0 * image_tensor.cpu().numpy(), 0, 255).astype(np.uint8))
|
return PILImage.fromarray(np.clip(255.0 * image_tensor.cpu().numpy(), 0, 255).astype(np.uint8))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_png_metadata(cls: Type[ComfyNode] | None) -> PngInfo | None:
|
def _create_png_metadata(cls: type[ComfyNode] | None) -> PngInfo | None:
|
||||||
"""Creates a PngInfo object with prompt and extra_pnginfo."""
|
"""Creates a PngInfo object with prompt and extra_pnginfo."""
|
||||||
if args.disable_metadata or cls is None or not cls.hidden:
|
if args.disable_metadata or cls is None or not cls.hidden:
|
||||||
return None
|
return None
|
||||||
@ -96,7 +95,7 @@ class ImageSaveHelper:
|
|||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_animated_png_metadata(cls: Type[ComfyNode] | None) -> PngInfo | None:
|
def _create_animated_png_metadata(cls: type[ComfyNode] | None) -> PngInfo | None:
|
||||||
"""Creates a PngInfo object with prompt and extra_pnginfo for animated PNGs (APNG)."""
|
"""Creates a PngInfo object with prompt and extra_pnginfo for animated PNGs (APNG)."""
|
||||||
if args.disable_metadata or cls is None or not cls.hidden:
|
if args.disable_metadata or cls is None or not cls.hidden:
|
||||||
return None
|
return None
|
||||||
@ -121,7 +120,7 @@ class ImageSaveHelper:
|
|||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_webp_metadata(pil_image: PILImage.Image, cls: Type[ComfyNode] | None) -> PILImage.Exif:
|
def _create_webp_metadata(pil_image: PILImage.Image, cls: type[ComfyNode] | None) -> PILImage.Exif:
|
||||||
"""Creates EXIF metadata bytes for WebP images."""
|
"""Creates EXIF metadata bytes for WebP images."""
|
||||||
exif_data = pil_image.getexif()
|
exif_data = pil_image.getexif()
|
||||||
if args.disable_metadata or cls is None or cls.hidden is None:
|
if args.disable_metadata or cls is None or cls.hidden is None:
|
||||||
@ -137,7 +136,7 @@ class ImageSaveHelper:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def save_images(
|
def save_images(
|
||||||
images, filename_prefix: str, folder_type: FolderType, cls: Type[ComfyNode] | None, compress_level = 4,
|
images, filename_prefix: str, folder_type: FolderType, cls: type[ComfyNode] | None, compress_level = 4,
|
||||||
) -> list[SavedResult]:
|
) -> list[SavedResult]:
|
||||||
"""Saves a batch of images as individual PNG files."""
|
"""Saves a batch of images as individual PNG files."""
|
||||||
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(
|
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(
|
||||||
@ -155,7 +154,7 @@ class ImageSaveHelper:
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_save_images_ui(images, filename_prefix: str, cls: Type[ComfyNode] | None, compress_level=4) -> SavedImages:
|
def get_save_images_ui(images, filename_prefix: str, cls: type[ComfyNode] | None, compress_level=4) -> SavedImages:
|
||||||
"""Saves a batch of images and returns a UI object for the node output."""
|
"""Saves a batch of images and returns a UI object for the node output."""
|
||||||
return SavedImages(
|
return SavedImages(
|
||||||
ImageSaveHelper.save_images(
|
ImageSaveHelper.save_images(
|
||||||
@ -169,7 +168,7 @@ class ImageSaveHelper:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def save_animated_png(
|
def save_animated_png(
|
||||||
images, filename_prefix: str, folder_type: FolderType, cls: Type[ComfyNode] | None, fps: float, compress_level: int
|
images, filename_prefix: str, folder_type: FolderType, cls: type[ComfyNode] | None, fps: float, compress_level: int
|
||||||
) -> SavedResult:
|
) -> SavedResult:
|
||||||
"""Saves a batch of images as a single animated PNG."""
|
"""Saves a batch of images as a single animated PNG."""
|
||||||
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(
|
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(
|
||||||
@ -191,7 +190,7 @@ class ImageSaveHelper:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_save_animated_png_ui(
|
def get_save_animated_png_ui(
|
||||||
images, filename_prefix: str, cls: Type[ComfyNode] | None, fps: float, compress_level: int
|
images, filename_prefix: str, cls: type[ComfyNode] | None, fps: float, compress_level: int
|
||||||
) -> SavedImages:
|
) -> SavedImages:
|
||||||
"""Saves an animated PNG and returns a UI object for the node output."""
|
"""Saves an animated PNG and returns a UI object for the node output."""
|
||||||
result = ImageSaveHelper.save_animated_png(
|
result = ImageSaveHelper.save_animated_png(
|
||||||
@ -209,7 +208,7 @@ class ImageSaveHelper:
|
|||||||
images,
|
images,
|
||||||
filename_prefix: str,
|
filename_prefix: str,
|
||||||
folder_type: FolderType,
|
folder_type: FolderType,
|
||||||
cls: Type[ComfyNode] | None,
|
cls: type[ComfyNode] | None,
|
||||||
fps: float,
|
fps: float,
|
||||||
lossless: bool,
|
lossless: bool,
|
||||||
quality: int,
|
quality: int,
|
||||||
@ -238,7 +237,7 @@ class ImageSaveHelper:
|
|||||||
def get_save_animated_webp_ui(
|
def get_save_animated_webp_ui(
|
||||||
images,
|
images,
|
||||||
filename_prefix: str,
|
filename_prefix: str,
|
||||||
cls: Type[ComfyNode] | None,
|
cls: type[ComfyNode] | None,
|
||||||
fps: float,
|
fps: float,
|
||||||
lossless: bool,
|
lossless: bool,
|
||||||
quality: int,
|
quality: int,
|
||||||
@ -267,7 +266,7 @@ class AudioSaveHelper:
|
|||||||
audio: dict,
|
audio: dict,
|
||||||
filename_prefix: str,
|
filename_prefix: str,
|
||||||
folder_type: FolderType,
|
folder_type: FolderType,
|
||||||
cls: Type[ComfyNode] | None,
|
cls: type[ComfyNode] | None,
|
||||||
format: str = "flac",
|
format: str = "flac",
|
||||||
quality: str = "128k",
|
quality: str = "128k",
|
||||||
) -> list[SavedResult]:
|
) -> list[SavedResult]:
|
||||||
@ -372,7 +371,7 @@ class AudioSaveHelper:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_save_audio_ui(
|
def get_save_audio_ui(
|
||||||
audio, filename_prefix: str, cls: Type[ComfyNode] | None, format: str = "flac", quality: str = "128k",
|
audio, filename_prefix: str, cls: type[ComfyNode] | None, format: str = "flac", quality: str = "128k",
|
||||||
) -> SavedAudios:
|
) -> SavedAudios:
|
||||||
"""Save and instantly wrap for UI."""
|
"""Save and instantly wrap for UI."""
|
||||||
return SavedAudios(
|
return SavedAudios(
|
||||||
@ -388,7 +387,7 @@ class AudioSaveHelper:
|
|||||||
|
|
||||||
|
|
||||||
class PreviewImage(_UIOutput):
|
class PreviewImage(_UIOutput):
|
||||||
def __init__(self, image: Image.Type, animated: bool = False, cls: Type[ComfyNode] = None, **kwargs):
|
def __init__(self, image: Image.Type, animated: bool = False, cls: type[ComfyNode] = None, **kwargs):
|
||||||
self.values = ImageSaveHelper.save_images(
|
self.values = ImageSaveHelper.save_images(
|
||||||
image,
|
image,
|
||||||
filename_prefix="ComfyUI_temp_" + ''.join(random.choice("abcdefghijklmnopqrstupvxyz") for _ in range(5)),
|
filename_prefix="ComfyUI_temp_" + ''.join(random.choice("abcdefghijklmnopqrstupvxyz") for _ in range(5)),
|
||||||
@ -412,7 +411,7 @@ class PreviewMask(PreviewImage):
|
|||||||
|
|
||||||
|
|
||||||
class PreviewAudio(_UIOutput):
|
class PreviewAudio(_UIOutput):
|
||||||
def __init__(self, audio: dict, cls: Type[ComfyNode] = None, **kwargs):
|
def __init__(self, audio: dict, cls: type[ComfyNode] = None, **kwargs):
|
||||||
self.values = AudioSaveHelper.save_audio(
|
self.values = AudioSaveHelper.save_audio(
|
||||||
audio,
|
audio,
|
||||||
filename_prefix="ComfyUI_temp_" + "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(5)),
|
filename_prefix="ComfyUI_temp_" + "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(5)),
|
||||||
|
|||||||
@ -2,9 +2,8 @@ from comfy_api.latest import ComfyAPI_latest
|
|||||||
from comfy_api.v0_0_2 import ComfyAPIAdapter_v0_0_2
|
from comfy_api.v0_0_2 import ComfyAPIAdapter_v0_0_2
|
||||||
from comfy_api.v0_0_1 import ComfyAPIAdapter_v0_0_1
|
from comfy_api.v0_0_1 import ComfyAPIAdapter_v0_0_1
|
||||||
from comfy_api.internal import ComfyAPIBase
|
from comfy_api.internal import ComfyAPIBase
|
||||||
from typing import List, Type
|
|
||||||
|
|
||||||
supported_versions: List[Type[ComfyAPIBase]] = [
|
supported_versions: list[type[ComfyAPIBase]] = [
|
||||||
ComfyAPI_latest,
|
ComfyAPI_latest,
|
||||||
ComfyAPIAdapter_v0_0_2,
|
ComfyAPIAdapter_v0_0_2,
|
||||||
ComfyAPIAdapter_v0_0_1,
|
ComfyAPIAdapter_v0_0_1,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user