Source code for multimodal_fin.utils.logging

"""
Logging utilities for the multimodal_fin package.

Provides a standardized logger with timestamps and log levels.
"""

import logging
from typing import List, Tuple, Optional

# Default logger for this module (used if none is provided explicitly)
_default_logger = None

[docs] def get_logger(name: str) -> logging.Logger: """Create and configure a logger for a given module or component. Ensures a consistent logging format and level across the package. Args: name (str): Name of the logger (typically use __name__). Returns: logging.Logger: A configured logger instance. """ logger = logging.getLogger(name) if not logger.handlers: handler = logging.StreamHandler() formatter = logging.Formatter( fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S" ) handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.INFO) logger.propagate = False return logger
[docs] def log_ensemble_prediction( model_outputs: List[Tuple[str, str, float]], final_label: str, final_confidence: float, logger: Optional[logging.Logger] = None, ): """ Logs the ensemble classification results in a clean, readable format. Args: model_outputs (List[Tuple[str, str, float]]): Tuples (model_name, predicted_label, confidence). final_label (str): Final combined prediction label. final_confidence (float): Final confidence (0 to 100). logger (Optional[logging.Logger]): Logger to use. If None, uses default package logger. """ if logger is None: global _default_logger if _default_logger is None: _default_logger = get_logger("multimodal_fin") logger = _default_logger lines = [ "========== Ensemble Classification ==========", *(f"Model {name:<14}{label} ({conf:.2f}%)" for name, label, conf in model_outputs), "", f"✅ Final prediction: {final_label} | Combined confidence: {final_confidence:.2f}%", "============================================\n" ] logger.info("\n" + "\n".join(lines))