superset
superset copied to clipboard
4.0 - Imported charts shows error on embedding
Bug description
「Guest user cannot modify chart payload」 Error is displayed for imported charts. It's related to this issue, but with a specific reproduction flow. (https://github.com/apache/superset/issues/27177)
How to reproduce the bug
- Create 2 superset 4.0 instances
- Create a dashboard with a few charts (tested with "big-number" chart)
- Export the dashboard and import it into the other superset instance
- Try to embed the dashboard (using the sdk) into a web app
- 「Guest user cannot modify chart payload」Error is displayed for each chart
Screenshots/recordings
Superset version
4.0.0
Python version
3.9
Node version
16
Browser
Chrome
Additional context
It seems that the export/import functionality doesn't copy the query_context field. (It becomes null after import)
I believe the query_context became important after this PR: https://github.com/apache/superset/pull/27484/files
Workaround
I noticed that just by opening the imported chart in the superset side updates the query_context and the embed starts working for that chart. We can't use this workaround as we have hundreds of charts for each of our clients.
Checklist
- [X] I have searched Superset docs and Slack and didn't find a solution to my problem.
- [X] I have searched the GitHub issue tracker and didn't find a similar bug report.
- [X] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.
To address the issue of "Guest user cannot modify chart payload" for imported charts in Apache Superset 4.0.0, you can automate the update of the query_context for each chart. This can be achieved by either directly interacting with the Superset backend database or using Superset's REST API to fetch and update charts. Here's a brief overview of both approaches:
-
Direct Database Manipulation: Write a script that connects to the Superset database, fetches all charts, updates the
query_contextfield in their metadata, and saves the changes back to the database. This method requires direct access to the database and careful handling to avoid data corruption. -
Using Superset APIs: A safer, albeit potentially slower, method involves using the Superset REST API. You would use the
GET /chart/endpoint to fetch chart configurations, update thequery_contextin each configuration, and then use thePUT /chart/{pk}endpoint to update each chart.
Before proceeding with either method, ensure you have a complete backup of your database to prevent data loss. It's also recommended to test your solution in a development environment before applying it to production.
Here's a simplified example of how you might use Python to update chart metadata using Superset's API:
import requests
SUPSERET_API_URL = "http://your-superset-instance/api/v1/chart"
API_TOKEN = "your_api_token"
def update_chart(chart_id, updated_config):
headers = {"Authorization": f"Bearer {API_TOKEN}"}
response = requests.put(f"{SUPSERET_API_URL}/{chart_id}", json=updated_config, headers=headers)
if response.status_code == 200:
print(f"Successfully updated chart {chart_id}")
else:
print(f"Failed to update chart {chart_id}: {response.text}")
# Example usage
chart_id = 123 # Example chart ID
updated_config = {
# Your updated chart configuration including the new query_context
}
update_chart(chart_id, updated_config)
This script is a basic example and will need to be adjusted based on your specific requirements, including authentication and the exact structure of the updated_config.
Details
Sources
- superset/security/manager.py
- superset/common/query_context.py
- superset/charts/schemas.py
- superset/commands/dashboard/importers/v1/init.py
- superset/common/query_context_processor.py
- superset/common/query_context_factory.py
- superset-frontend/packages/superset-ui-core/src/query/buildQueryContext.ts
- superset/security/api.py
- superset-embedded-sdk/src/index.ts
- superset/commands/dashboard/importers/v1/utils.py
- tests/unit_tests/security/manager_test.py
- tests/integration_tests/security/guest_token_security_tests.py
About Dosu This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.
Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.
To continue the conversation, mention @dosu.
I actually tried to call the update api to see if the query_context would be automatically created, but it wasn't. I would have to know the exact json to put there, which I don't. Even if it were doable, It still feels that the query_context should also be copied with the import functionality.
I also noticed a different related issue.
When you are embedding standalone charts, if the chart has no query_context it will try to update the chart from the iframe, and since the Public role doesn't have permission to update the chart, it ends up redirecting to the login page and you end up having iframes with login pages showing on them.
I could patch the issue described (「Guest user cannot modify chart payload」): Just opening each chart giving mentioned error and, without having to modify anything, saving it again. That worked for me.
@betodealmeida am I taking crazy pills or does this sound like the issue you fixed in unblocking 4.0?
I think the issue blocking 4.0 previously was without imports, embeds would show that error for certain charts. This is a blocker for us though, as we use a multi-environment setup and have to use imports to deploy to higher environments. Adding a new manual step to an already cumbersome pipeline wouldn't bode well.
Any update on this? We use a multi-environment set up and this presently a blocker. Please and thank you.
We're also experiencing this issue and have not updated to 4.x.x because of this. Was working fine on 3.x. There are some nice improvements within 4.x we'd like to take advantage of, but this is currenty blocking us from updating.
@michael-s-molina do you have any context on this, perchance?
@rusackas I think this was caused by a change made by @betodealmeida https://github.com/apache/superset/pull/27484
From my understanding of the problem:
- When you export charts, query_context is present in the exported files but the id for the datasource and the slice are not converted to uuid so the query_context is useless when you import it to a different instance.
- To avoid a bug when you import, a process has been added to remove the query_context entirely, still present in master
- Then the new security layer fails because the query context is empty
So a fix could be around properly export the charts in the first place and stop removing the query_context when importing.
A temporary workaround is to update the charts using the api, based on the exported query_context. Of course if you are exporting and importing on a different instance, you need to change ids references in the query_context
Hello,
the context seems to be solely about importing dashboards for all of you.
On my side, I tried to embed a dashboard that was created directly (all elements (dashboard, chart, dataset are created from scratch).
I got the same error message.
The dasboard in Superset :
My tests were carried out on version 3.1.1
Best regards.
We have also faced this issue after upgrading to 4.0.0
Any news on this ? I have the same problem in 3.1.1
Nope, no news yet. Anyone here is welcome to explore a fix... I'm guessing @betodealmeida is just a bit too busy to get to it right now.
Sorry, I missed this. Let me take a look, seems like we need to fix the import/export.
Workaround: You can open the Chart using Superset Interface, load the data, and then go to your Embedded dashboard and reload it. It should work.
FROM apache/superset:4.0.2-py310
Hey @betodealmeida, and updates on this by chance?
cannot upgrade to 4.0.2 because of this issue. we are still using 3.0.2.
we are using multi-environment set up and saving each charts in each instance isn't practical.
any turnaround for this issue?
Hey Any fix for this?
We've got a commit on our fork to fix the imports to include the query context. Commit is here: https://github.com/lindenh/superset/commit/eee9b8518cddf3471000cb081e1b8ce1e6a6ebef I'm not 100% if this is the best approach all around and I still need to write some tests to open a PR here, but this has worked really well for our org's deployment structure. Hope this helps someone else.