Files
Gokay Aydogan 73d9392bf7 feat: v2.5.0 — async execution, typed builders, featured tier, registry freshness
- Async node execution: on ComfyUI with native async support (detected
  via comfy_execution.utils, added in the same commit as async nodes),
  all dynamic nodes and Fal Any Endpoint run as coroutines — independent
  graph branches execute fal calls concurrently with no Submit/Collect
  required. Uploads/downloads/preflight run off-loop; older ComfyUI
  versions keep byte-identical sync behavior. Live-verified: two
  concurrent generations in 2.5s total.
- Typed builder nodes (FAL/Utils/Builders): 8 chainable builders
  (LoRA, embedding, ControlNet, IP-Adapter, reference image/element,
  multi-prompt shot, key-value, JSON merge) replacing JSON-by-hand for
  the 467 object-typed inputs across the catalog; shapes validated
  against live OpenAPI schemas.
- Discovery: FAL/Featured tier (data/featured_models.json, 26 flagship
  endpoints with display-name overrides), 434 models flagged as
  superseded within their family in node help, thumbnails in the
  endpoint picker.
- Registry freshness: startup delta check against the live catalog
  (logs how many models are newer than the snapshot), sidebar Registry
  section with one-click refresh (atomic registry write; restart note).
- Docs: README 1,946 → 327 lines; model tables moved to MODELS.md
  (generator retargeted; weekly refresh workflow now regenerates it);
  CONTRIBUTING.md redirects hand-written-node PRs to the registry and
  featured-list workflow.

Review fixes: spend-guard preflight moved off the event loop in the
async path; registry writes atomically via temp+rename; freshness
daemon gated off in tests; non-finite numbers rejected in FalKeyValue;
sidebar poll budget aligned with the server timeout.
2026-07-02 20:34:55 +03:00

73 lines
1.7 KiB
Python

"""Shared fixtures: load the pack exactly like ComfyUI does (hyphenated dir)."""
from __future__ import annotations
import importlib
import importlib.util
import os
import sys
import tempfile
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
PKG = "ComfyUI_fal_API"
# never let the freshness daemon make live network calls during tests
os.environ.setdefault("FAL_DISABLE_STARTUP_CHECK", "1")
# keep the persistent result cache out of the user's real cache dir during tests
os.environ.setdefault(
"COMFYUI_FAL_API_CACHE_DB",
str(Path(tempfile.mkdtemp(prefix="fal-api-test-cache-")) / "cache.db"),
)
def _load_package():
if PKG in sys.modules:
return sys.modules[PKG]
spec = importlib.util.spec_from_file_location(
PKG, ROOT / "__init__.py", submodule_search_locations=[str(ROOT)]
)
module = importlib.util.module_from_spec(spec)
sys.modules[PKG] = module
spec.loader.exec_module(module)
return module
@pytest.fixture(scope="session")
def pack():
"""The fully loaded node pack (static + dynamic mappings)."""
return _load_package()
def _submodule(name: str):
_load_package()
return importlib.import_module(f"{PKG}.{name}")
@pytest.fixture(scope="session")
def schema_to_inputs():
return _submodule("nodes.dynamic.schema_to_inputs")
@pytest.fixture(scope="session")
def arguments_mod():
return _submodule("nodes.dynamic.arguments")
@pytest.fixture(scope="session")
def outputs_mod():
return _submodule("nodes.dynamic.outputs")
@pytest.fixture(scope="session")
def factory_mod():
return _submodule("nodes.dynamic.factory")
@pytest.fixture(scope="session")
def errors_mod():
return _submodule("nodes.utils.errors")