Opinionated Configuration
Opinionated configuration means encoding project-specific rules and defaults once, then reusing them across all components that share those constraints. Instead of repeating the same parameter values or enforcing the same policy in every configuration script, you centralize the opinion in a dedicated class or function.
This page shows three patterns for applying opinionated configuration on top of the Forge facade API. Choose the pattern that best matches how your project is structured.
Pattern: Inheritance
Subclass an existing facade to provide a project-specific factory method. The subclass removes the choices that must not vary, exposes only the parameters that callers are allowed to customize, and enforces the rest internally.
This pattern is suitable when you want to replace the standard facade with a stricter type throughout your project.
from __future__ import annotations
from ves_socom.facades import ComDaemonFacade, LogLevel
class OpinionatedComDaemonFacade(ComDaemonFacade):
"""Project-specific facade that always enables IAM and IDSM."""
@staticmethod
def create_opinionated(name: str) -> OpinionatedComDaemonFacade:
base = ComDaemonFacade.create(
name,
log_level=LogLevel.INFO,
enable_console_log=False,
iam_required=True,
iam_config_file_path="./config/iam_cfg.json",
idsm_enabled=True,
telemetry_enabled=False,
)
return OpinionatedComDaemonFacade(base.name, base.data)
if __name__ == "__main__":
daemon = OpinionatedComDaemonFacade.create_opinionated("my_comdaemon")
# Continue building configuration as usual...
iam_required and idsm_enabled are no longer visible to callers—they are always True.
The rest of the configuration workflow is identical to the standard facade.
Pattern: Strategy
Create a strategy object that applies a transformation to an already-built facade instance. The strategy operates on the facade after it has been constructed, normalizing or enforcing rules across its children.
This pattern is suitable when the opinion applies to content that is added incrementally (such as ports or subnets), or when you want to apply the same rule to facades you did not create yourself.
from ves_socom.facades import ComDaemonFacade, IpPortType, IpProtocol, LogLevel
class UdpMixedDataIpPortStrategy:
"""Normalizes all data IP ports to UDP + Mixed."""
def apply(self, facade: ComDaemonFacade) -> None:
for subnet in facade.get_subnet_iterator():
for data_ip_port in subnet.get_data_ip_port_iterator():
data_ip_port.protocol = IpProtocol.UDP
data_ip_port.port_type = IpPortType.MIXED
if __name__ == "__main__":
daemon = ComDaemonFacade.create("my_comdaemon", log_level=LogLevel.DEBUG, idsm_enabled=True)
# ... add subnets and ports ...
UdpMixedDataIpPortStrategy().apply(daemon)
# All data IP ports are now UDP + Mixed regardless of how they were added.
Pattern: Configuration Object
Define a typed dataclass that holds all the opinion dimensions as fields with defaults. Pass an instance of this object to a factory function that creates the facade.
This pattern is suitable when the opinion has multiple independent dimensions that callers may need to vary independently, or when you want to make the opinion explicit and auditable in one place.
from dataclasses import dataclass
from ves_socom.facades import ComDaemonFacade, LogLevel
@dataclass(frozen=True)
class ComDaemonOpinionConfig:
"""Explicit opinion configuration for ComDaemon setup."""
log_level: LogLevel = LogLevel.INFO
enable_console_log: bool = False
iam_required: bool = True
iam_config_file: str = "./config/iam_cfg.json"
idsm_enabled: bool = True
telemetry_enabled: bool = False
tcp_maximum_message_size_bytes: int = 1500
def create_with_opinion(name: str, config: ComDaemonOpinionConfig) -> ComDaemonFacade:
return ComDaemonFacade.create(
name,
log_level=config.log_level,
enable_console_log=config.enable_console_log,
iam_required=config.iam_required,
iam_config_file_path=config.iam_config_file,
idsm_enabled=config.idsm_enabled,
telemetry_enabled=config.telemetry_enabled,
tcp_maximum_message_size_bytes=config.tcp_maximum_message_size_bytes,
)
if __name__ == "__main__":
# Use the defaults, or override individual fields as needed.
daemon = create_with_opinion("my_comdaemon", ComDaemonOpinionConfig())
# Continue building configuration as usual...
The dataclass instance can be stored in a shared constants module and imported wherever the same opinion is needed.