Validation API

The FLYNC SDK exposes a Python API for validating workspaces and individual nodes programmatically. This is the foundation for CI/CD pipelines, tooling integrations, and language server diagnostics.

All functions return a DiagnosticsResult that captures the validation state, per-document errors, the loaded model, and the workspace instance.

Tip

For a quick sanity-check from the command line, you can also use the validate_workspace helper script instead of the Python API.


Imports

from flync.sdk.helpers.validation_helpers import (
    validate_workspace,
    validate_external_node,
    validate_node,
)
from flync.sdk.helpers.nodes_helpers import (
    available_flync_nodes,
    type_from_input,
)
from flync.sdk.context.diagnostics_result import DiagnosticsResult, WorkspaceState

DiagnosticsResult

Every validation function returns a DiagnosticsResult.

class DiagnosticsResult(state: WorkspaceState, errors: dict[str, list[ErrorDetails]], model: FLYNCBaseModel | None = None, workspace: FLYNCWorkspace | None = None)

Bases: object

Result of a workspace or node validation operation.

Attributes:

state (WorkspaceState): The overall validation state. errors (dict[str, list[ErrorDetails]]): Mapping of document URIs to

their associated Pydantic validation error details.

model (Optional[FLYNCBaseModel]): The validated root model, or

None if validation failed.

workspace (Optional[FLYNCWorkspace]): The loaded workspace instance,

or None if the workspace could not be created.

state: WorkspaceState
errors: dict[str, list[ErrorDetails]]
model: FLYNCBaseModel | None = None
workspace: FLYNCWorkspace | None = None
serialize_workspace(value: FLYNCWorkspace) str

Serialize the workspace to a compact string representation.

Args:

value (FLYNCWorkspace): The workspace to serialize.

Returns:
str: A human-readable string with the workspace name and relative

path.

class WorkspaceState(*values)

Bases: str, Enum

Enumeration of possible workspace validation states.

Attributes:

UNKNOWN: State has not been determined. EMPTY: No model was loaded; the workspace is empty. LOADING: The workspace is currently being loaded. VALID: All documents validated successfully with no errors. WARNING: Validation completed but some documents have non-fatal errors. INVALID: The model could not be constructed due to validation errors. BROKEN: An unexpected exception occurred during loading.

UNKNOWN = 'unknown'
EMPTY = 'empty'
LOADING = 'loading'
VALID = 'valid'
WARNING = 'warning'
INVALID = 'invalid'
BROKEN = 'broken'

Reading results

result = validate_workspace("/path/to/workspace")

# Check overall state
if result.state == WorkspaceState.VALID:
    print("All good!", result.model)

elif result.state == WorkspaceState.WARNING:
    # Model was created but some documents have non-fatal errors
    for doc_uri, errors in result.errors.items():
        for err in errors:
            print(f"[{doc_uri}] {err['msg']} @ {err['loc']}")

elif result.state in (WorkspaceState.INVALID, WorkspaceState.BROKEN):
    print("Validation failed:", result.errors)

Discovering Node Paths

Before validating a specific node you need to know its path in the model hierarchy. Use available_flync_nodes() to list every node reachable from a root model together with the dot-separated paths through which they can be accessed.

available_flync_nodes(root_node: str | type[FLYNCBaseModel] | None = <class 'flync.model.flync_model.FLYNCModel'>) dict[str, NodeInfo]

Return metadata for all nodes reachable from a root model.

Args:
root_node (str | type[FLYNCBaseModel] | None): The root model class
or its name. Defaults to

FLYNCModel.

Returns:

dict[str, NodeInfo]: Mapping of class names to NodeInfo objects describing each node in the dependency graph.

Example

from flync.sdk.helpers.nodes_helpers import available_flync_nodes

nodes = available_flync_nodes()   # defaults to FLYNCModel as root

for name, info in nodes.items():
    print(f"{name}:")
    print(f"  type  : {info.python_type}")
    print(f"  paths : {info.flync_paths}")

Example output:

FLYNCModel:
  type  : <class 'flync.model.flync_model.FLYNCModel'>
  paths : []
