Встраивание приборных панелей 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'
Надеюсь, это поможет и другим :)