Retire the Superset reader setup and the ATOMA dashboard (PD-13)

ATOMA's users use the Petrolyst app; Superset keeps admins, editors and the
app's embedded dashboards. Removed: the "ATOMA Reader" role and its rules
(petrolyst_reader.py, ReaderAccessMixin, reader.css, the head template, the
SQL-hiding patch), the atoma-reader mapping (it now maps to nothing in
Superset), the iframe allowance for the Map tab, and the "atoma" dashboard
with its Fleet/Map tab, D0 and dashboard.css. The bundle holds atoma-overview
and atoma-site only (byte-identical to before); the guest role keeps the
reader's 12 permissions in roles/atoma_guest.py. Brand files now name
petrolyst-web. SPEC marks the retired parts as history.

Checks (local): bundle checks pass; image rebuilt and healthy; import with
column drift 0 and unchanged embedding ids; the production config loads with
OAuth, embedding off, no reader hook; admin sees atoma-site with its tabs and
filter column; the app's browser tests pass 10/10. shellcheck not run (not
installed). Not deployed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nasim SadatandClaude Opus 5.5 committed 2026-10-29 21:10:19 +01:00
1 parent 1b8e57adb4
commit da3f803947
22 files changed
+164 -702

No files matched your search

@@ -1,4 +1,4 @@
"""Import the ATOMA dashboard bundle into Superset, overwriting what it defines.
"""Import the ATOMA dashboards bundle into Superset, overwriting what it defines.
Runs inside the Superset container, with the image's Python:
@@ -17,15 +17,10 @@ live view and any drift is reported (exit status 2).
The database is never created or changed: the bundle's database uuid must
already exist under the name "Fuel (Trino)", otherwise nothing is imported.
A bundle cannot carry a dashboard's roles, so afterwards the role "ATOMA Reader"
is attached to the ATOMA dashboard: with DASHBOARD_RBAC that is how ATOMA's
readers see it. The role comes from roles/atoma_reader.py (run by superset-init);
without it nothing is imported.
The Petrolyst app's dashboards (PD-12: atoma-overview, atoma-site) get no role:
the app shows them with guest passes. With --embedded-out FILE --embed-domain URL,
each of them is made embeddable from that origin (its embedding id stays the same
across imports), and FILE receives {slug: embedding id} for the app service:
The dashboards (atoma-overview, atoma-site) get no role: admins see them in Superset, and
the Petrolyst app shows them with guest passes (PD-12). With --embedded-out FILE
--embed-domain URL, each of them is made embeddable from that origin (its embedding id stays
the same across imports), and FILE receives {slug: embedding id} for the Petrolyst server:
docker exec <container> /app/.venv/bin/python /tmp/import_bundle.py /tmp/atoma-dashboards.zip \
--user <username> --embedded-out /tmp/embedded-dashboards.json --embed-domain http://127.0.0.1:8098
@@ -41,14 +36,12 @@ import zipfile
import yaml
DATABASE_NAME = "Fuel (Trino)"
READER_ROLE = "ATOMA Reader"
READER_SLUG = "atoma" # the readers' dashboard; the others are the app's (PD-12)
EMBEDDED_PREFIX = "atoma-"
STEPS = [("datasets", "SqlaTable"), ("charts", "Slice"), ("dashboards", "Dashboard")]
def main() -> int:
parser = argparse.ArgumentParser(description="Import the ATOMA dashboard bundle.")
parser = argparse.ArgumentParser(description="Import the ATOMA dashboards bundle.")
parser.add_argument("bundle", nargs="?")
parser.add_argument("--user", help="existing Superset user who will own new objects")
parser.add_argument("--show-database", action="store_true",
@@ -85,10 +78,6 @@ def main() -> int:
if user is None:
print(f"no Superset user {args.user!r}", file=sys.stderr)
return 1
reader_role = security_manager.find_role(READER_ROLE)
if reader_role is None:
print(f'no role "{READER_ROLE}": run roles/atoma_reader.py first', file=sys.stderr)
return 1
with zipfile.ZipFile(args.bundle) as bundle:
contents = get_contents_from_bundle(bundle)
databases = [yaml.safe_load(t) for p, t in contents.items() if p.startswith("databases/")]
@@ -115,17 +104,13 @@ def main() -> int:
if path.startswith("dashboards/"):
dashboard = db.session.query(Dashboard).filter_by(
uuid=yaml.safe_load(text)["uuid"]).one()
if dashboard.slug == READER_SLUG:
if reader_role not in dashboard.roles:
dashboard.roles.append(reader_role)
elif dashboard.slug.startswith(EMBEDDED_PREFIX) and args.embedded_out:
if dashboard.slug.startswith(EMBEDDED_PREFIX) and args.embedded_out:
from superset.daos.dashboard import EmbeddedDashboardDAO
config = EmbeddedDashboardDAO.upsert(dashboard, [args.embed_domain])
db.session.flush()
embedded[dashboard.slug] = str(config.uuid)
db.session.commit()
print(f'dashboards: "{READER_SLUG}" readable for "{READER_ROLE}"')
if args.embedded_out:
with open(args.embedded_out, "w") as out:
json.dump(dict(sorted(embedded.items())), out, indent=2)