Skip to content

Commit 87ac9df

Browse files
shrutipatel31facebook-github-bot
authored andcommitted
Route AnalysisNotApplicableStateError to NotApplicableAnalysisCard (#5051)
Summary: Update error_card_from_analysis_e() in analysis.py to route AnalysisNotApplicableStateError exceptions to NotApplicableStateAnalysisCard instead of ErrorAnalysisCard. Reviewed By: bernardbeckerman Differential Revision: D96248248
1 parent 1becca4 commit 87ac9df

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

ax/analysis/analysis.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
AnalysisCardBase,
2020
AnalysisCardGroup,
2121
ErrorAnalysisCard,
22+
NotApplicableStateAnalysisCard,
2223
)
2324
from ax.core.experiment import Experiment
2425
from ax.exceptions.analysis import AnalysisNotApplicableStateError
@@ -29,6 +30,12 @@
2930

3031
logger: Logger = get_logger(__name__)
3132

33+
NOT_APPLICABLE_STATE_SUBTITLE: str = (
34+
"This analysis is temporarily unavailable. It will become available "
35+
"as your experiment progresses (e.g., after collecting more data, "
36+
"running more trials, or fitting a model)."
37+
)
38+
3239

3340
class Analysis(Protocol):
3441
"""
@@ -202,7 +209,7 @@ def display_cards(
202209

203210
def error_card_from_analysis_e(
204211
analysis_e: AnalysisE,
205-
) -> ErrorAnalysisCard:
212+
) -> ErrorAnalysisCard | NotApplicableStateAnalysisCard:
206213
analysis_name = analysis_e.analysis.__class__.__name__
207214
exception_name = analysis_e.exception.__class__.__name__
208215

@@ -213,6 +220,18 @@ def error_card_from_analysis_e(
213220
if (exception_message := str(analysis_e.exception))
214221
else f"{exception_name} encountered while computing {analysis_name}."
215222
)
223+
if isinstance(analysis_e.exception, AnalysisNotApplicableStateError):
224+
# AnalysisNotApplicableStateError gets rendered as a
225+
# NotApplicableStateAnalysisCard
226+
return NotApplicableStateAnalysisCard(
227+
name=analysis_name,
228+
title=f"{analysis_name} -- Not Available Yet",
229+
subtitle=NOT_APPLICABLE_STATE_SUBTITLE,
230+
df=pd.DataFrame(),
231+
blob=exception_message
232+
if exception_message
233+
else f"{exception_name} encountered.",
234+
)
216235

217236
return ErrorAnalysisCard(
218237
name=analysis_name,

ax/analysis/tests/test_analysis.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,51 @@
1+
#!/usr/bin/env python3
12
# Copyright (c) Meta Platforms, Inc. and affiliates.
23
#
34
# This source code is licensed under the MIT license found in the
45
# LICENSE file in the root directory of this source tree.
56

67
# pyre-strict
78

8-
from ax.analysis.analysis import AnalysisE, error_card_from_analysis_e
9+
from ax.analysis.analysis import (
10+
AnalysisE,
11+
error_card_from_analysis_e,
12+
NOT_APPLICABLE_STATE_SUBTITLE,
13+
)
914
from ax.analysis.plotly.parallel_coordinates import ParallelCoordinatesPlot
15+
from ax.core.analysis_card import ErrorAnalysisCard, NotApplicableStateAnalysisCard
16+
from ax.exceptions.analysis import AnalysisNotApplicableStateError
1017
from ax.utils.common.testutils import TestCase
1118

1219

1320
class AnalysisTest(TestCase):
1421
def test_error_card_from_analysis_e(self) -> None:
15-
for exception, expected_subtitle in (
22+
for (
23+
exception,
24+
expected_card_type,
25+
expected_title,
26+
expected_subtitle,
27+
expected_blob,
28+
) in (
1629
(
1730
ValueError("something went wrong"),
31+
ErrorAnalysisCard,
32+
"ParallelCoordinatesPlot Error",
1833
"ValueError: something went wrong",
34+
"ValueError",
1935
),
2036
(
2137
ValueError(),
38+
ErrorAnalysisCard,
39+
"ParallelCoordinatesPlot Error",
2240
"ValueError encountered while computing ParallelCoordinatesPlot.",
41+
"ValueError",
42+
),
43+
(
44+
AnalysisNotApplicableStateError("Experiment has no data."),
45+
NotApplicableStateAnalysisCard,
46+
"ParallelCoordinatesPlot -- Not Available Yet",
47+
NOT_APPLICABLE_STATE_SUBTITLE,
48+
"Experiment has no data.",
2349
),
2450
):
2551
with self.subTest(exception=exception):
@@ -31,7 +57,8 @@ def test_error_card_from_analysis_e(self) -> None:
3157

3258
card = error_card_from_analysis_e(analysis_e)
3359

60+
self.assertIsInstance(card, expected_card_type)
3461
self.assertEqual(card.name, "ParallelCoordinatesPlot")
35-
self.assertEqual(card.title, "ParallelCoordinatesPlot Error")
62+
self.assertEqual(card.title, expected_title)
3663
self.assertEqual(card.subtitle, expected_subtitle)
37-
self.assertIn("ValueError", card.blob)
64+
self.assertIn(expected_blob, card.blob)

ax/api/tests/test_client.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import numpy as np
1414
import pandas as pd
15+
from ax.analysis.analysis import NOT_APPLICABLE_STATE_SUBTITLE
1516
from ax.analysis.plotly.parallel_coordinates import ParallelCoordinatesPlot
1617
from ax.api.client import Client
1718
from ax.api.configs import (
@@ -1278,10 +1279,10 @@ def test_compute_analyses(self) -> None:
12781279

12791280
self.assertEqual(len(cards), 1)
12801281
self.assertEqual(cards[0].name, "ParallelCoordinatesPlot")
1281-
self.assertEqual(cards[0].title, "ParallelCoordinatesPlot Error")
1282+
self.assertEqual(cards[0].title, "ParallelCoordinatesPlot -- Not Available Yet")
12821283
self.assertEqual(
12831284
cards[0].subtitle,
1284-
"AnalysisNotApplicableStateError: Experiment has no trials.",
1285+
NOT_APPLICABLE_STATE_SUBTITLE,
12851286
)
12861287

12871288
for trial_index, _ in client.get_next_trials(max_trials=1).items():

0 commit comments

Comments
 (0)