Workspace Configuration

The WorkspaceConfiguration class controls how a FLYNC workspace is loaded, validated, and serialized. It defines file extensions, object mapping behavior, serialization options, the root model, and version tracking.

A workspace can carry its own configuration on disk, in a .flync/config.yaml file at the workspace root. The workspace is then self-describing: it is loaded the same way by every tool, and there is no need to rebuild the same WorkspaceConfiguration in a script each time the workspace is opened.

Overview

Every workspace has a configuration that controls:

  • file extensions: Which files are recognized as FLYNC configuration files

  • object mapping: Whether the workspace maps all objects (performance tradeoff)

  • serialization: How fields are excluded when unset

  • version: FLYNC version used to create the configuration (tracking only, see below)

The root_model field is part of the configuration object but is deliberately not part of the file. See The Root Model Is Not Configurable From File.

Note

version records the FLYNC release that last wrote the file, so future releases can migrate older configuration files. When a newer FLYNC rewrites a workspace the stamp moves forward, because the file is then in that newer release’s format; it is never moved backwards. It is not checked when a configuration is loaded; no compatibility is enforced today.

Configuration File Format

Convention: .flync/config.yaml in the workspace root

myproject/
  .flync/
    config.yaml
  my_ecu.flync.yaml

.flync/ is the single directory FLYNC tooling persists into, and is meant to be committed alongside the workspace.

File Structure:

# Only non-default values are serialized
version:
  version_schema: pep440
  version: 0.0.0

exclude_unset: false
map_objects: true
allowed_extensions:
  - .flync.yaml
  - .flync.yml
  - .safety.yaml

list_objects_mode:
  - INDEX
  - NAME

Auto-Discovery:

When calling FLYNCWorkspace.load_workspace() without an explicit workspace_config parameter:

workspace = FLYNCWorkspace.load_workspace(
        workspace_name="myproject",
        workspace_path="/path/to/project"
        # .flync/config.yaml is auto-discovered from /path/to/project/
)

If .flync/config.yaml exists, it’s loaded. Otherwise, defaults are used.

The Root Model Is Not Configurable From File

root_model is the only configuration field that is programmatic-only. It is set by the host application in code (the SDK, the REST server, the language server, a script) and is:

  • never written to .flync/config.yaml

  • rejected when present in .flync/config.yaml

  • rejected when given as a module path string, e.g. WorkspaceConfiguration(root_model="my.module.MyModel")

The reason is that resolving a class named in a file means importing it, which means executing code that ships inside a workspace. FLYNC workspaces are exchanged between suppliers and OEMs, so a workspace is treated strictly as data. Opening one never imports anything from it and never modifies sys.path.

A consequence is that a custom root model set in code is not restored when the workspace is reopened; the loading application must supply it again:

config = WorkspaceConfiguration(root_model=MyRootModel)  # class, never a string
workspace = FLYNCWorkspace.load_workspace("myproject", "/path/to/project", config)

Configuration Resolution Priority

When loading a workspace, configurations are resolved in this order (highest to lowest priority):

  1. Explicit config object passed to load_workspace(workspace_config=config_obj)

  2. Explicit config file path (str or Path) passed to load_workspace(workspace_config="path/to/config.yaml")

  3. Auto-discovered .flync/config.yaml in workspace root

  4. Default WorkspaceConfiguration()

If an explicit config object is passed, both the file path and auto-discovered file are ignored.

Persisting Configuration

Configuration is automatically saved when calling generate_configs():

workspace = FLYNCWorkspace.load_workspace("myproject", "/path/to/project")
# ... modify workspace and models ...
workspace.generate_configs()  # Persists configuration to .flync/config.yaml

To explicitly save without saving the full workspace:

workspace.save_workspace_config()  # Saves to workspace_root/.flync/config.yaml (creating .flync/ if needed)

Suppressing the configuration file:

Not every directory a workspace is written to should receive FLYNC tooling files. Generated or converted output, scratch directories, and workspaces whose configuration file is maintained by hand are all cases where the implicit write is unwanted. Set persist_config to opt out:

