Embedding Superset dashboards in a Django application - Help needed

Junior developer here, so some answers might need context :) but I thank you in advance for your help. I am trying to embed a Apache Superset dashboard to a Django application and struggling to find any meaningful documentation for the same, including this one: https://github.com/apache/superset/tree/master/superset-embedded-sdk

Background:

  • The Django app is running perfectly on localhost:8000 and the Apache Superset is also running perfectly on localhost:8088 (embedding is enabled in Superset). Problem is them working together :(
  • A logged-in user of the Django app needs to be able to see the dashboard created on Apache Superset
  • I have implemented a utility function in the Django app to fetch a guest_token (for a user with Public and Gamma permissions on Superset).
  • This guest_token along with the dashboard embed ID is passed to the template
  • When the page is visited by the user, nothing appears on the page except a small grey screen saying 127.0.0.1 refused to connect

Code to fetch guest_token:

import requests
from django.conf import settings

def fetch_guest_token(dashboard_id):
    url = f"{settings.SUPERSET_SITE_URL}/api/v1/security/guest_token"
    headers = {
        "Authorization": f"Bearer {settings.SUPERSET_ADMIN_TOKEN}",
        "Content-Type": "application/json",
    }
    payload = {
        "user": {
            "username": "guest_test",
            "first_name": "Test",
            "last_name": "User"
        },
        "resources": [{
            "type": "dashboard",
            "id": dashboard_id
        }],
    }
    response = requests.post(url, json=payload, headers=headers)
    if response.status_code == 200:
        return response.json().get('token')
    else:
        return None

Django view to invoke the fetch_guest_token:

@login_required
@xframe_options_exempt
def page(request, account_slug, page_slug):
    account = get_object_or_404(Account, slug=account_slug)
    page = get_object_or_404(
        Pages, slug=page_slug, account=account, status="ACTIVE"
    )
    superset_embed_id = section_details.visualization.superset_embed_id
    guest_token = fetch_guest_token(superset_embed_id)

    return render(
        request,
        "app/page.html",
        {
            "page": page,
            "superset_embed_id": superset_embed_id,
            "guest_token": guest_token,
        },
    )

And finally, the template

{% extends 'base_logged_in.html' %}

{% block extra_head %}
<script src="https://unpkg.com/@superset-ui/embedded-sdk"></script>
{% endblock extra_head %}

{% block content %}
<h1>{{ page.name }}</h1>
<div class="container">
    <!-- This div will serve as the mount point for the embedded dashboard -->
    <div id="my-superset-container" style="height: 1920px; width: 100%;"></div>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            // Check if we have a token and an embed ID
            if ("{{ guest_token }}" && "{{ superset_embed_id }}") {
                supersetEmbeddedSdk.embedDashboard({
                    id: "{{ superset_embed_id }}",
                    supersetDomain: "{{ settings.SUPERSET_SITE_URL }}",
                    mountPoint: document.getElementById("my-superset-container"),
                    fetchGuestToken: () => Promise.resolve("{{ guest_token }}"),
                    dashboardUiConfig: {
                        hideTitle: true,
                        filters: {
                            expanded: true,
                        }
                    },
                }).catch(error => {
                    console.error('Error embedding Superset dashboard:', error);
                });
            } else {
                console.error('Missing Superset embed ID or guest token.');
            }
        });
    </script>
</div>
{% endblock %}

Testing (Console): When the page is loaded, the following errors appear on the browser console:

Refused to display 'http://127.0.0.1:8000/' in a frame because it set 'X-Frame-Options' to 'deny'. Failed to load resource: the server responded with a status of 404 () Uncaught DOMException: Failed to execute 'postMessage' on 'Window': Invalid target origin '' in a call to 'postMessage'. at HTMLIFrameElement.<anonymous> (https://unpkg.com/@superset-ui/embedded-sdk:1:7125)


Testing (Network Headers) The following appears on the Network Headers in the browser

Page not found (404) Request Method: GET Request URL: http://127.0.0.1:8000/embedded/ce532768-4dd5-4267-ace7-421cda64930e?uiConfig=1&expand_filters=true

I especially do not understand this error because the dashboard definitely exists and has the mentioned embed_id


Can someone please please please help me?

The dashboard that has been created in Apache Superset should be visible on the Django app. The SDK should be loaded via CDN only

Add X_FRAME_OPTIONS = 'SAMEORIGIN' to settings.py file. This should help

It finally worked when the following was added to the Superset config file

     # Dashboard embedding
    GUEST_ROLE_NAME = "Gamma"
    GUEST_TOKEN_JWT_SECRET = "test-guest-secret-change-me"
    GUEST_TOKEN_JWT_ALGO = "HS256"
    GUEST_TOKEN_HEADER_NAME = "X-GuestToken"
    GUEST_TOKEN_JWT_EXP_SECONDS = 300
    TALISMAN_ENABLED = False
    ENABLE_CORS = True
    HTTP_HEADERS={"X-Frame-Options":"ALLOWALL"}

' Source: https://github.com/apache/superset/issues/22258

Also, the following was added to the settings.py file of Django

X_FRAME_OPTIONS = 'SAMEORIGIN'

Hope this helps others too :)

Back to Top