You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Publisher Namespaces**: Extensions use organizational namespaces similar to VS Code extensions, providing collision-safe naming across organizations:
67
+
-**NPM package**: `@my-org/hello-world` (scoped package for frontend distribution)
This ensures consistent naming across all technical components, even when the display name differs significantly from the ID. Since all technical names derive from the extension ID, choosing a unique ID automatically ensures all generated names are also unique, preventing conflicts between extensions.
72
+
This approach ensures that extensions from different organizations cannot conflict, even if they use the same technical name (e.g., both `acme.dashboard-widgets` and `corp.dashboard-widgets` can coexist).
72
73
73
74
This creates a complete project structure:
74
75
75
76
```
76
-
hello-world/
77
+
my-org.hello-world/
77
78
├── extension.json # Extension metadata and configuration
78
79
├── backend/ # Backend Python code
79
80
│ ├── src/
80
81
│ │ └── superset_extensions/
81
-
│ │ └── hello_world/
82
+
│ │ └── my_org/
82
83
│ │ ├── __init__.py
83
-
│ │ └── entrypoint.py # Backend registration
84
+
│ │ └── hello_world/
85
+
│ │ ├── __init__.py
86
+
│ │ └── entrypoint.py # Backend registration
84
87
│ └── pyproject.toml
85
88
└── frontend/ # Frontend TypeScript/React code
86
89
├── src/
@@ -96,8 +99,9 @@ The generated `extension.json` contains basic metadata. Update it to register yo
96
99
97
100
```json
98
101
{
99
-
"id": "hello-world",
100
-
"name": "Hello World",
102
+
"publisher": "my-org",
103
+
"name": "hello-world",
104
+
"displayName": "Hello World",
101
105
"version": "0.1.0",
102
106
"license": "Apache-2.0",
103
107
"frontend": {
@@ -106,7 +110,7 @@ The generated `extension.json` contains basic metadata. Update it to register yo
106
110
"sqllab": {
107
111
"panels": [
108
112
{
109
-
"id": "hello-world.main",
113
+
"id": "my-org.hello-world.main",
110
114
"name": "Hello World"
111
115
}
112
116
]
@@ -115,29 +119,32 @@ The generated `extension.json` contains basic metadata. Update it to register yo
**Note**: The `moduleFederation.name`is automatically derived from the extension ID (`hello-world` → `helloWorld`), and backend entry points use the full Python namespace (`superset_extensions.hello_world`).
133
+
**Note**: The `moduleFederation.name`uses collision-safe naming (`myOrg_helloWorld`), and backend entry points use the full nested Python namespace (`superset_extensions.my_org.hello_world`).
130
134
131
135
**Key fields:**
132
136
137
+
-`publisher`: Organizational namespace for the extension
138
+
-`name`: Technical identifier (kebab-case)
139
+
-`displayName`: Human-readable name shown to users
133
140
-`frontend.contributions.views.sqllab.panels`: Registers your panel in SQL Lab
134
141
-`backend.entryPoints`: Python modules to load eagerly when extension starts
135
142
136
143
## Step 4: Create Backend API
137
144
138
-
The CLI generated a basic `backend/src/superset_extensions/hello_world/entrypoint.py`. We'll create an API endpoint.
145
+
The CLI generated a basic `backend/src/superset_extensions/my_org/hello_world/entrypoint.py`. We'll create an API endpoint.
- Returns responses using `self.response(status_code, result=data)`
189
-
- The endpoint will be accessible at `/extensions/hello-world/message`
196
+
- The endpoint will be accessible at `/extensions/my-org/hello-world/message`
190
197
- OpenAPI docstrings are crucial - Flask-AppBuilder uses them to automatically generate interactive API documentation at `/swagger/v1`, allowing developers to explore endpoints, understand schemas, and test the API directly from the browser
0 commit comments