File indexing completed on 2026-08-12 08:24:55
0001 """
0002 Configuration inspection commands for AID2E CLI.
0003
0004 Core commands for examining, describing, and validating configuration files:
0005 - describe: Quick summary with auto-detection
0006 - inspect: Detailed inspection with section filtering
0007 - validate: Syntax and structure validation
0008 """
0009
0010 import sys
0011 from typing import Optional
0012
0013 import click
0014 import yaml
0015
0016 from aid2e.utilities.configurations import FullConfig, load_config
0017 from ._helpers import (
0018 detect_config_type,
0019 count_parameters,
0020 format_description_text,
0021 extract_description_data,
0022 inspect_full_config,
0023 inspect_problem_config,
0024 inspect_design_config,
0025 )
0026
0027
0028 @click.command()
0029 @click.argument("config_file", type=click.Path(exists=True))
0030 @click.option("--format", type=click.Choice(["text", "json", "yaml"]), default="text", help="Output format")
0031 @click.option("--compact", is_flag=True, help="Show compact summary")
0032 def describe(config_file: str, format: str, compact: bool):
0033 """
0034 Describe the contents and structure of a configuration file.
0035
0036 Automatically detects config type (design/problem/optimizer/full)
0037 and displays relevant information in a human-readable format.
0038
0039 Examples:
0040 aid2e describe config.yml
0041 aid2e describe design.params --compact
0042 aid2e describe config.yml --format json
0043 """
0044 try:
0045
0046 with open(config_file) as f:
0047 data = yaml.safe_load(f)
0048
0049
0050 config_type = detect_config_type(data)
0051
0052 if format == "text":
0053 format_description_text(data, config_type, compact, config_file)
0054 elif format == "json":
0055 import json
0056 description = extract_description_data(data, config_type)
0057 click.echo(json.dumps(description, indent=2))
0058 elif format == "yaml":
0059 description = extract_description_data(data, config_type)
0060 click.echo(yaml.dump(description, default_flow_style=False))
0061
0062 except Exception as e:
0063 click.echo(click.style(f"✗ Error: {e}", fg="red"), err=True)
0064 sys.exit(1)
0065
0066
0067 @click.command(name="inspect")
0068 @click.argument("config_file", type=click.Path(exists=True))
0069 @click.option("--section", type=click.Choice(["problem", "optimizer", "design", "all"]), default="all", help="Section to inspect")
0070 def inspect(config_file: str, section: str):
0071 """
0072 Display detailed information about a configuration file.
0073
0074 Provides comprehensive view of configuration with optional section filtering.
0075
0076 Examples:
0077 aid2e inspect config.yml
0078 aid2e inspect config.yml --section optimizer
0079 aid2e inspect config.yml --section design
0080 """
0081 try:
0082
0083 with open(config_file) as f:
0084 raw_data = yaml.safe_load(f)
0085
0086 config_type = detect_config_type(raw_data)
0087
0088
0089 if config_type == "full":
0090 config = load_config(config_file)
0091 inspect_full_config(config, section)
0092 elif config_type == "problem":
0093 from aid2e.utilities.configurations import ProblemConfigLoader
0094 config = ProblemConfigLoader.load(config_file)
0095 inspect_problem_config(config)
0096 elif config_type == "design":
0097 from aid2e.utilities.configurations import DesignConfigLoader
0098 config = DesignConfigLoader.load(config_file)
0099 inspect_design_config(config)
0100 else:
0101
0102 click.echo(click.style(f"Configuration Type: {config_type}", bold=True))
0103 click.echo(yaml.dump(raw_data, default_flow_style=False))
0104
0105 except Exception as e:
0106 click.echo(click.style(f"✗ Error: {e}", fg="red"), err=True)
0107 sys.exit(1)
0108
0109
0110 @click.command()
0111 @click.argument("config_file", type=click.Path(exists=True))
0112 def validate(config_file: str):
0113 """
0114 Validate a configuration file without loading full context.
0115
0116 Checks syntax, required fields, and structural correctness.
0117
0118 Examples:
0119 aid2e validate config.yml
0120 aid2e validate design.params
0121 """
0122 try:
0123
0124 with open(config_file) as f:
0125 data = yaml.safe_load(f)
0126
0127 config_type = detect_config_type(data)
0128
0129 click.echo(f"Validating {config_type} configuration...")
0130
0131
0132 if config_type == "full":
0133 config = load_config(config_file)
0134 elif config_type == "problem":
0135 from aid2e.utilities.configurations import ProblemConfigLoader
0136 config = ProblemConfigLoader.load(config_file)
0137 elif config_type == "design":
0138 from aid2e.utilities.configurations import DesignConfigLoader
0139 config = DesignConfigLoader.load(config_file)
0140 elif config_type == "optimizer":
0141 from aid2e.utilities.configurations import OptimizerConfiguration
0142 opt = data.get("optimizer", data)
0143 config = OptimizerConfiguration(**opt)
0144 else:
0145 click.echo(click.style("⚠ Unknown configuration type, performing basic YAML validation only", fg="yellow"))
0146 click.echo(click.style("✓ YAML syntax is valid", fg="green"))
0147 return
0148
0149 click.echo(click.style("✓ Configuration is valid!", fg="green", bold=True))
0150 click.echo(f" Type: {config_type}")
0151
0152 if config_type in ["full", "problem"]:
0153 param_count = len(config.problem.design_config.get_parameter_names() if config_type == "full" else config.design_config.get_parameter_names())
0154 click.echo(f" Parameters: {param_count}")
0155
0156 except Exception as e:
0157 click.echo(click.style(f"✗ Validation failed: {e}", fg="red", bold=True), err=True)
0158 sys.exit(1)