Commit Graph

19855 Commits

Author SHA1 Message Date
Amin Ghadersohi
f5ba09f7af feat(mcp): add runtime chart plugin enable/disable via _PluginFilterConfig
Introduces a dynamic filter layer in the chart type registry so operators can
disable individual plugins (e.g. `handlebars`) without a code deploy:

- `MCP_DISABLED_CHART_PLUGINS: frozenset[str]` — static deny-list in mcp_config.py
- `MCP_CHART_PLUGIN_ENABLED_FUNC: Callable[[str], bool] | None` — dynamic hook
  for Harness/Split/per-user targeting; takes precedence over the deny-list
- Both keys are propagated through `get_mcp_config()` defaults

registry.py changes:
- `_PluginFilterConfig` frozen dataclass replaces two bare globals so
  configure() replaces them atomically (no torn reads under concurrency)
- `configure(disabled, enabled_func)` — called at app init; accepts any
  iterable for `disabled`; validates `enabled_func` is callable
- `_is_plugin_enabled()` — reads config once, fails closed on callable exception
- `get()` / `all_types()` / `is_enabled()` apply the filter at lookup time;
  `is_registered()` and `display_name_for_viz_type()` intentionally bypass it
  so callers can distinguish "unknown" vs "disabled" and existing charts still
  resolve display names for disabled viz types

schema_validator.py: two-step pre-check — `is_registered()` for unknown types,
`is_enabled()` for disabled ones, with distinct `DISABLED_CHART_TYPE` error code.

Wiring:
- `SupersetAppInitializer.configure_mcp_chart_registry()` called after
  `configure_feature_flags()` in `init_app()`
- `flask_singleton.py` re-calls `registry.configure()` after the MCP config
  overlay so MCP-specific overrides in `superset_config.py` take effect in
  standalone MCP mode

Tests: 28 cases in test_registry_filters.py covering deny-list, callable hook,
fail-closed on exception, all_types() filtering, display_name bypass, atomic
reconfigure, and configure() with list/tuple/frozenset inputs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:59:54 +00:00
Amin Ghadersohi
9d298f86f0 fix(mcp): fix E501 in update_chart.py and update_chart test mocks for column validation
Split an 89-char comment line and an over-limit condition in update_chart.py
to satisfy the ruff E501 rule. Also applied ruff format.

Two TestUpdateChartValidationGate tests expected CHART_VALIDATION_FAILED but
received CHART_DATASET_NOT_FOUND because _validate_update_against_dataset calls
DatasetValidator.validate_against_dataset before validate_and_compile, and the
existing mocks provided a Mock() object for chart.datasource whose .id attribute
is an auto-generated MagicMock (not a real int). Added a patch for
DatasetValidator.validate_against_dataset returning (True, None) so the
column-validation tier is bypassed and the test reaches the mocked
validate_and_compile response as intended.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 22:12:08 +00:00
Amin Ghadersohi
b34d346e0d refactor(mcp): address Codex review — fix registry bug, DRY schema hints, remove column regex
P1.1 registry.py: move _plugins_loaded=True to after successful import so a
failed load doesn't permanently poison the registry.

P1.3 schemas.py: remove overly restrictive ColumnRef.name / FilterClause.column
/ BigNumberChartConfig.temporal_column regex that blocked valid column names
containing parentheses, slashes, and other SQL-common characters.

P2.3 (DRY): eliminate _CHART_TYPE_ERROR_HINTS second-registry in
schema_validator.py by adding schema_error_hint() to ChartTypePlugin protocol,
BaseChartPlugin default, and all 7 plugin classes. SchemaValidator now delegates
to the plugin registry instead of maintaining a parallel dict.

P3.3 test_registry.py: add full registry unit-test coverage (register, get,
all_types, is_registered, display_name_for_viz_type, proxy methods, duplicate
warning, empty chart_type validation, insertion-order guarantee).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:27:39 +00:00
Amin Ghadersohi
18a9eff641 fix(mcp): add full column validation to update_chart
update_chart was only running SchemaValidator + Tier-2 compile check,
silently skipping DatasetValidator's column-existence + fuzzy-match
and column-name normalisation layers that generate_chart runs.

