Bases: BaseModel
A complete data flow diagram declaration.
Validates at construction:
1. At least one process
2. No duplicate element names across all lists
3. Flow source/target reference declared element names
4. No direct external-to-external flows
5. Every process has at least one connected flow
Source code in packages/gds-software/gds_software/dfd/model.py
| class DFDModel(BaseModel):
"""A complete data flow diagram declaration.
Validates at construction:
1. At least one process
2. No duplicate element names across all lists
3. Flow source/target reference declared element names
4. No direct external-to-external flows
5. Every process has at least one connected flow
"""
name: str
external_entities: list[ExternalEntity] = Field(default_factory=list)
processes: list[Process] = Field(default_factory=list)
data_stores: list[DataStore] = Field(default_factory=list)
data_flows: list[DataFlow] = Field(default_factory=list)
description: str = ""
@model_validator(mode="after")
def _validate_structure(self) -> Self:
errors: list[str] = []
# 1. At least one process
if not self.processes:
errors.append("DFD must have at least one process")
# 2. No duplicate names
all_names: list[str] = []
for e in self.external_entities:
all_names.append(e.name)
for p in self.processes:
all_names.append(p.name)
for d in self.data_stores:
all_names.append(d.name)
seen: set[str] = set()
for n in all_names:
if n in seen:
errors.append(f"Duplicate element name: {n!r}")
seen.add(n)
all_element_names = set(all_names)
# 3. Flow source/target reference declared elements
for flow in self.data_flows:
if flow.source not in all_element_names:
errors.append(
f"Flow {flow.name!r} source {flow.source!r} "
f"is not a declared element"
)
if flow.target not in all_element_names:
errors.append(
f"Flow {flow.name!r} target {flow.target!r} "
f"is not a declared element"
)
# 4. No direct external-to-external flows
ext_names = {e.name for e in self.external_entities}
for flow in self.data_flows:
if flow.source in ext_names and flow.target in ext_names:
errors.append(
f"Flow {flow.name!r} connects two external entities "
f"({flow.source!r} -> {flow.target!r})"
)
if errors:
raise SWValidationError(
f"DFDModel {self.name!r} validation failed:\n"
+ "\n".join(f" - {e}" for e in errors)
)
return self
# ── Convenience properties ──────────────────────────────
@property
def element_names(self) -> set[str]:
"""All element names in the model."""
names: set[str] = set()
for e in self.external_entities:
names.add(e.name)
for p in self.processes:
names.add(p.name)
for d in self.data_stores:
names.add(d.name)
return names
@property
def external_names(self) -> set[str]:
return {e.name for e in self.external_entities}
@property
def process_names(self) -> set[str]:
return {p.name for p in self.processes}
@property
def store_names(self) -> set[str]:
return {d.name for d in self.data_stores}
# ── Compilation ─────────────────────────────────────────
def compile(self) -> GDSSpec:
"""Compile this model to a GDS specification."""
from gds_software.dfd.compile import compile_dfd
return compile_dfd(self)
def compile_system(self) -> SystemIR:
"""Compile this model to a flat SystemIR for verification + visualization."""
from gds_software.dfd.compile import compile_dfd_to_system
return compile_dfd_to_system(self)
|
element_names
property
All element names in the model.
compile()
Compile this model to a GDS specification.
Source code in packages/gds-software/gds_software/dfd/model.py
| def compile(self) -> GDSSpec:
"""Compile this model to a GDS specification."""
from gds_software.dfd.compile import compile_dfd
return compile_dfd(self)
|
compile_system()
Compile this model to a flat SystemIR for verification + visualization.
Source code in packages/gds-software/gds_software/dfd/model.py
| def compile_system(self) -> SystemIR:
"""Compile this model to a flat SystemIR for verification + visualization."""
from gds_software.dfd.compile import compile_dfd_to_system
return compile_dfd_to_system(self)
|