refactor: make scanner helper functions public

Rename _sync_root_safely, _prune_orphans_safely, _collect_paths_for_roots,
_build_asset_specs, and _insert_asset_specs to remove underscore prefix
since they are used by seeder.py as part of the public API.

Amp-Thread-ID: https://ampcode.com/threads/T-019c3037-df32-7138-99d8-b4b824d896b3
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Luke Mino-Altherr
2026-02-05 19:01:46 -08:00
parent e054a40765
commit 6443cf016e
3 changed files with 70 additions and 53 deletions

View File

@@ -46,6 +46,7 @@ class _AssetAccumulator(TypedDict):
size_db: int
states: list[_StateInfo]
RootType = Literal["models", "input", "output"]
@@ -200,7 +201,7 @@ def sync_cache_states_with_filesystem(
return survivors if collect_existing_paths else None
def _sync_root_safely(root: RootType) -> set[str]:
def sync_root_safely(root: RootType) -> set[str]:
"""Sync a single root's cache states with the filesystem.
Returns survivors (existing paths) or empty set on failure.
@@ -220,7 +221,7 @@ def _sync_root_safely(root: RootType) -> set[str]:
return set()
def _prune_orphans_safely(prefixes: list[str]) -> int:
def prune_orphans_safely(prefixes: list[str]) -> int:
"""Prune orphaned assets outside the given prefixes.
Returns count pruned or 0 on failure.
@@ -235,7 +236,7 @@ def _prune_orphans_safely(prefixes: list[str]) -> int:
return 0
def _collect_paths_for_roots(roots: tuple[RootType, ...]) -> list[str]:
def collect_paths_for_roots(roots: tuple[RootType, ...]) -> list[str]:
"""Collect all file paths for the given roots."""
paths: list[str] = []
if "models" in roots:
@@ -247,7 +248,7 @@ def _collect_paths_for_roots(roots: tuple[RootType, ...]) -> list[str]:
return paths
def _build_asset_specs(
def build_asset_specs(
paths: list[str],
existing_paths: set[str],
enable_metadata_extraction: bool = True,
@@ -303,7 +304,7 @@ def _build_asset_specs(
return specs, tag_pool, skipped
def _insert_asset_specs(specs: list[SeedAssetSpec], tag_pool: set[str]) -> int:
def insert_asset_specs(specs: list[SeedAssetSpec], tag_pool: set[str]) -> int:
"""Insert asset specs into database, returning count of created infos."""
if not specs:
return 0
@@ -330,11 +331,11 @@ def seed_assets(roots: tuple[RootType, ...], enable_logging: bool = False) -> No
existing_paths: set[str] = set()
for r in roots:
existing_paths.update(_sync_root_safely(r))
existing_paths.update(sync_root_safely(r))
paths = _collect_paths_for_roots(roots)
specs, tag_pool, skipped_existing = _build_asset_specs(paths, existing_paths)
created = _insert_asset_specs(specs, tag_pool)
paths = collect_paths_for_roots(roots)
specs, tag_pool, skipped_existing = build_asset_specs(paths, existing_paths)
created = insert_asset_specs(specs, tag_pool)
if enable_logging:
logging.info(

View File

@@ -10,18 +10,18 @@ from typing import TYPE_CHECKING, Callable
from app.assets.scanner import (
RootType,
_build_asset_specs,
_collect_paths_for_roots,
_insert_asset_specs,
_prune_orphans_safely,
_sync_root_safely,
build_asset_specs,
collect_paths_for_roots,
get_all_known_prefixes,
get_prefixes_for_root,
insert_asset_specs,
prune_orphans_safely,
sync_root_safely,
)
from app.database.db import dependencies_available
if TYPE_CHECKING:
from server import PromptServer
pass
class State(Enum):
@@ -193,11 +193,13 @@ class AssetSeeder:
return 0
if not dependencies_available():
logging.warning("Database dependencies not available, skipping orphan pruning")
logging.warning(
"Database dependencies not available, skipping orphan pruning"
)
return 0
all_prefixes = get_all_known_prefixes()
pruned = _prune_orphans_safely(all_prefixes)
pruned = prune_orphans_safely(all_prefixes)
if pruned > 0:
logging.info("Pruned %d orphaned assets", pruned)
return pruned
@@ -288,7 +290,7 @@ class AssetSeeder:
if self._prune_first:
all_prefixes = get_all_known_prefixes()
pruned = _prune_orphans_safely(all_prefixes)
pruned = prune_orphans_safely(all_prefixes)
if pruned > 0:
logging.info("Pruned %d orphaned assets before scan", pruned)
@@ -305,14 +307,14 @@ class AssetSeeder:
logging.info("Asset scan cancelled during sync phase")
cancelled = True
return
existing_paths.update(_sync_root_safely(r))
existing_paths.update(sync_root_safely(r))
if self._is_cancelled():
logging.info("Asset scan cancelled after sync phase")
cancelled = True
return
paths = _collect_paths_for_roots(roots)
paths = collect_paths_for_roots(roots)
total_paths = len(paths)
self._update_progress(total=total_paths)
@@ -321,7 +323,7 @@ class AssetSeeder:
{"roots": list(roots), "total": total_paths},
)
specs, tag_pool, skipped_existing = _build_asset_specs(paths, existing_paths)
specs, tag_pool, skipped_existing = build_asset_specs(paths, existing_paths)
self._update_progress(skipped=skipped_existing)
if self._is_cancelled():
@@ -347,7 +349,7 @@ class AssetSeeder:
batch = specs[i : i + batch_size]
batch_tags = {t for spec in batch for t in spec["tags"]}
try:
created = _insert_asset_specs(batch, batch_tags)
created = insert_asset_specs(batch, batch_tags)
total_created += created
except Exception as e:
self._add_error(f"Batch insert failed at offset {i}: {e}")
@@ -360,7 +362,11 @@ class AssetSeeder:
if now - last_progress_time >= progress_interval:
self._emit_event(
"assets.seed.progress",
{"scanned": scanned, "total": len(specs), "created": total_created},
{
"scanned": scanned,
"total": len(specs),
"created": total_created,
},
)
last_progress_time = now