A typo like {name: "reveneu"} would save the broken chart and only
surface as a render-time failure in the browser.

Now matches generate_chart pipeline:
- Layer 2: DatasetValidator.validate_against_dataset() — column
  existence check with fuzzy-match "did you mean?" suggestions returned
  to the LLM before any DB write occurs
- Layer 4: DatasetValidator.normalize_column_names() — case
  normalisation so "order_date" resolves to "OrderDate" if that is the
  canonical dataset name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:14:32 +00:00
Amin Ghadersohi
eface3bf54 fix(mcp): add threading lock to registry plugin loader
_ensure_plugins_loaded() used an unprotected boolean flag, making it
unsafe under concurrent first-call scenarios (e.g. gunicorn multi-thread
workers). Double-checked locking with threading.Lock eliminates the race.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 17:40:10 +00:00
Amin Ghadersohi
b41a53bc8f fix(mcp): resolve E402 and E501 in dataset_validator.py
- Move error_schemas import above _C TypeVar definition (E402)
- Split two over-length comment lines to ≤88 chars (E501, lines 268 and 380)
2026-05-10 00:08:43 +00:00
Amin Ghadersohi
f1b95d6ae3 fix(mcp): resolve ruff E501 and formatting issues to pass pre-commit
- Split long string literal in schema_validator.py line 202 (E501, 94 > 88 chars)
- Apply ruff format auto-fixes to big_number.py, handlebars.py, and test_get_chart_data.py
2026-05-09 00:11:52 +00:00
Amin Ghadersohi
1e2b541600 refactor(mcp): move all local imports to top level in chart type plugins
All per-method local imports in the 7 chart plugins were moved to module-level.
None of them create circular imports: schemas.py, chart_utils.py, and
dataset_validator.py are safe to import at plugin load time because those
modules guard their own registry lookups with local imports.

- big_number: add map_big_number_config, _big_number_chart_what,
  _summarize_filters, DatasetValidator to top-level imports
- pie: add map_pie_config, _pie_chart_what, _summarize_filters, PieChartConfig,
  DatasetValidator to top-level imports
- xy: add map_xy_config, _xy_chart_what/context, XYChartConfig, DatasetValidator,
  FormatTypeValidator, CardinalityValidator to top-level imports
- table: add map_table_config, _table_chart_what, _summarize_filters,
  TableChartConfig, DatasetValidator to top-level imports
- pivot_table: add map_pivot_table_config, _pivot_table_what, _summarize_filters,
  PivotTableChartConfig, DatasetValidator to top-level imports
- mixed_timeseries: add map_mixed_timeseries_config, _mixed_timeseries_what,
  _summarize_filters, MixedTimeseriesChartConfig, DatasetValidator to top-level
- handlebars: add map_handlebars_config, _handlebars_chart_what, _summarize_filters,
  HandlebarsChartConfig, DatasetValidator to top-level imports

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 22:19:03 +00:00
Amin Ghadersohi
b16de3622f fix(mcp): address reviewer comments — local import rationale, x-optional corrections, cardinality suggestions
- Remove redundant local imports from BigNumberChartPlugin.post_map_validate()
  now that BigNumberChartConfig and is_column_truly_temporal are at top level
- Add explanatory comments on the two remaining local get_registry imports in
  chart_utils.py and dataset_validator.py (circular import prevention)
- Fix schema_validator.py and generate_chart.py docstring: XY 'x' field is
  optional (defaults to dataset primary datetime column), not required
- Propagate cardinality suggestions alongside warnings in XYChartPlugin
- Clarify app.py instructions: chart_type_display_name is null for viz_types
  outside the 7 generate_chart-supported types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 22:19:03 +00:00