# For the lifetime of the workspace
config = WorkspaceConfiguration(persist_config=False)
workspace = FLYNCWorkspace.load_workspace("myproject", "/path/to/project", config)
workspace.generate_configs()  # writes the FLYNC documents, no .flync/config.yaml

# Or for a single call
workspace.generate_configs(persist_config=False)

The per-call argument wins over the configuration field in both directions, so generate_configs(persist_config=True) forces the write even when the field is False.

persist_config governs only this implicit write. save_workspace_config() asks for the file directly and always produces it, regardless of the flag. Because the field itself is persisted, a workspace whose .flync/config.yaml contains persist_config: false keeps that file untouched across saves - which is how a hand-maintained configuration file is protected from being rewritten.

Default Exclusion:

Only non-default values are serialized to YAML:

# Default values (not saved)
exclude_unset: true
map_objects: false
persist_config: true
list_objects_mode:
  - INDEX
  - NAME

# Always saved (version is always included, stamped from the running FLYNC release)
version:
  version_schema: pep440
  version: 0.0.0

Configuration Fields

flync_file_extension (str)

Primary file extension for FLYNC files. Default: .flync.yaml

allowed_extensions (set[str])

File extensions recognized as FLYNC files. Default: {".flync.yaml", ".flync.yml"}

exclude_unset (bool)

When True, fields not explicitly set on models are omitted from serialized output. Default: True

root_model (Type[FLYNCBaseModel])

The Pydantic model class used to validate workspace contents. Set in code only: it is never serialized and cannot be read from a configuration file (see The Root Model Is Not Configurable From File). Default: FLYNCModel

map_objects (bool)

When True, the workspace maps all objects (improves lookup speed but increases memory). Default: False

list_objects_mode (ListObjectsMode)

Controls how list items are keyed in workspace object map. Supports INDEX and/or NAME flags. Default: INDEX | NAME

persist_config (bool)

When True, saving the whole workspace with generate_configs() also writes this configuration to .flync/config.yaml. Set it to False for output directories that should contain nothing but the generated FLYNC files, or to protect a hand-maintained configuration file from being rewritten. Only the implicit write is suppressed: save_workspace_config() always writes. Default: True

version (BaseVersion)

FLYNC release that last wrote this configuration. Auto-detects the installed version, falling back to 0.0.0 when the distribution metadata is unavailable. On save the stamp is advanced to the running release if that is newer than the recorded one, and left alone otherwise (including when the recorded version uses a different version_schema, which makes the two incomparable). Default: current FLYNC version (PEP 440 format)

Error Handling

Programmatic-only field set in a file:

ValueError: /path/to/.flync/config.yaml: root_model cannot be set from a configuration file.
It is supplied by the host application in code so that opening a workspace never imports code it names.

Unknown key (typo) in a file:

ValidationError: 1 validation error for WorkspaceConfiguration
map_object
  Extra inputs are not permitted

YAML file not found:

FileNotFoundError: Configuration file not found: /path/to/.flync/config.yaml

Invalid configuration format:

ValidationError: 1 validation error for WorkspaceConfiguration
version
  Input should be a valid dictionary or instance of BaseVersion

API Reference

class WorkspaceConfiguration(*, flync_file_extension: str = '.flync.yaml', allowed_extensions: set[str] = {'.flync.yaml', '.flync.yml'}, exclude_unset: bool = True, root_model: Type[FLYNCBaseModel] = <class 'flync.model.flync_model.FLYNCModel'>, map_objects: bool = False, list_objects_mode: ListObjectsMode = <ListObjectsMode.INDEX|NAME: 3>, persist_config: bool = True, version: BaseVersion = <factory>)

Bases: BaseModel

Configuration object for the FLYNC SDK workspace.

A workspace can store this configuration on disk as .flync/config.yaml in its root (see from_workspace() and to_yaml_file()), so the workspace is self-describing and the same settings do not have to be rebuilt in a script every time it is opened.

The persisted file only ever carries plain data. Fields listed in NON_PERSISTED_FIELDS (currently root_model) are set by the host application in code and are rejected when present in a configuration file.

Attributes:

