villebro commented on PR #43262:
URL: https://github.com/apache/superset/pull/43262#issuecomment-5332863261
Thanks @michael-s-molina — all four points are addressed.
**1. Registration contract lives in `superset_core`.** `Widget` (the base
class) and a `widget()` decorator are now in `superset_core.widgets`, so an
extension registers exactly as you sketched:
```python
from superset_core.widgets import Widget, widget
@widget(widget_type="my-widget", name="My Widget", description="...")
class MyWidget(Widget):
controls_class = MyWidgetControlsModel
```
The concrete decorator is injected in
`superset/core/api/core_api_injection.py::inject_widget_implementations` (the
same stub-and-inject pattern as semantic layers / MCP), and the app-side
registry is now a plain `dict[str, type[Widget]]`. `Widget` is deliberately the
wrapper (not a bare "controls" object): today it exposes the control panel
(schema + validation), but a widget type's other backend concerns — building a
`SemanticQuery` from the control values, and post-processing query results
before they reach the viz — will be added as sibling methods on `Widget` and
register as a whole, rather than in a parallel registry.
**2. Built-ins go through the exact same decorator.**
`superset/widgets/builtin.py` uses `@widget(...)` from `superset_core.widgets`
— no second path. One wrinkle worth noting: `init_views()` imports the widget
REST API *before* dependency injection runs, so the built-ins are imported
inside the injection step (once the decorator is concrete) — the same ordering
the MCP layer uses for its built-in tools.
**3. Collision guard.** Registering a `widget_type` that's already taken
raises `ValueError` naming both the existing and the new class. Extension
registrations are namespaced `extensions.<publisher>.<name>.<type>` (as
semantic layers do), so an extension can't shadow a built-in.
**4. Frontend allowlist is derived.** The Inspector no longer hardcodes the
set — it fetches `/api/v1/widgets/types` (cached hook, fails open) and falls
back to the generic props form for a type with no schema. Adding a widget type,
built-in or extension, needs no frontend edit.
Two additional things landed in the same PR:
- **Commit-time schema validation** (the meaningful one): a widget-agnostic
`Widget.validate_control_values` + `POST /api/v1/widgets/type/<type>/validate`
that surfaces declarative Pydantic rules as actionable errors. This lets a
widget enforce constraints JSON Schema can't express (e.g. balloons'
`colorDimension` must be one of `dataBinding.dimensions`) just by adding a
validator to its control model — the caller gets a clear message and
self-corrects. I think this is key to making the schema-driven panel resilient
as more widgets are added.
- Minor balloons polish (clearer self-description, de-synchronized motion) —
cosmetic; happy to drop it if you'd rather keep the PR tight.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]