Amin Ghadersohi
5e02d0ec65 refactor(mcp): complete plugin protocol — registry bootstrap, mypy fixes, test repairs
On top of the dead-code elimination in the previous commit:
- Add lazy _ensure_plugins_loaded() bootstrap to ChartTypeRegistry so the
  registry is populated even without importing app.py (fixes isolated test runs)
- Delegate _RegistryProxy methods to module-level functions so bootstrap runs
- Guard register() against empty chart_type strings
- Add generate_name + resolve_viz_type to ChartTypePlugin Protocol and
  BaseChartPlugin; delegate generate_chart_name/_resolve_viz_type in
  chart_utils to the plugin registry
- Add _with_context static helper to BaseChartPlugin (shared by all plugins)
- Fix stale 'five methods' → 'eight methods' docstring in plugin.py
- Add TypeVar _C to normalize_column_names so mypy infers correct return type
- Fix broken tests: update _pre_validate_big_number_config → _pre_validate_chart_type,
  remove deleted TestNormalizeXYConfig/TestNormalizeTableConfig classes,
  update runtime validator tests for removed _validate_format_compatibility /
  _validate_cardinality methods, add x is not None narrowing guards

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 22:19:03 +00:00
Amin Ghadersohi
139eea92f6 refactor(mcp): eliminate dead code and complete plugin registry dispatch
H1: Delete 7 dead _pre_validate_* static methods from SchemaValidator
    — exact duplicates of plugin pre_validate() methods, never called
    after _pre_validate_chart_type() was updated to delegate to plugin.

H2: Inline DatasetValidator._normalize_xy_config/_normalize_table_config
    into XYChartPlugin/TableChartPlugin.normalize_column_refs() and delete
    both DatasetValidator helper methods. The 5 other plugins already
    called _get_canonical_column_name directly; XY and Table now match.

H3: Add generate_name()/resolve_viz_type() to ChartTypePlugin protocol
    and BaseChartPlugin, implement in all 7 plugins. Replace the 7-arm
    isinstance chain in generate_chart_name() and the 7-arm elif chain
    in _resolve_viz_type() with single-line registry dispatch.

H4: Add a sync comment above _CHART_TYPE_ERROR_HINTS to document that
    it must stay in sync with the plugin registry.

M4: Move logger=logging.getLogger(__name__) from inside
    XYChartPlugin.get_runtime_warnings() to module scope.
2026-05-07 22:19:03 +00:00
Amin Ghadersohi
b09cbc80aa feat(mcp): add display_name and native_viz_types to chart type plugins
Each ChartTypePlugin now declares:
- display_name: human-readable label for the chart_type discriminator
  (e.g. "Line / Bar / Area / Scatter Chart", "Pivot Table")
- native_viz_types: dict mapping every Superset-internal viz_type the
  plugin produces to a user-friendly name
  (e.g. {"echarts_timeseries_line": "Line Chart", "echarts_area": "Area Chart"})

The registry gains display_name_for_viz_type(viz_type) which searches
all plugins' native_viz_types maps, replacing the need for a separate
viz_type_display_names.json or viz_type_names.py module.

ChartInfo gains a chart_type_display_name field populated via the registry,
so list_charts / get_chart_info return human-readable chart type names.
The MCP system instructions now reference display names rather than
internal viz_type identifiers.
2026-05-07 22:19:03 +00:00
Amin Ghadersohi
e7adf0c670 feat(mcp): introduce chart type plugin registry for extensible chart generation
Replaces four scattered dispatch locations (schema_validator, dataset_validator,
chart_utils, runtime validator) with a central ChartTypePlugin registry. Each of
the 7 supported chart types (xy, table, pie, pivot_table, mixed_timeseries,
handlebars, big_number) now owns its pre-validation, column extraction, form_data
mapping, post-map validation, column normalization, and runtime warnings in a
single plugin class.

Key changes:
- Add ChartTypePlugin protocol and BaseChartPlugin base class (plugin.py)
- Add ChartTypeRegistry with register/get/all_types helpers (registry.py)
- Add 7 chart type plugins under chart/plugins/ with full coverage
- Fix 5-type column validation gap: pie, pivot_table, mixed_timeseries, handlebars,
  and big_number now participate in dataset column validation (previously silently skipped)
