fix(mcp): fix dashboard owners Pydantic crash and preserve chart preview filters (#38987)

This commit is contained in:
Amin Ghadersohi
2026-04-01 19:18:28 +02:00
committed by GitHub
parent 5f99d613a0
commit 190f1a59c5
2 changed files with 34 additions and 1 deletions

View File

@@ -39,10 +39,32 @@ from superset.mcp_service.chart.schemas import (
PerformanceMetadata,
UpdateChartPreviewRequest,
)
from superset.utils import json as utils_json
logger = logging.getLogger(__name__)
def _get_old_adhoc_filters(form_data_key: str) -> list[Dict[str, Any]] | None:
"""Retrieve adhoc_filters from the previously cached form_data."""
from superset.commands.exceptions import CommandException
from superset.commands.explore.form_data.get import GetFormDataCommand
from superset.commands.explore.form_data.parameters import CommandParameters
try:
cmd_params = CommandParameters(key=form_data_key)
cached_data = GetFormDataCommand(cmd_params).run()
if cached_data:
if isinstance(cached_data, str):
cached_data = utils_json.loads(cached_data)
if isinstance(cached_data, dict):
adhoc_filters = cached_data.get("adhoc_filters")
if adhoc_filters:
return adhoc_filters
except (KeyError, ValueError, TypeError, CommandException):
logger.debug("Could not retrieve old form_data for filter preservation")
return None
@tool(
tags=["mutate"],
class_permission_name="Chart",
@@ -81,6 +103,16 @@ def update_chart_preview(
)
new_form_data.pop("_mcp_warnings", None)
# Preserve adhoc filters from the previous cached form_data
# when the new config doesn't explicitly specify filters
if (
getattr(request.config, "filters", None) is None
and request.form_data_key
):
old_adhoc_filters = _get_old_adhoc_filters(request.form_data_key)
if old_adhoc_filters:
new_form_data["adhoc_filters"] = old_adhoc_filters
# Generate new explore link with updated form_data
explore_url = generate_explore_link(request.dataset_id, new_form_data)

View File

@@ -566,8 +566,9 @@ def serialize_dashboard_object(dashboard: Any) -> DashboardInfo:
else None,
chart_count=len(getattr(dashboard, "slices", [])),
owners=[
UserInfo.model_validate(owner, from_attributes=True)
info
for owner in getattr(dashboard, "owners", [])
if (info := serialize_user_object(owner)) is not None
]
if getattr(dashboard, "owners", None)
else [],