flync_file_extension (str): The primary file extension used when writing FLYNC configuration files. Defaults to ".flync.yaml". allowed_extensions (set[str]): Set of file extensions recognized as FLYNC files. Defaults to {".flync.yaml", ".flync.yml"}. exclude_unset (bool): When True, fields that were not explicitly set on a model are omitted from serialized output. root_model (Type[FLYNCBaseModel]): The root Pydantic model class used to validate workspace contents. Programmatic-only, never serialized. Defaults to FLYNCModel. map_objects (bool): tells the workspace if it should map all objects in the workspace (reduces performance). list_objects_mode (ListObjectsMode): Controls how objects are keyed when listed. Defaults to INDEX | NAME. Accepts int, list of flag names, or pipe-separated string. persist_config (bool): When True (the default), saving the whole workspace also writes this configuration to .flync/config.yaml. Set it to False for workspaces whose output directory should stay free of FLYNC tooling files - generated or converted output, scratch directories, or a workspace whose configuration file is maintained by hand. Only the implicit write is suppressed; to_yaml_file() still writes when called directly. version (BaseVersion): FLYNC release that last wrote this configuration. Auto-detects the current version by default. Always serialized, and moved forward (never backwards) when a newer FLYNC rewrites the file. Tracking only: it is recorded to support future migrations and is not enforced on load.

model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

flync_file_extension: str
allowed_extensions: set[str]
exclude_unset: bool
root_model: Type[FLYNCBaseModel]
map_objects: bool
list_objects_mode: ListObjectsMode
persist_config: bool
version: BaseVersion
classmethod validate_root_model(v: Any) → Any

Reject model class paths; only a real class is accepted.

classmethod validate_list_objects_mode(v: Any) → ListObjectsMode

Convert list/string formats to ListObjectsMode IntFlag.

serialize_list_objects_mode(v: ListObjectsMode) → list[str]

Serialize ListObjectsMode IntFlag to list of flag names for readability.

classmethod from_yaml_file(path: str | Path) → Self

Load WorkspaceConfiguration from a YAML file.

Args:

path: Path to YAML file (e.g., .flync/config.yaml).

Returns:

WorkspaceConfiguration instance with values from file.

Raises:

FileNotFoundError: If file doesn’t exist. ValueError: If YAML is invalid, contains an unknown key, or sets a programmatic-only field (see NON_PERSISTED_FIELDS).

Example:
>>> config = WorkspaceConfiguration.from_yaml_file(".flync/config.yaml")
classmethod from_workspace(workspace_path: str | Path) → Self

Resolve the base configuration for a workspace directory.

Loads CONFIG_RELPATH under the workspace root if it exists, otherwise returns defaults. This is the disk-backed base that server/runtime overrides layer on top of.

The file is read as plain data only: nothing in it is imported or executed, and the workspace directory is never added to sys.path.

to_yaml_file(path: str | Path) → None

Save WorkspaceConfiguration to a YAML file.

Only non-default values are written, making configs concise and readable. The version field is always serialized to track FLYNC compatibility. Programmatic-only fields (see NON_PERSISTED_FIELDS) are never written.

Args:

path: Path to write YAML file (e.g., .flync/config.yaml).

Example:
>>> config = WorkspaceConfiguration(map_objects=True)
>>> config.to_yaml_file(".flync/config.yaml")
classmethod create_from_config(existing_config: Self, **configs) → Self

Create a new configuration by overriding fields on an existing one.

Converts existing_config to a dict, applies configs on top, then constructs and returns a new WorkspaceConfiguration.

Args:

existing_config (WorkspaceConfiguration): The base configuration to copy from. configs: Field names and new values to override.

Returns:

WorkspaceConfiguration: A new instance with the overrides applied.

class ListObjectsMode(*values)

Bases: IntFlag

Flags controlling how list items are keyed in the workspace object map.

Flags can be combined with |. The default is INDEX | NAME.

Attributes:

INDEX: Register each list item under its zero-based integer index (e.g. controllers.0). NAME: Register each list item under its name — the file/directory stem for folder-based lists, or the model’s name attribute for inline YAML lists. Items without a name are skipped.

INDEX = 1
NAME = 2

See Also