refactor: tighten backend, flows, frontend, tests; push flows to Langflow

This commit is contained in:
Jonas Miederer 2026-09-28 15:58:00 +02:00
parent 6688fb08c6
commit 06ab25fb47
31 changed files with 783 additions and 358 deletions

View file

@ -186,6 +186,14 @@ async def sync_from_directory(
return report
def format_report(report: SyncReport) -> str:
"""One-line summary for startup/watcher logs (keeps main.py thin)."""
return (
f"+{len(report.added)} ~{len(report.updated)} -{len(report.deleted)} "
f"skipped={len(report.skipped)} errors={len(report.errors)}"
)
def default_session_factory() -> Callable[[], Session]:
return lambda: Session(get_engine())
@ -194,6 +202,27 @@ def default_lfx_factory() -> Callable[[], LfxClient]:
return lambda: LfxClient(settings.lfx_url, api_key=settings.lfx_api_key or None)
async def sync_full_pass(
session: Session,
lfx: LfxClient,
langflow,
flows_dir: str | Path,
) -> SyncReport:
"""Single orchestration: Langflow pull -> files -> DB + LFX.
Shared by POST /api/flows/sync, CLI, and watcher-adjacent paths so the
full-pass logic lives once. Pull errors merge with sync errors.
"""
from .deploy import pull_all_from_langflow
flows_dir = Path(flows_dir)
pulled_result = await pull_all_from_langflow(langflow, flows_dir)
report = await sync_from_directory(session, lfx, flows_dir)
report.pulled = pulled_result["pulled"] # type: ignore[typeddict-item]
report.errors = {**pulled_result["errors"], **report.errors} # type: ignore[typeddict-item]
return report
def run_sync_blocking(
flows_dir: str | Path,
*,
@ -250,11 +279,4 @@ async def watch_forever(
except Exception:
logger.exception("flow sync failed")
continue
logger.info(
"flow sync: +%d ~%d -%d skipped=%d errors=%d",
len(report.added),
len(report.updated),
len(report.deleted),
len(report.skipped),
len(report.errors),
)
logger.info("flow sync: %s", format_report(report))