Source code for ergodic_insurance.config.reporting

"""Output, logging, and reporting configuration.

Contains configuration classes that control where and how simulation results
are saved, logging behavior, and Excel report generation options.

Since:
    Version 0.9.0 (Issue #458)
"""

from pathlib import Path
from typing import Any, Dict, Literal, Optional

from pydantic import BaseModel, Field, field_validator


[docs] class OutputConfig(BaseModel): """Output and results configuration. Controls where and how simulation results are saved, including file formats and checkpoint frequencies. """ output_directory: str = Field(default="outputs", description="Directory for saving results") file_format: Literal["csv", "parquet", "json"] = Field( default="csv", description="Output file format" ) checkpoint_frequency: int = Field( ge=0, default=0, description="Save checkpoints every N years (0=disabled)" ) detailed_metrics: bool = Field(default=True, description="Include detailed metrics in output") @property def output_path(self) -> Path: """Get output directory as Path object. Returns: Path object for the output directory. """ return Path(self.output_directory)
[docs] class LoggingConfig(BaseModel): """Logging configuration. Controls logging behavior including level, output destinations, and message formatting. """ enabled: bool = Field(default=True, description="Enable logging") level: Literal["DEBUG", "INFO", "WARNING", "ERROR"] = Field( default="INFO", description="Logging level" ) log_file: Optional[str] = Field( default=None, description="Log file path (None=no file logging)" ) console_output: bool = Field(default=True, description="Log to console") format: str = Field( default="%(asctime)s - %(name)s - %(levelname)s - %(message)s", description="Log message format", )
[docs] class ExcelReportConfig(BaseModel): """Configuration for Excel report generation. This is the canonical definition used throughout the codebase. Both ``ExcelReporter`` and the unified config hierarchy (``Config``) use this class. Attributes: enabled: Whether Excel reporting is enabled. output_path: Directory for output files. include_balance_sheet: Whether to include balance sheet. include_income_statement: Whether to include income statement. include_cash_flow: Whether to include cash flow statement. include_reconciliation: Whether to include reconciliation sheet. include_metrics_dashboard: Whether to include metrics dashboard. include_pivot_data: Whether to include pivot-ready data sheet. formatting: Custom formatting options. engine: Excel engine to use ('xlsxwriter', 'openpyxl', 'auto', 'pandas'). currency_format: Currency format string. decimal_places: Number of decimal places for numbers. date_format: Date format string. """ enabled: bool = Field(default=True, description="Whether Excel reporting is enabled") output_path: Path = Field(default=Path("./reports"), description="Directory for Excel reports") include_balance_sheet: bool = Field(default=True, description="Include balance sheet") include_income_statement: bool = Field(default=True, description="Include income statement") include_cash_flow: bool = Field(default=True, description="Include cash flow statement") include_reconciliation: bool = Field(default=True, description="Include reconciliation report") include_metrics_dashboard: bool = Field(default=True, description="Include metrics dashboard") include_pivot_data: bool = Field(default=True, description="Include pivot-ready data") formatting: Optional[Dict[str, Any]] = Field( default=None, description="Custom formatting options" ) engine: str = Field(default="auto", description="Excel engine: xlsxwriter, openpyxl, or auto") currency_format: str = Field(default="$#,##0", description="Currency format string") decimal_places: int = Field(default=0, ge=0, le=10, description="Number of decimal places") date_format: str = Field(default="yyyy-mm-dd", description="Date format string")
[docs] @field_validator("engine") @classmethod def validate_engine(cls, v: str) -> str: """Validate Excel engine selection. Args: v: Engine name to validate. Returns: Validated engine name. Raises: ValueError: If engine is not valid. """ valid_engines = ["xlsxwriter", "openpyxl", "auto", "pandas"] if v not in valid_engines: raise ValueError(f"Invalid Excel engine: {v}. Must be one of {valid_engines}") return v