From de2d7712e85b9cb786fae604da1a1cbd8f4d5ed9 Mon Sep 17 00:00:00 2001 From: vitor-aignosi Date: Thu, 16 Apr 2026 14:43:25 -0300 Subject: [PATCH] feat: add project base path and template path handling in report generation - Introduced PROJECT_BASE_PATH constant for consistent project directory reference. - Updated Reports class to require template_path for loading HTML templates. - Modified DataManagerRepository to pass the new template_path when generating reports. --- model_manager/runtime_paths.py | 3 +++ model_manager/sientia/reports.py | 8 ++++++-- .../utils/repository/data_manager_repository.py | 13 +++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/model_manager/runtime_paths.py b/model_manager/runtime_paths.py index b65b701..e1d20ed 100644 --- a/model_manager/runtime_paths.py +++ b/model_manager/runtime_paths.py @@ -9,6 +9,9 @@ RUNTIME_DATA_ROOT = '/var/lib/model-manager' # Training reports (HTML, CSV exports, etc.) and related outputs. REPORTS_ROOT = join(RUNTIME_DATA_ROOT, 'reports') +# project base path +PROJECT_BASE_PATH = '/app/model_manager' + # Per-training run folders (name + timestamp); cleanup cron deletes stale entries here. REPORTS_TEMP_DIR = join(REPORTS_ROOT, 'temp') diff --git a/model_manager/sientia/reports.py b/model_manager/sientia/reports.py index 56296b0..fb28827 100644 --- a/model_manager/sientia/reports.py +++ b/model_manager/sientia/reports.py @@ -68,7 +68,7 @@ class Reports: """ def __init__( - self, reference_data: Any, current_data: Any, target_name: str, base_path: str | None = None + self, reference_data: Any, current_data: Any, target_name: str, base_path: str | None = None, template_path: str | None = None ) -> None: """ Initializes an instance of the AigReport class. @@ -87,6 +87,7 @@ class Reports: self.target_name = target_name self.set_color_options(primary_color='#0F4C81', secondary_color='#001E60') self.base_path = base_path + self.template_path = template_path def add_data_quality_section(self, columns: list[str] | None = None, run: bool = True) -> None: """ @@ -238,6 +239,9 @@ class Reports: if not self.base_path: raise ValueError('base_path is required to save all sections HTML') + if not self.template_path: + raise ValueError('template_path is required to save all sections HTML') + # Ensure output directory exists output_dir = os.path.dirname(report_path) if output_dir and not os.path.exists(output_dir): @@ -248,7 +252,7 @@ class Reports: print(f"Base path: {self.base_path}") # Load main HTML template - main_html_path = os.path.join(self.base_path, 'header.html') + main_html_path = os.path.join(self.template_path, 'header.html') main_html = load_html_from_file(main_html_path) # Load content from data_drift.html, data_quality.html, and regression.html diff --git a/model_manager/utils/repository/data_manager_repository.py b/model_manager/utils/repository/data_manager_repository.py index a87e7f5..152c41d 100644 --- a/model_manager/utils/repository/data_manager_repository.py +++ b/model_manager/utils/repository/data_manager_repository.py @@ -28,7 +28,7 @@ from sientia_do.observability.sientia_monitoring import SientiaMonitoring from sientia_do.temporal.constants import DATETIME_FORMAT_WITH_TZ from sientia_model.wrappers.sientia_model import SientiaModel -from model_manager.runtime_paths import REPORTS_ROOT +from model_manager.runtime_paths import REPORTS_ROOT, PROJECT_BASE_PATH from model_manager.sientia.metrics import mae, mse, r2 from model_manager.sientia.reports import Reports # type: ignore[import-untyped] from model_manager.utils.models.train_model_params import TrainModelParams @@ -473,8 +473,7 @@ class DataManagerRepository(SientiaMonitoring): OSError: If directory creation fails for any other reason. """ # Use microsecond precision to reduce collision probability - timestamp = datetime.now().strftime('%Y%m%d_%H%M%S_%f') - run_dir = path.join(base_path, 'temp', f'{run_name}_{timestamp}') + run_dir = path.join(base_path, 'temp', f'{run_name}') try: makedirs(run_dir, exist_ok=True) @@ -534,11 +533,17 @@ class DataManagerRepository(SientiaMonitoring): current_data_float = current_data.astype(np.float64) # Initialize report generator - data.run_dir = self._create_run_directory(self._get_reports_directory(), data.run_name) + base_path = self._get_reports_directory() + data.run_dir = self._create_run_directory(base_path, data.run_name) + + # Template path is the code path of the model_manager package + template_path = path.join(PROJECT_BASE_PATH, 'reports') + report = Reports( reference_data=reference_data_float, current_data=current_data_float, base_path=data.run_dir, + template_path=template_path, target_name=data.params.target_variable, )