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]

Reply via email to