Expand governed Dataflow editor and node library

This commit is contained in:
2026-07-28 11:14:01 +02:00
parent df468a2bd8
commit dee8380631
22 changed files with 3563 additions and 290 deletions
+58 -4
View File
@@ -5,6 +5,12 @@ from dataclasses import dataclass
from sqlalchemy import select
from sqlalchemy.orm import Session
from govoplan_core.auth import ApiPrincipal
from govoplan_core.core.tabular_sources import (
TabularReadRequest,
TabularSourceError,
tabular_source_provider,
)
from govoplan_core.db.base import utcnow
from govoplan_dataflow.backend.db.models import (
DataflowPipeline,
@@ -14,6 +20,7 @@ from govoplan_dataflow.backend.db.models import (
from govoplan_dataflow.backend.executor import (
EXECUTOR_VERSION,
PipelineExecutionError,
ResolvedSource,
execute_preview,
)
from govoplan_dataflow.backend.graph import canonical_graph_payload, definition_hash, validate_graph
@@ -333,6 +340,8 @@ def preview_pipeline(
tenant_id: str,
actor_id: str | None,
payload: PipelinePreviewRequest,
principal: ApiPrincipal | None = None,
registry: object | None = None,
) -> PipelinePreviewResponse:
pipeline: DataflowPipeline | None = None
revision: DataflowPipelineRevision | None = None
@@ -360,6 +369,8 @@ def preview_pipeline(
truncated=False,
diagnostics=validated.diagnostics,
node_diagnostics=[],
source_fingerprints=[],
input_row_count=0,
definition_hash="",
executor_version=EXECUTOR_VERSION,
)
@@ -370,7 +381,47 @@ def preview_pipeline(
started_at = utcnow()
run: DataflowRun | None = None
try:
result = execute_preview(graph, row_limit=payload.row_limit)
provider = tabular_source_provider(registry)
def resolve_source(node: GraphNode, limit: int) -> ResolvedSource:
if provider is None:
raise PipelineExecutionError(
"Connector-backed preview requires the Connectors tabular-source capability.",
node_id=node.id,
)
if principal is None:
raise PipelineExecutionError(
"Connector-backed preview requires a tenant API principal.",
node_id=node.id,
)
try:
resolved = provider.read_source(
session,
principal,
request=TabularReadRequest(
source_ref=str(node.config["source_ref"]),
limit=limit,
expected_fingerprint=_clean_optional(
node.config.get("expected_fingerprint")
),
),
)
except TabularSourceError as exc:
raise PipelineExecutionError(str(exc), node_id=node.id) from exc
return ResolvedSource(
rows=tuple(dict(row) for row in resolved.rows),
source_ref=resolved.source.ref,
provider=resolved.source.provider,
fingerprint=resolved.source.fingerprint,
total_rows=resolved.total_rows,
truncated=resolved.truncated,
)
result = execute_preview(
graph,
row_limit=payload.row_limit,
source_resolver=resolve_source,
)
status = "succeeded"
error = None
diagnostics = result.diagnostics
@@ -385,6 +436,7 @@ def preview_pipeline(
status = "failed"
error = str(exc)
diagnostics = [
*exc.diagnostics,
DataflowDiagnostic(
severity="error",
code="preview.execution",
@@ -396,9 +448,9 @@ def preview_pipeline(
rows = []
total_rows = 0
truncated = False
node_diagnostics = []
source_fingerprints = []
input_row_count = 0
node_diagnostics = list(exc.node_diagnostics)
source_fingerprints = list(exc.source_fingerprints)
input_row_count = exc.input_row_count
if pipeline is not None and revision is not None:
run = DataflowRun(
@@ -433,6 +485,8 @@ def preview_pipeline(
truncated=truncated,
diagnostics=diagnostics,
node_diagnostics=node_diagnostics,
source_fingerprints=source_fingerprints,
input_row_count=input_row_count,
definition_hash=graph_hash,
executor_version=EXECUTOR_VERSION,
)