EcuConfig:
  type  : <class 'flync.model.ecu.ecu_config.EcuConfig'>
  paths : ['ecus.{}']
ControllerConfig:
  type  : <class 'flync.model.ecu.controller.ControllerConfig'>
  paths : ['ecus.{}.controllers.[]']

The paths list uses {} for dict keys and [] for list indices. These correspond directly to the segments you pass to validate_node().

You can also scope the query to a subtree by passing a different root:

from flync.model.ecu.ecu_config import EcuConfig

ecu_nodes = available_flync_nodes(EcuConfig)

Validating a Full Workspace

validate_workspace() validates an entire workspace directory against the default FLYNCModel.

validate_workspace(workspace_path: str | Path, workspace_config: WorkspaceConfiguration | None = None) DiagnosticsResult

Validate an entire FLYNC workspace rooted at the default FLYNCModel.

Args:

workspace_path (str | Path): Path to the workspace directory. workspace_config (WorkspaceConfiguration | None): Optional workspace

configuration. Uses defaults if None.

Returns:

DiagnosticsResult: The validation outcome including state, errors, and the loaded model.

Example

result = validate_workspace("/path/to/my_config")

if result.state == WorkspaceState.VALID:
    model = result.model          # fully constructed FLYNCModel
    workspace = result.workspace  # FLYNCWorkspace with all objects

else:
    for doc, errors in result.errors.items():
        for err in errors:
            print(err["msg"], err["loc"])

Validating an External Node

An external node is any model type that is stored in its own directory, separate from the workspace root. Use validate_external_node() when you want to validate a subtree in isolation — for example, a single ECU directory — without loading the entire workspace.

validate_external_node(node: str | type[FLYNCBaseModel], node_path: Path | str, workspace_config: WorkspaceConfiguration | None = None) DiagnosticsResult

Validate a specific FLYNC node type at a given filesystem path.

Loads the node using a fresh workspace configured with node as the root model, then inspects per-document errors to determine the overall WorkspaceState.

Args:
node (str | type[FLYNCBaseModel]): The model class to validate, or

its string name.

node_path (Path | str): Path to the directory containing the node’s

FLYNC configuration files.

workspace_config (WorkspaceConfiguration | None): Optional workspace

configuration. Uses defaults if None. The root_model field is always overwritten with node.

Returns:

DiagnosticsResult: Validation outcome with state, per-document errors, the loaded model, and the workspace instance.

The node argument can be either the model class itself or its string name as returned by available_flync_nodes().

Example — using a type

from flync.model.ecu.ecu_config import EcuConfig
from flync.sdk.helpers.validation_helpers import validate_external_node

result = validate_external_node(EcuConfig, "/path/to/ecus/my_ecu")

if result.state == WorkspaceState.VALID:
    ecu = result.model   # EcuConfig instance

Example — using a string name

result = validate_external_node("EcuConfig", "/path/to/ecus/my_ecu")

Validating a Partial (In-Workspace) Node

validate_node() validates the entire workspace first, then extracts and returns the model for a specific node identified by its dot-separated path.

Use this when you already have a workspace loaded and want to focus on a single node — for instance in a language server hover or diagnostic request.

validate_node(ws_path: Path | str, node_path: str = '', workspace_config: WorkspaceConfiguration | None = None) DiagnosticsResult

Validate a single node within an already-loaded workspace.

First validates the full workspace, then checks that the node at node_path exists and extracts its model. If the node is missing, a fatal validation error is recorded.

Args:

ws_path (Path | str): Path to the workspace root directory. node_path (str): Dot-separated path to the target node within the

workspace object graph.

workspace_config (WorkspaceConfiguration | None): Optional workspace

configuration forwarded to validate_workspace().

Returns:

DiagnosticsResult: Validation outcome for the specified node.

The node_path is the dot-separated object path within the workspace. You can discover valid paths with available_flync_nodes() (see Discovering Node Paths) or by inspecting objects on an already-loaded workspace.

Path syntax reference

Segment

Meaning

Example

