Field Annotations¶
The annotations control how a field is loaded, generated or derived from external data.
They are expressed directly on the pydantic model attributes, inside Annotated[...].
See also
Structure & polymorphism in the Model Development Guide shows how to choose between these annotations when adding a field. This page is the behavior reference.
Overview¶
In FLYNC a field can stray away from standard yaml serialization by being:
External - the value is read from or written to a separate file / folder.
Implied - the value is not stored but calculated on the fly using a defined strategy.
Reference - the value is a key naming an object that was loaded elsewhere.
All three are frozen dataclasses in flync.core.annotations, together with the strategy
enums that refine them:
NamingStrategy- how the external file / folder is named.OutputStrategy- how the external representation is organized (single file vs folder).ImpliedStrategy- how an implied field is calculated.ReferenceStrategy- how a reference is stored and resolved.
Important
Import them from flync.core.annotations. The package re-exports everything, and
importing from the defining submodules invites circular imports.
Using External in a model¶
from typing import Annotated
from pydantic import Field
from flync.core.annotations import External, NamingStrategy, OutputStrategy
from flync.core.base_models import FLYNCBaseModel
class FLYNCModel(FLYNCBaseModel):
ecus: Annotated[
list[ECU],
External(
output_structure=OutputStrategy.FOLDER,
naming_strategy=NamingStrategy.FIELD_NAME,
),
]
metadata: Annotated[
SystemMetadata,
External(
output_structure=OutputStrategy.SINGLE_FILE | OutputStrategy.OMMIT_ROOT,
naming_strategy=NamingStrategy.FIXED_PATH,
path="system_metadata",
),
]
External takes four fields:
path- location of the external resource relative to the current component. Left empty, it is derived fromnaming_strategy.root- re-bases the location on a directory other than the parent’s; used withOutputStrategy.FIXED_ROOT.output_structure- anIntFlag, so members combine with|:Member
Effect
FOLDER(alias ofAUTO, the default)creates a directory containing one file per item
SINGLE_FILEcreates one
<name>.flync.yamlOMMIT_ROOTsuppresses the wrapper key inside the written file
FIXED_ROOTresolves the path against
rootinstead of the parentnaming_strategy-FIELD_NAME(alias ofAUTO, the default) derives the name from the field name;FIXED_PATHuses the explicitpath.
Using Implied in a model¶
from flync.core.annotations import Implied, ImpliedStrategy
class Controller(FLYNCBaseModel):
name: Annotated[str, Implied(strategy=ImpliedStrategy.FOLDER_NAME)] = Field()
When the model is instantiated, flync computes name from the surrounding path:
ImpliedStrategy.FOLDER_NAME(alias ofAUTO, the default) - the containing directory’s name, used for identifiers that follow the directory layout.ImpliedStrategy.FILE_NAME- the file’s own name.
Using Reference in a model¶
A reference field is a string in YAML and an object in Python. The public field holds
the key; a private attribute named by source holds the resolved model, wired in during
workspace resolution and exposed through a property.
from flync.core.annotations import Reference
class ECUPortToXConnection(InternalConnection):
ecu_port_name: Annotated[str, Reference(source="_ecu_port")] = Field(alias="ecu_port")
_ecu_port: ECUPort | None = None
@property
def ecu_port(self) -> ECUPort | None:
return self._ecu_port
Reference takes:
source- name of the private attribute holding the referenced model object.source_key- attribute on the referenced model whose value is the key written back. Defaults to"name"; set it when objects are identified by something else.reference_strategy-PRIVATE_ATTR(alias ofAUTO, the default).
resolve_reference() returns the concrete object a
field’s annotation points at, accepting either the Python name or the alias.
Combining annotations¶
A field can be declared as either External or Implied - they are mutually exclusive.
If both are needed, split the logic into separate helper properties. Reference is orthogonal
and may be combined with Field constraints, as SOMEIPServiceDeployment.service does.
Key points¶
Choose the appropriate
NamingStrategyto control file naming.Use
OutputStrategy.FOLDERwhen a field naturally maps to multiple files (e.g. controllers).ImpliedStrategy.FOLDER_NAMEis handy for identifiers that follow the directory layout.The annotation on a field is the repository layout a config author sees - the expected tree is documented at Writing a FLYNC config. Changing one changes the other.