feat: canonical flow directory with sync engine (files are source of truth)
This commit is contained in:
parent
7d5ade6b6a
commit
c65e3ed332
16 changed files with 4167 additions and 42 deletions
|
|
@ -1,15 +1,15 @@
|
|||
"""Authoring pipeline: Langflow export -> versioned definition -> LFX deploy."""
|
||||
"""Authoring pipeline: Langflow export -> canonical file -> version -> LFX deploy."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlmodel import Session
|
||||
|
||||
from app.models import FlowDefinition, FlowVersion
|
||||
from app.settings import settings
|
||||
|
||||
from . import store
|
||||
from . import export, store, sync
|
||||
from .langflow_client import LangflowClient
|
||||
from .lfx_client import LfxClient
|
||||
from .schemas import FlowDefinitionCreate, FlowVersionCreate
|
||||
|
||||
|
||||
async def import_from_langflow(
|
||||
|
|
@ -22,39 +22,31 @@ async def import_from_langflow(
|
|||
author: str = "",
|
||||
deploy: bool = True,
|
||||
) -> tuple[FlowDefinition, FlowVersion]:
|
||||
"""Export a flow from Langflow, store it as a new version, deploy to LFX.
|
||||
"""Export a flow from Langflow, persist it to backend/flows, then sync.
|
||||
|
||||
Definitions are matched by name (explicit `name` wins, else the exported
|
||||
name); every import creates a new immutable version.
|
||||
The canonical file is written first so the directory stays the source of
|
||||
truth; sync_document() derives the definition + version from it.
|
||||
"""
|
||||
export = await langflow.export_flow(langflow_flow_id)
|
||||
flow_name = name or export.get("name") or f"langflow-{langflow_flow_id}"
|
||||
exported = await langflow.export_flow(langflow_flow_id)
|
||||
flow_name = name or exported.get("name") or f"langflow-{langflow_flow_id}"
|
||||
langflow_json = {
|
||||
"id": export.get("id", langflow_flow_id),
|
||||
"id": exported.get("id", langflow_flow_id),
|
||||
"name": flow_name,
|
||||
"description": export.get("description") or "",
|
||||
"endpoint_name": export.get("endpoint_name"),
|
||||
"data": export.get("data", {}),
|
||||
"tags": export.get("tags", []),
|
||||
"webhook": export.get("webhook", False),
|
||||
"is_component": export.get("is_component", False),
|
||||
"description": exported.get("description") or "",
|
||||
"endpoint_name": exported.get("endpoint_name"),
|
||||
"data": exported.get("data", {}),
|
||||
"tags": exported.get("tags", []),
|
||||
"webhook": exported.get("webhook", False),
|
||||
"is_component": exported.get("is_component", False),
|
||||
}
|
||||
try:
|
||||
definition = next(
|
||||
d for d in store.list_definitions(session) if d.name == flow_name
|
||||
)
|
||||
except StopIteration:
|
||||
definition = store.create_definition(
|
||||
session, FlowDefinitionCreate(name=flow_name)
|
||||
)
|
||||
version = store.create_version(
|
||||
path = export.write_flow_file(settings.flows_dir, langflow_json, name=flow_name)
|
||||
definition, version, _action = await sync.sync_document(
|
||||
session,
|
||||
definition.id,
|
||||
FlowVersionCreate(langflow_json=langflow_json, author=author),
|
||||
lfx,
|
||||
langflow_json,
|
||||
source_filename=path.name,
|
||||
author=author,
|
||||
deploy=deploy,
|
||||
)
|
||||
if deploy:
|
||||
uploaded = await lfx.upload_flow(
|
||||
version.langflow_json, flow_id=str(version.id), replace=True
|
||||
)
|
||||
version = store.mark_deployed(session, version, uploaded.id)
|
||||
assert version is not None # sync_document always versions on import
|
||||
return definition, version
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue