From c506f2fe4dbb1544e59b604d3de735d3e2ebf65b Mon Sep 17 00:00:00 2001 From: Eric Onofrey Date: Thu, 5 Feb 2026 20:06:04 -0800 Subject: [PATCH] Handle GraphViz objects in storage and UI (#4855) Summary: In [analysis_card_to_sqa](https://www.internalfb.com/code/fbsource/[f35aae2adf7e14e81702f0f3cd5584af5ce363fd]/fbcode/ax/storage/sqa_store/encoder.py?lines=1161-1171) we support every type of AnalysisCard except GraphViz. This diff has small additions to encoding and decoding for `GraphVizAnalysisCard` so `GenerationStrategyGraph` can be properly stored and rendered in the UI since currently it does not render: {F1985181889} Reviewed By: Cesar-Cardoso Differential Revision: D92208435 --- ax/storage/sqa_store/decoder.py | 10 ++++++++++ ax/storage/sqa_store/encoder.py | 3 +++ 2 files changed, 13 insertions(+) diff --git a/ax/storage/sqa_store/decoder.py b/ax/storage/sqa_store/decoder.py index 3ba9ef21be3..92628b093f3 100644 --- a/ax/storage/sqa_store/decoder.py +++ b/ax/storage/sqa_store/decoder.py @@ -13,6 +13,7 @@ from typing import Any, Callable, cast, Union import pandas as pd +from ax.analysis.graphviz.graphviz_analysis import GraphvizAnalysisCard from ax.analysis.healthcheck.healthcheck_analysis import HealthcheckAnalysisCard from ax.analysis.markdown.markdown_analysis import MarkdownAnalysisCard from ax.analysis.plotly.plotly_analysis import PlotlyAnalysisCard @@ -1118,6 +1119,15 @@ def analysis_card_from_sqa( blob=blob, timestamp=analysis_card_sqa.timestamp, ) + if blob_annotation == "graphviz": + return GraphvizAnalysisCard( + name=analysis_card_sqa.name, + title=title, + subtitle=subtitle, + df=read_json(StringIO(analysis_card_sqa.dataframe_json)), + blob=blob, + timestamp=analysis_card_sqa.timestamp, + ) return AnalysisCard( name=analysis_card_sqa.name, title=title, diff --git a/ax/storage/sqa_store/encoder.py b/ax/storage/sqa_store/encoder.py index 16b7a58b043..00a9568caa7 100644 --- a/ax/storage/sqa_store/encoder.py +++ b/ax/storage/sqa_store/encoder.py @@ -10,6 +10,7 @@ from logging import Logger from typing import Any, cast +from ax.analysis.graphviz.graphviz_analysis import GraphvizAnalysisCard from ax.analysis.healthcheck.healthcheck_analysis import HealthcheckAnalysisCard from ax.analysis.markdown.markdown_analysis import MarkdownAnalysisCard from ax.analysis.plotly.plotly_analysis import PlotlyAnalysisCard @@ -1167,6 +1168,8 @@ def analysis_card_to_sqa( blob_annotation = "markdown" elif isinstance(card, HealthcheckAnalysisCard): blob_annotation = "healthcheck" + elif isinstance(card, GraphvizAnalysisCard): + blob_annotation = "graphviz" else: blob_annotation = "dataframe"