Встраивание приборных панелей Superset в приложение Django - нужна помощь

Младший разработчик здесь, поэтому некоторые ответы могут нуждаться в контексте :), но я заранее благодарю вас за помощь. Я пытаюсь встроить приборную панель Apache Superset в приложение Django и не могу найти никакой толковой документации по этому вопросу, включая эту: https://github.com/apache/superset/tree/master/superset-embedded-sdk

Фон:

  • Приложение Django прекрасно работает на localhost:8000 и Apache Superset также прекрасно работает на localhost:8088 (в Superset включено встраивание). Проблема в том, что они работают вместе :(
  • .
  • Нужно, чтобы залогиненный пользователь приложения Django мог видеть панель, созданную на Apache Superset
  • .
  • Я реализовал в приложении Django служебную функцию для получения guest_token (для пользователя с правами Public и Gamma на Superset).
  • Этот guest_token вместе с идентификатором встраивания приборной панели передается в шаблон
  • .
  • При посещении страницы пользователем на ней ничего не появляется, кроме небольшого серого экрана с сообщением 127.0.0.1 отказано в подключении
  • .

Код для получения 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 для вызова 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,
        },
    )

И, наконец, шаблон

{% 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 %}

Тестирование (консоль): При загрузке страницы в консоли браузера появляются следующие ошибки:

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)


Тестирование (сетевые заголовки) В браузере в заголовках сети появляется следующее сообщение

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

Я особенно не понимаю эту ошибку, потому что приборная панель определенно существует и имеет упомянутый embed_id


Может ли кто-нибудь, пожалуйста, помочь мне?

Приборная панель, созданная в Apache Superset, должна быть видна в приложении Django. SDK должен загружаться только через CDN

Добавьте X_FRAME_OPTIONS = 'SAMEORIGIN' в файл settings.py. Это должно помочь

В итоге все заработало, когда в файл конфигурации Superset было добавлено следующее

     # 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"}

' Источник: https://github.com/apache/superset/issues/22258

Кроме того, в файл settings.py в Django

было добавлено следующее
X_FRAME_OPTIONS = 'SAMEORIGIN'

Надеюсь, это поможет и другим :)

Вернуться на верх