You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by am...@apache.org on 2026/09/01 16:21:51 UTC
(superset) 01/15: feat(embedded): add EmbeddedChart model and migration
This is an automated email from the ASF dual-hosted git repository.
amaannawab923 pushed a commit to branch feat/embedded-chart
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 0a61a78980d12e1d21ef0e91a13b018352acc4b5
Author: amaannawab923 <am...@gmail.com>
AuthorDate: Tue Sep 1 18:13:58 2026 +0530
feat(embedded): add EmbeddedChart model and migration
Mirrors EmbeddedDashboard so both embeddable resource types share the same
guest-token and allowed-domain semantics, including
guest_token_revoked_before.
---
...10-00_a1c7e4b62f18_add_embedded_charts_table.py | 56 +++++++++++++++++++
superset/models/embedded_chart.py | 64 ++++++++++++++++++++++
superset/models/slice.py | 5 ++
3 files changed, 125 insertions(+)
diff --git a/superset/migrations/versions/2026-09-01_10-00_a1c7e4b62f18_add_embedded_charts_table.py b/superset/migrations/versions/2026-09-01_10-00_a1c7e4b62f18_add_embedded_charts_table.py
new file mode 100644
index 00000000000..de6017e1ac9
--- /dev/null
+++ b/superset/migrations/versions/2026-09-01_10-00_a1c7e4b62f18_add_embedded_charts_table.py
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""add embedded_charts table
+
+Revision ID: a1c7e4b62f18
+Revises: 39097d124752
+Create Date: 2026-09-01 10:00:00.000000
+
+"""
+
+import sqlalchemy as sa
+from alembic import op
+from sqlalchemy_utils import UUIDType
+
+from superset.migrations.shared.utils import create_table, drop_table
+
+# revision identifiers, used by Alembic.
+revision = "a1c7e4b62f18"
+down_revision = "39097d124752"
+
+
+def upgrade() -> None:
+ create_table(
+ "embedded_charts",
+ sa.Column("created_on", sa.DateTime(), nullable=True),
+ sa.Column("changed_on", sa.DateTime(), nullable=True),
+ sa.Column("created_by_fk", sa.Integer(), nullable=True),
+ sa.Column("changed_by_fk", sa.Integer(), nullable=True),
+ sa.Column("uuid", UUIDType(binary=True), primary_key=True),
+ sa.Column("allow_domain_list", sa.Text(), nullable=True),
+ sa.Column("guest_token_revoked_before", sa.Integer(), nullable=True),
+ sa.Column("slice_id", sa.Integer(), nullable=False),
+ sa.ForeignKeyConstraint(
+ ["slice_id"], ["slices.id"], ondelete="CASCADE"
+ ),
+ sa.ForeignKeyConstraint(["changed_by_fk"], ["ab_user.id"]),
+ sa.ForeignKeyConstraint(["created_by_fk"], ["ab_user.id"]),
+ )
+
+
+def downgrade() -> None:
+ drop_table("embedded_charts")
diff --git a/superset/models/embedded_chart.py b/superset/models/embedded_chart.py
new file mode 100644
index 00000000000..89335dbb8a4
--- /dev/null
+++ b/superset/models/embedded_chart.py
@@ -0,0 +1,64 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import uuid
+
+from flask_appbuilder import Model
+from sqlalchemy import Column, ForeignKey, Integer, Text
+from sqlalchemy.orm import relationship
+from sqlalchemy_utils import UUIDType
+
+from superset.models.helpers import AuditMixinNullable
+
+
+class EmbeddedChart(Model, AuditMixinNullable):
+ """
+ A configuration of embedding for a chart.
+
+ References the chart, and contains a config for embedding that chart.
+ Mirrors ``EmbeddedDashboard`` so both embeddable resource types share the
+ same guest-token and allowed-domain semantics.
+
+ This data model allows multiple configurations for a given chart,
+ but at this time the API only allows setting one.
+ """
+
+ __tablename__ = "embedded_charts"
+
+ uuid = Column(UUIDType(binary=True), default=uuid.uuid4, primary_key=True)
+ allow_domain_list = Column(Text) # reference the `allowed_domains` property instead
+ # Epoch seconds; guest tokens whose `iat` predates this are rejected. Set to
+ # "now" to revoke all currently-issued guest tokens for this embedded
+ # chart. NULL = no revocation.
+ guest_token_revoked_before = Column(Integer, nullable=True)
+ slice_id = Column(
+ Integer,
+ ForeignKey("slices.id", ondelete="CASCADE"),
+ nullable=False,
+ )
+ slice = relationship(
+ "Slice",
+ back_populates="embedded",
+ foreign_keys=[slice_id],
+ )
+
+ @property
+ def allowed_domains(self) -> list[str]:
+ """
+ A list of domains which are allowed to embed the chart.
+ An empty list means any domain can embed.
+ """
+ return self.allow_domain_list.split(",") if self.allow_domain_list else []
diff --git a/superset/models/slice.py b/superset/models/slice.py
index 8540817ee9f..bf33db3fd49 100644
--- a/superset/models/slice.py
+++ b/superset/models/slice.py
@@ -142,6 +142,11 @@ class Slice( # pylint: disable=too-many-public-methods
secondary=chart_viewers,
passive_deletes=True,
)
+ embedded = relationship(
+ "EmbeddedChart",
+ back_populates="slice",
+ cascade="all, delete-orphan",
+ )
tags = relationship(
"Tag",