diff --git a/ax/analysis/healthcheck/healthcheck_analysis.py b/ax/analysis/healthcheck/healthcheck_analysis.py index 1f9589fd3b7..8f220c38396 100644 --- a/ax/analysis/healthcheck/healthcheck_analysis.py +++ b/ax/analysis/healthcheck/healthcheck_analysis.py @@ -26,6 +26,19 @@ def get_status(self) -> HealthcheckStatus: def is_passing(self) -> bool: return self.get_status() in (HealthcheckStatus.PASS, HealthcheckStatus.INFO) + def is_user_facing(self) -> bool: + """Returns True if this card should be displayed to users. + + User-facing cards: + - FAIL: Critical issues blocking the experiment + - WARNING: Potential issues that can lead to issues in the future + - INFO: Informational context and feature upsells + + Hidden cards: + - PASS: No issues, nothing noteworthy to display + """ + return self.get_status() != HealthcheckStatus.PASS + def get_aditional_attrs(self) -> dict[str, str | int | float | bool]: return json.loads(self.blob) diff --git a/ax/analysis/healthcheck/tests/test_healthcheck_analysis.py b/ax/analysis/healthcheck/tests/test_healthcheck_analysis.py new file mode 100644 index 00000000000..632676643b0 --- /dev/null +++ b/ax/analysis/healthcheck/tests/test_healthcheck_analysis.py @@ -0,0 +1,29 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +# pyre-strict + +import pandas as pd +from ax.analysis.healthcheck.healthcheck_analysis import ( + create_healthcheck_analysis_card, + HealthcheckStatus, +) +from ax.utils.common.testutils import TestCase + + +class TestHealthcheckAnalysisCard(TestCase): + def test_is_user_facing(self) -> None: + # Only PASS status should be hidden; all others are user-facing + for status in HealthcheckStatus: + with self.subTest(status=status.name): + card = create_healthcheck_analysis_card( + name="TestAnalysis", + title="Test Healthcheck", + subtitle="Test subtitle", + df=pd.DataFrame(), + status=status, + ) + expected = status != HealthcheckStatus.PASS + self.assertEqual(card.is_user_facing(), expected) diff --git a/ax/analysis/overview.py b/ax/analysis/overview.py index 67b18689e69..53b27427167 100644 --- a/ax/analysis/overview.py +++ b/ax/analysis/overview.py @@ -265,10 +265,11 @@ def compute( if analyis is not None ] - non_passing_health_checks = [ + user_facing_health_check_cards = [ card for card in health_check_cards - if (isinstance(card, HealthcheckAnalysisCard) and not card.is_passing()) + if isinstance(card, HealthcheckAnalysisCard) + and card.is_user_facing() or isinstance(card, ErrorAnalysisCard) ] @@ -277,9 +278,9 @@ def compute( name="HealthchecksAnalysis", title=HEALTH_CHECK_CARDGROUP_TITLE, subtitle=HEALTH_CHECK_CARDGROUP_SUBTITLE, - children=non_passing_health_checks, + children=user_facing_health_check_cards, ) - if len(non_passing_health_checks) > 0 + if len(user_facing_health_check_cards) > 0 else None )