From 2dd10645ff1ef7ba6665be8ca211e919be2eb531 Mon Sep 17 00:00:00 2001 From: Juan Date: Tue, 18 Feb 2025 11:16:52 +0100 Subject: [PATCH 1/5] Add check when result_id not in template --- validmind/vm_models/result/result.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/validmind/vm_models/result/result.py b/validmind/vm_models/result/result.py index 82da5edeb..75ba48092 100644 --- a/validmind/vm_models/result/result.py +++ b/validmind/vm_models/result/result.py @@ -440,6 +440,9 @@ def log(self, section_id: str = None, position: int = None, unsafe: bool = False unsafe (bool): If True, log the result even if it contains sensitive data i.e. raw data from input datasets """ + + self.check_result_id_exist() + if not unsafe: for table in self.tables or []: check_for_sensitive_data(table.data, self._get_flat_inputs()) @@ -448,3 +451,24 @@ def log(self, section_id: str = None, position: int = None, unsafe: bool = False self._validate_section_id_for_block(section_id, position) run_async(self.log_async, section_id=section_id, position=position) + + def check_result_id_exist(self) -> bool: + """Check if the result_id exists in any test block across all sections""" + api_client.reload() + client_config = api_client.client_config + + # Iterate through all sections + for section in client_config.documentation_template["sections"]: + blocks = section.get("contents", []) + # Check each block in the section + for block in blocks: + if ( + block.get("content_type") == "test" + and block.get("content_id") == self.result_id + ): + return True + + logger.info( + f"Test driven block with result_id {self.result_id} does not exist in document template" + ) + return False From fd3273f49ac4b37b1249cef1580f21103cd9fa73 Mon Sep 17 00:00:00 2001 From: Juan Date: Tue, 18 Feb 2025 11:32:35 +0100 Subject: [PATCH 2/5] Small refactoring --- validmind/vm_models/result/result.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/validmind/vm_models/result/result.py b/validmind/vm_models/result/result.py index 75ba48092..c32df588f 100644 --- a/validmind/vm_models/result/result.py +++ b/validmind/vm_models/result/result.py @@ -452,7 +452,7 @@ def log(self, section_id: str = None, position: int = None, unsafe: bool = False run_async(self.log_async, section_id=section_id, position=position) - def check_result_id_exist(self) -> bool: + def check_result_id_exist(self): """Check if the result_id exists in any test block across all sections""" api_client.reload() client_config = api_client.client_config @@ -466,9 +466,8 @@ def check_result_id_exist(self) -> bool: block.get("content_type") == "test" and block.get("content_id") == self.result_id ): - return True + return logger.info( f"Test driven block with result_id {self.result_id} does not exist in document template" ) - return False From fd27a100f49b424c96ccc0fa3c65d196da28f2d6 Mon Sep 17 00:00:00 2001 From: Juan Date: Wed, 19 Feb 2025 14:00:12 +0100 Subject: [PATCH 3/5] Add caching logic to client config reload --- validmind/vm_models/result/result.py | 52 ++++++++++++++++------------ 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/validmind/vm_models/result/result.py b/validmind/vm_models/result/result.py index c32df588f..a2620adff 100644 --- a/validmind/vm_models/result/result.py +++ b/validmind/vm_models/result/result.py @@ -171,6 +171,7 @@ class TestResult(Result): metadata: Optional[Dict[str, Any]] = None _was_description_generated: bool = False _unsafe: bool = False + _client_config_cache: Optional[Any] = None def __post_init__(self): if self.ref_id is None: @@ -329,13 +330,40 @@ def to_widget(self): return VBox(widgets) + @classmethod + def _get_client_config(cls): + """Get the client config, loading it if not cached""" + if cls._client_config_cache is None: + api_client.reload() + cls._client_config_cache = api_client.client_config + else: + return cls._client_config_cache + + def check_result_id_exist(self): + """Check if the result_id exists in any test block across all sections""" + client_config = self._get_client_config() + + # Iterate through all sections + for section in client_config.documentation_template["sections"]: + blocks = section.get("contents", []) + # Check each block in the section + for block in blocks: + if ( + block.get("content_type") == "test" + and block.get("content_id") == self.result_id + ): + return + + logger.info( + f"Test driven block with result_id {self.result_id} does not exist in model's document" + ) + def _validate_section_id_for_block( self, section_id: str, position: Union[int, None] = None ): """Validate the section_id exits on the template before logging""" - api_client.reload() + client_config = self._get_client_config() found = False - client_config = api_client.client_config for section in client_config.documentation_template["sections"]: if section["id"] == section_id: @@ -451,23 +479,3 @@ def log(self, section_id: str = None, position: int = None, unsafe: bool = False self._validate_section_id_for_block(section_id, position) run_async(self.log_async, section_id=section_id, position=position) - - def check_result_id_exist(self): - """Check if the result_id exists in any test block across all sections""" - api_client.reload() - client_config = api_client.client_config - - # Iterate through all sections - for section in client_config.documentation_template["sections"]: - blocks = section.get("contents", []) - # Check each block in the section - for block in blocks: - if ( - block.get("content_type") == "test" - and block.get("content_id") == self.result_id - ): - return - - logger.info( - f"Test driven block with result_id {self.result_id} does not exist in document template" - ) From 4dfd2754347d759cad2fc3b69044b81298f700b7 Mon Sep 17 00:00:00 2001 From: Juan Date: Wed, 19 Feb 2025 20:56:38 +0100 Subject: [PATCH 4/5] Add validation --- validmind/vm_models/result/result.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/validmind/vm_models/result/result.py b/validmind/vm_models/result/result.py index a2620adff..382a24996 100644 --- a/validmind/vm_models/result/result.py +++ b/validmind/vm_models/result/result.py @@ -336,8 +336,18 @@ def _get_client_config(cls): if cls._client_config_cache is None: api_client.reload() cls._client_config_cache = api_client.client_config - else: - return cls._client_config_cache + + if cls._client_config_cache is None: + raise ValueError( + "Failed to load client config: api_client.client_config is None" + ) + + if not hasattr(cls._client_config_cache, "documentation_template"): + raise ValueError( + "Invalid client config: missing documentation_template" + ) + + return cls._client_config_cache def check_result_id_exist(self): """Check if the result_id exists in any test block across all sections""" From f2e6dcf989658f0c0d12fab61a5c11de158856fe Mon Sep 17 00:00:00 2001 From: Juan Date: Wed, 19 Feb 2025 21:10:02 +0100 Subject: [PATCH 5/5] 2.8.10 --- pyproject.toml | 2 +- validmind/__version__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c42db1a9e..3a5b25455 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ description = "ValidMind Library" license = "Commercial License" name = "validmind" readme = "README.pypi.md" -version = "2.8.9" +version = "2.8.10" [tool.poetry.dependencies] python = ">=3.8.1,<3.12" diff --git a/validmind/__version__.py b/validmind/__version__.py index e71de367e..71322b8ca 100644 --- a/validmind/__version__.py +++ b/validmind/__version__.py @@ -1 +1 @@ -__version__ = "2.8.9" +__version__ = "2.8.10"