mirror of
https://github.com/apache/superset.git
synced 2026-05-29 20:29:34 +00:00
fix(mcp): defer chart preview command imports (#40164)
This commit is contained in:
committed by
GitHub
parent
59b5f69627
commit
1e2d0b5f5b
@@ -26,7 +26,6 @@ import logging
|
||||
import math
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from superset.commands.chart.data.get_data_command import ChartDataCommand
|
||||
from superset.mcp_service.chart.schemas import (
|
||||
ASCIIPreview,
|
||||
ChartError,
|
||||
@@ -78,6 +77,7 @@ def generate_preview_from_form_data(
|
||||
"""
|
||||
try:
|
||||
# Execute query to get data
|
||||
from superset.commands.chart.data.get_data_command import ChartDataCommand
|
||||
from superset.connectors.sqla.models import SqlaTable
|
||||
from superset.extensions import db
|
||||
|
||||
|
||||
@@ -19,6 +19,47 @@
|
||||
Tests for preview_utils query context column building.
|
||||
"""
|
||||
|
||||
import ast
|
||||
import inspect
|
||||
from pathlib import Path
|
||||
|
||||
from superset.mcp_service.chart import preview_utils
|
||||
|
||||
|
||||
def _imports_chart_data_command(node: ast.Import | ast.ImportFrom) -> bool:
|
||||
blocked_module = "superset.commands.chart.data.get_data_command"
|
||||
|
||||
if isinstance(node, ast.Import):
|
||||
return any(
|
||||
alias.name == blocked_module or alias.name.startswith(f"{blocked_module}.")
|
||||
for alias in node.names
|
||||
)
|
||||
|
||||
module = node.module or ""
|
||||
return (
|
||||
module == blocked_module
|
||||
or module.startswith(f"{blocked_module}.")
|
||||
or (
|
||||
module == "superset.commands.chart.data"
|
||||
and any(alias.name == "get_data_command" for alias in node.names)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_preview_utils_does_not_top_level_import_chart_data_command():
|
||||
"""preview_utils constants should stay safe to import before app setup."""
|
||||
source_path = inspect.getsourcefile(preview_utils) or preview_utils.__file__
|
||||
source = Path(source_path).read_text(encoding="utf-8")
|
||||
tree = ast.parse(source)
|
||||
top_level_imports = [
|
||||
node for node in tree.body if isinstance(node, (ast.Import, ast.ImportFrom))
|
||||
]
|
||||
|
||||
assert preview_utils.SUPPORTED_FORM_DATA_PREVIEW_FORMATS == frozenset(
|
||||
{"ascii", "table", "vega_lite"}
|
||||
)
|
||||
assert not any(_imports_chart_data_command(node) for node in top_level_imports)
|
||||
|
||||
|
||||
class TestPreviewUtilsColumnBuilding:
|
||||
"""Tests for x_axis + groupby column building in generate_preview_from_form_data.
|
||||
|
||||
@@ -1007,12 +1007,12 @@ class TestChartDataCommandValidation:
|
||||
mock_dataset = MagicMock()
|
||||
mock_dataset.id = 10
|
||||
|
||||
# ChartDataCommand is module-level import in preview_utils;
|
||||
# db and QueryContextFactory are local imports inside the function.
|
||||
# ChartDataCommand, db, and QueryContextFactory are local imports inside
|
||||
# the function so preview_utils stays safe to import before app setup.
|
||||
with (
|
||||
patch("superset.extensions.db") as mock_db,
|
||||
patch(
|
||||
"superset.mcp_service.chart.preview_utils.ChartDataCommand",
|
||||
"superset.commands.chart.data.get_data_command.ChartDataCommand",
|
||||
return_value=mock_command,
|
||||
),
|
||||
patch(
|
||||
@@ -1061,7 +1061,7 @@ class TestChartDataCommandValidation:
|
||||
with (
|
||||
patch("superset.extensions.db") as mock_db,
|
||||
patch(
|
||||
"superset.mcp_service.chart.preview_utils.ChartDataCommand",
|
||||
"superset.commands.chart.data.get_data_command.ChartDataCommand",
|
||||
return_value=mock_command,
|
||||
),
|
||||
patch(
|
||||
|
||||
Reference in New Issue
Block a user