ConfigValidator#
- class bamengine.config.validator.ConfigValidator[source]#
Bases:
objectCentralized validation for simulation configuration.
All validation happens once at Simulation.init() to ensure:
Type correctness
Valid parameter ranges
Relationship constraints between parameters
Clear error messages with actionable feedback
This class is stateless and uses only static methods. All validation logic is centralized here rather than scattered across the codebase.
Examples
Validate a complete configuration:
>>> from bamengine.config import ConfigValidator >>> cfg = { ... "n_firms": 100, ... "n_households": 500, ... "h_rho": 0.1, ... "beta": 2.5, ... } >>> ConfigValidator.validate_config(cfg) # No exception = valid
Validate only types:
>>> cfg = {"n_firms": 100, "h_rho": 0.1} >>> ConfigValidator._validate_types(cfg) # Valid
>>> cfg = {"n_firms": "100"} >>> ConfigValidator._validate_types(cfg) ValueError: Config parameter 'n_firms' must be int, got str
Validate only ranges:
>>> cfg = {"h_rho": 0.5} >>> ConfigValidator._validate_ranges(cfg) # Valid
>>> cfg = {"h_rho": 1.5} >>> ConfigValidator._validate_ranges(cfg) ValueError: Config parameter 'h_rho' must be <= 1.0, got 1.5
Notes
The ConfigValidator ensures validation happens once, upfront, rather than during simulation execution. This provides better error messages and avoids runtime overhead.
See also
ConfigConfiguration dataclass validated by this class
bamengine.simulation.Simulation.initEntry point that triggers validation
- VALID_LOG_LEVELS = {'CRITICAL', 'DEBUG', 'ERROR', 'INFO', 'TRACE', 'WARNING'}#
- static validate_config(cfg)[source]#
Validate all configuration parameters.
This is the main entry point for configuration validation. It runs all validation checks in sequence: types, ranges, relationships, and logging.
- Parameters:
cfg (
dict) – Configuration dictionary to validate. Should contain simulation parameters like n_firms, n_households, h_rho, etc.- Raises:
ValueError – If any validation check fails (type error, out of range, invalid pipeline/logging config).
Examples
Valid configuration passes silently:
>>> from bamengine.config import ConfigValidator >>> cfg = {"n_firms": 100, "h_rho": 0.1, "beta": 2.5} >>> ConfigValidator.validate_config(cfg) # No exception
Invalid type raises ValueError:
>>> cfg = {"n_firms": "100"} >>> ConfigValidator.validate_config(cfg) ValueError: Config parameter 'n_firms' must be int, got str
Out of range raises ValueError:
>>> cfg = {"h_rho": 1.5} >>> ConfigValidator.validate_config(cfg) ValueError: Config parameter 'h_rho' must be <= 1.0, got 1.5
Notes
This method is called by Simulation.init() before any initialization occurs, ensuring fail-fast behavior with clear error messages.
See also
_validate_typesType checking for configuration parameters
_validate_rangesRange validation for configuration parameters
_validate_relationshipsCross-parameter constraint validation
_validate_loggingLogging configuration validation
- static validate_pipeline_path(pipeline_path)[source]#
Validate pipeline path exists and is readable.
Checks that the given path points to an existing, readable file. Issues warning if file doesn’t have .yml or .yaml extension.
- Parameters:
pipeline_path (
str) – Path to pipeline YAML file.- Raises:
ValueError – If path does not exist or is not a file.
- Warns:
UserWarning – If file doesn’t have .yml or .yaml extension.
Examples
Valid path passes silently:
>>> from bamengine.config import ConfigValidator >>> import tempfile >>> from pathlib import Path >>> with tempfile.NamedTemporaryFile(suffix=".yml", delete=False) as f: ... f.write(b"events: []") ... path = f.name >>> ConfigValidator.validate_pipeline_path(path) >>> Path(path).unlink() # cleanup
Non-existent path raises ValueError:
>>> ConfigValidator.validate_pipeline_path("/nonexistent.yml") ValueError: Pipeline path '/nonexistent.yml' does not exist
Notes
This method only checks path validity, not YAML structure or event names. Use validate_pipeline_yaml() for full validation.
See also
validate_pipeline_yamlValidate pipeline YAML structure and events
- static validate_pipeline_yaml(yaml_path, params=None)[source]#
Validate pipeline YAML file structure and event references.
Checks that:
YAML is valid and has ‘events’ key
All event names exist in the registry
All parameter placeholders can be substituted
Event spec syntax is valid (repeat, interleave)
- Parameters:
yaml_path (
str) – Path to pipeline YAML file.params (
dict[str,int], optional) – Parameters available for substitution (e.g., {“max_M”: 4}). If None, no parameter substitution is performed.
- Raises:
ValueError – If YAML structure is invalid, references unknown events, or contains unsubstituted placeholders.
Examples
Valid pipeline YAML passes silently:
>>> from bamengine.config import ConfigValidator >>> import tempfile >>> from pathlib import Path >>> yaml_content = ''' ... events: ... - firms_decide_desired_production ... - labor_market_round x 4 ... ''' >>> with tempfile.NamedTemporaryFile( ... mode="w", suffix=".yml", delete=False ... ) as f: ... f.write(yaml_content) ... path = f.name >>> ConfigValidator.validate_pipeline_yaml(path) >>> Path(path).unlink() # cleanup
Unknown event raises ValueError:
>>> yaml_content = ''' ... events: ... - nonexistent_event ... ''' >>> with tempfile.NamedTemporaryFile( ... mode="w", suffix=".yml", delete=False ... ) as f: ... f.write(yaml_content) ... path = f.name >>> ConfigValidator.validate_pipeline_yaml(path) ValueError: Event 'nonexistent_event' not found in registry... >>> Path(path).unlink() # cleanup
Notes
This validation is called by Simulation.init() after path validation. It ensures all event names are registered before attempting to load the pipeline.
See also
validate_pipeline_pathValidate path exists
bamengine.core.pipeline.Pipeline.from_yamlLoads validated pipeline