field_name

Named attribute on a model

ecus

{}

Dictionary key (wildcard in schema paths)

ecus.my_ecu

[]

List index (wildcard in schema paths)

ecus.my_ecu.controllers.0

Example

from flync.sdk.helpers.validation_helpers import validate_node

# Validate the controller at index 0 inside "my_ecu"
result = validate_node(
    ws_path="/path/to/my_config",
    node_path="ecus.my_ecu.controllers.0",
)

if result.state == WorkspaceState.VALID:
    controller = result.model
else:
    print("Node errors:", result.errors)

Note

When node_path does not exist in the loaded workspace, validate_node() sets the state to INVALID and records a fatal error under the given node_path key.


Node metadata reference

class NodeInfo(name: str, python_type: Type, flync_paths: list[str] = <factory>)

Bases: object

Metadata for a node in the FLYNC model dependency graph.

Attributes:

name (str): Human-readable name of the node (typically the class name). python_type (Type): The Python type (usually a Pydantic model class)

that this node represents.

flync_paths (list[str]): Dot-separated paths from the root model to

this node through the dependency graph.

name: str
python_type: Type
flync_paths: list[str] = FieldInfo(annotation=NoneType, required=False, default_factory=list)
serialize_type(value: Type) str

Serialize the Python type to its string representation.

Args:

value (Type): The type to serialize.

Returns:

str: The string form of the type.


Function reference

validate_workspace(workspace_path: str | Path, workspace_config: WorkspaceConfiguration | None = None) DiagnosticsResult

Validate an entire FLYNC workspace rooted at the default FLYNCModel.

Args:

workspace_path (str | Path): Path to the workspace directory. workspace_config (WorkspaceConfiguration | None): Optional workspace

configuration. Uses defaults if None.

Returns:

DiagnosticsResult: The validation outcome including state, errors, and the loaded model.

validate_external_node(node: str | type[FLYNCBaseModel], node_path: Path | str, workspace_config: WorkspaceConfiguration | None = None) DiagnosticsResult

Validate a specific FLYNC node type at a given filesystem path.

Loads the node using a fresh workspace configured with node as the root model, then inspects per-document errors to determine the overall WorkspaceState.

Args:
node (str | type[FLYNCBaseModel]): The model class to validate, or

its string name.

node_path (Path | str): Path to the directory containing the node’s

FLYNC configuration files.

workspace_config (WorkspaceConfiguration | None): Optional workspace

configuration. Uses defaults if None. The root_model field is always overwritten with node.

Returns:

DiagnosticsResult: Validation outcome with state, per-document errors, the loaded model, and the workspace instance.

validate_node(ws_path: Path | str, node_path: str = '', workspace_config: WorkspaceConfiguration | None = None) DiagnosticsResult

Validate a single node within an already-loaded workspace.

First validates the full workspace, then checks that the node at node_path exists and extracts its model. If the node is missing, a fatal validation error is recorded.

Args:

ws_path (Path | str): Path to the workspace root directory. node_path (str): Dot-separated path to the target node within the

workspace object graph.

workspace_config (WorkspaceConfiguration | None): Optional workspace

configuration forwarded to validate_workspace().

Returns:

DiagnosticsResult: Validation outcome for the specified node.

available_flync_nodes(root_node: str | type[FLYNCBaseModel] | None = <class 'flync.model.flync_model.FLYNCModel'>) dict[str, NodeInfo]

Return metadata for all nodes reachable from a root model.

Args:
root_node (str | type[FLYNCBaseModel] | None): The root model class
or its name. Defaults to

FLYNCModel.

Returns:

dict[str, NodeInfo]: Mapping of class names to NodeInfo objects describing each node in the dependency graph.

type_from_input(node: str | type[FLYNCBaseModel]) type[FLYNCBaseModel]

Resolve a node identifier to its Python type.

Accepts either a string class name (looked up in the global dependency graph) or a type directly.

Args:

node (str | type[FLYNCBaseModel]): A model class or its string name.

Returns:

type[FLYNCBaseModel]: The resolved model class.