- Move BigNumber trendline temporal check to BigNumberChartPlugin.post_map_validate()
- Add get_runtime_warnings() to plugin protocol; XYChartPlugin implements
  format/cardinality checks, removing isinstance(config, XYChartConfig) from RuntimeValidator
- Fix stale generate_chart.py docstring listing only 'xy' and 'table' chart types
- Add missing pie, pivot_table, mixed_timeseries handlers to _enhance_validation_error;
  refactor into a data-driven lookup table to stay within complexity limits
- Fix empty details fallback in Pydantic error handler
2026-05-07 22:19:03 +00:00
Vitor Avila
ad5e3170dd fix: OpenSearch dialect identifier delimiters (#39953) 2026-05-07 16:19:27 -03:00
Maxime Beauchemin
aa710672ed fix(ui): remove makeUrl() double-prefix bugs under subdirectory deployment (#39503)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Vitor Avila <96086495+Vitor-Avila@users.noreply.github.com>
2026-05-07 15:39:38 -03:00
Richard Fogaca Nienkotter
8c80caefa3 fix(explore): preserve preview chart name on save (#39908) 2026-05-07 13:08:28 -03:00
Richard Fogaca Nienkotter
8088c5d1de fix(dashboard): match auto-refresh paused-dot outline to icon color (#39909) 2026-05-07 13:07:52 -03:00
Amin Ghadersohi
9b520312a1 fix(mcp): use tiktoken for response-size-guard token estimation (#39912) 2026-05-07 11:51:31 -04:00
Amin Ghadersohi
9ac4711ac8 fix(mcp): prevent DetachedInstanceError in get_chart_preview (#39921) 2026-05-07 11:44:11 -04:00
dependabot[bot]
7593d2a164 chore(deps): bump caniuse-lite from 1.0.30001791 to 1.0.30001792 in /docs (#39933)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-07 21:57:29 +07:00
dependabot[bot]
d3c44e311e chore(deps): bump aws-actions/amazon-ecr-login from 2.1.4 to 2.1.5 (#39931)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-07 21:54:59 +07:00
Enzo Martellucci
b5186d1c65 fix(reports): keep body sized so standalone screenshots don't time out (#39944) 2026-05-07 12:26:50 +02:00
bdonovan1
5b5dd01028 fix(sqla): parenthesize calculated column expressions in WHERE clause (#39793)
Co-authored-by: Brian Donovan <briand@netflix.com>
Co-authored-by: Vitor Avila <96086495+Vitor-Avila@users.noreply.github.com>
2026-05-06 19:45:27 -03:00
bialkou
4aa4415d8f fix(i18n): update Russian translations (#39589)
Co-authored-by: bito-code-review[bot] <188872107+bito-code-review[bot]@users.noreply.github.com>
2026-05-06 13:05:23 -04:00
Sebastian Mohr
e667ceb6cf feat(themes): expose active theme mode via data-theme-mode attribute (#39063) 2026-05-06 18:17:54 +03:00
Enzo Martellucci
9aaa12c7d4 fix(reports): preserve urlParams in multi-tab report fan-out (#39884) 2026-05-06 16:29:45 +02:00
Alexandru Soare
adfbbf1433 fix(sql): quote identifiers in transpile_to_dialect to fix case-sensitive column filters (#39521) 2026-05-06 10:53:09 +03:00
dependabot[bot]
d7663a9a1c chore(deps-dev): update denodo-sqlalchemy requirement from ~=1.0.6 to >=1.0.6,<2.1.0 (#39832)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 22:17:21 -07:00
dependabot[bot]
7290d3c452 chore(deps-dev): update pyathena requirement from <3,>=2 to >=2,<4 (#39830)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 22:17:00 -07:00
dependabot[bot]
d7beffcec1 chore(deps-dev): bump eslint-plugin-react-you-might-not-need-an-effect from 0.9.3 to 0.10.0 in /superset-frontend (#39853)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 22:15:10 -07:00
dependabot[bot]
f018b67895 chore(deps-dev): update sqlalchemy-vertica-python requirement from <0.6,>=0.5.9 to >=0.5.9,<0.7 (#39831)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 22:14:08 -07:00
dependabot[bot]
5e2c6d8c9e chore(deps): bump nanoid from 5.1.9 to 5.1.11 in /superset-frontend (#39820)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 22:13:52 -07:00
dependabot[bot]
b305c8681c chore(deps-dev): update impyla requirement from <0.17,>0.16.2 to >0.16.2,<0.23 (#39833)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 22:09:37 -07:00
dependabot[bot]
d578fa1949 chore(deps): bump @deck.gl/mapbox from 9.3.1 to 9.3.2 in /superset-frontend (#39814)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Đỗ Trọng Hải <41283691+hainenber@users.noreply.github.com>
2026-05-05 22:09:33 -07:00
dependabot[bot]
14d28c34fd chore(deps-dev): update cx-oracle requirement from <8.1,>8.0.0 to >8.0.0,<8.4 (#39753)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 22:05:54 -07:00
dependabot[bot]
c06aee8513 chore(deps-dev): bump jsdom from 29.1.0 to 29.1.1 in /superset-frontend (#39815)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Đỗ Trọng Hải <41283691+hainenber@users.noreply.github.com>
2026-05-05 22:04:47 -07:00
dependabot[bot]
d0ef19953a chore(deps): bump memoize-one from 5.2.1 to 6.0.0 in /superset-frontend/plugins/plugin-chart-ag-grid-table (#37910)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Evan Rusackas <evan@rusackas.com>
2026-05-05 21:38:49 -07:00
Vitor Avila
3745e37182 fix(OAuth2): Support OAuth2 exception with legacy endpoint (#39897) 2026-05-05 21:21:48 -03:00
Joe Li
4b17ac2629 fix(explore): add matrixify_enable guard to prevent stale validators on pre-revamp charts (#38765)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 16:45:38 -07:00
Amin Ghadersohi
4a21a5365f fix(mcp): validate column refs in generate_explore_link, update_chart_preview, and update_chart (#39797) 2026-05-05 19:12:31 -04:00
Richard Fogaca Nienkotter
9459bc7bf4 fix(mcp): warn on invalid chart preview form data key (#39891)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-05 16:40:00 -03:00
Beto Dealmeida
cb53745d43 feat: semantic layer extension (#37815) 2026-05-05 12:07:46 -04:00
jesperct
9e91ae8cff fix(colors): reassign colliding series when dashboard locks shared dimension color (#39297)
Co-authored-by: codeant-ai-for-open-source[bot] <244253245+codeant-ai-for-open-source[bot]@users.noreply.github.com>
2026-05-05 08:38:19 -07:00
jesperct
5b5f23d127 test(plugin-chart-echarts): regression guards for temporal x-axis labels on timeseries charts (#39208) 2026-05-05 08:37:35 -07:00
Mehmet Salih Yavuz
8173cfe9e3 fix(CollectionControl): assign stable ids to keyless items (#39862) 2026-05-05 17:52:36 +03:00
Mehmet Salih Yavuz
586de12a05 fix(embedded): prevent duplicate React root on rehandshake (#39860) 2026-05-05 17:52:01 +03:00
dependabot[bot]
d6188374b4 chore(deps): bump docusaurus-theme-openapi-docs from 5.0.1 to 5.0.2 in /docs (#39846)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 09:16:53 +07:00
dependabot[bot]
2edae162f0 chore(deps): bump baseline-browser-mapping from 2.10.24 to 2.10.27 in /docs (#39848)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-05 09:16:33 +07:00
dependabot[bot]
e80207218b chore(deps-dev): bump eslint from 10.2.1 to 10.3.0 in /superset-websocket (#39843)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-04 17:02:27 -07:00
Beto Dealmeida
76955017eb chore: bump shillelagh to 1.4.4 (#39870) 2026-05-04 19:39:38 -04:00