Model Serialization¶
Overview¶
When serializing FLYNC models to YAML, JSON, or other formats, certain Literal-typed discriminator fields may be excluded from the output if they have default values and were not explicitly set during model creation.
This guide explains how to properly dump FLYNC models to ensure discriminators are included in the serialized output.
The Problem¶
Pydantic v2 tracks which fields were explicitly set on a model instance via model_fields_set. During serialization with model_dump(), by default all fields are included. However, when custom logic excludes unset fields or when downstream code expects discriminators to be present, Literal fields with defaults may appear missing.
Example:
class LINMasterInterfaceConfig(FLYNCBaseModel):
node_type: Literal["master"] = Field(default="master") # Has default
bus_ref: str = Field()
# When created, node_type is not in model_fields_set:
config = LINMasterInterfaceConfig(bus_ref="CAN1")
# config.model_fields_set might not contain "node_type"
Solution: Use dump_model_with_discriminators¶
The SDK provides a utility function that ensures discriminator fields are always included:
from flync.sdk.utils.model_dumper import dump_model_with_discriminators
# Correct way to dump FLYNC models
data = dump_model_with_discriminators(model)
yaml.dump(data, output_file)
How It Works¶
Graph Lookup (O(1)): Uses the pre-built
ModelDependencyGraph(constructed once at startup) to identify which fields are discriminatorsMark as Set: Temporarily marks those fields in
model_fields_setbefore dumpingSafe Fallback: If the graph is not available, silently skips marking (no error)
Performance¶
First call: Slightly slower (initializes graph lookup if needed)
Subsequent calls: O(1) lookup from cached graph, negligible overhead
Memory: No additional memory per instance; uses shared graph
Usage in Converters¶
All converters should use this utility when dumping models.
For FLYNCConverter¶
from flync.sdk.utils.model_dumper import dump_model_with_discriminators
# In encode method:
def encode(self, source: FLYNCModel):
data = dump_model_with_discriminators(source, exclude=...)
# ... write to files
For SDK Workspace¶
In flync_workspace.py, replace:
# Old:
content = flync_model.model_dump(exclude=exclude, exclude_unset=...)
# New:
content = dump_model_with_discriminators(
flync_model,
exclude=exclude,
exclude_unset=...
)
When to Use¶
Always use when dumping models for output (files, APIs, serialization)
Skip for internal operations that don’t care about discriminators
Safe to use everywhere—fallback behavior handles edge cases
Example¶
from flync.sdk.utils.model_dumper import dump_model_with_discriminators
from flync.model import FLYNCModel
# Load or create a model
model = FLYNCModel(...)
# Dump with discriminators included
output_dict = dump_model_with_discriminators(model)
# Now discriminator fields are guaranteed to be in output_dict
# even if they have default values
Architecture¶
Core: No changes. FLYNCBaseModel stays clean.
SDK: Handles discriminator marking via
dump_model_with_discriminatorsGraph: Provides O(1) lookup of discriminator fields, computed once at startup
This design keeps the core model lightweight while leveraging SDK infrastructure for specialized output requirements.