apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
61.94k stars 13.57k forks source link

Chart UUID not exposed in API but required when creating dashboard via API #15456

Closed jtornblad closed 7 months ago

jtornblad commented 3 years ago

In order to create a dashboard with the API, the UUID(s) of charts on the dashboard must be supplied in the serialized JSON object in the position_json attribute of the request to POST /dashboard/ (attribute name uuid). This UUID is apparently created internally with the chart (say, during a POST to /chart/) but the UUID value is not returned in the create chart response, nor by any other chart-related API, making it impossible to know / ascertain the UUID of charts via the API and therefore create a dashboard with the API immediately following creation of charts with the API.

Noting that chart UUIDs can be determined if they are manually added to a dashboard through the UI and then a GET /dashboard/{pk}` is performed.

Expected results

Upon creating a chart, the UUID of the chart should be returned in the response JSON from POST /chart/.

Actual results

No UUID is returned.

How to reproduce the bug

Prerequisites:

  1. Obtain a TOKEN TOKEN=$(curl -s http://$SUPERSET_HOST/api/v1/security/login -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "password": "'$SUPERSET_PASSWORD'", "provider": "db", "refresh": true, "username": "'$SUPERSET_USER'" }' | jq -r .access_token)

  2. Look up flights dataset DATASOURCE_ID=$(curl -s -H 'Authorization: Bearer '$TOKEN'' http://$SUPERSET_HOST/api/v1/dataset/'?q=%7B%0A%20%20%22filters%22%3A%20%5B%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%22col%22%3A%20%22table_name%22%2C%0A%20%20%20%20%20%20%22opr%22%3A%20%22eq%22%2C%0A%20%20%20%20%20%20%22value%22%3A%20%22flights%22%0A%20%20%20%20%7D%0A%20%20%5D%0A%7D' | jq -r '.result[0].id')

  3. Create a chart curl -s 'http://'$SUPERSET_HOST'/api/v1/chart/' \ -H 'Authorization: Bearer '$TOKEN'' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "datasource_id": '$DATASOURCE_ID', "description": "Test", "slice_name": "Test", "datasource_type": "table", "viz_type": "bar", "params": "{\n \"adhoc_filters\": [],\n \"annotation_layers\": [],\n \"bar_stacked\": false,\n \"bottom_margin\": \"auto\",\n \"color_scheme\": \"supersetColors\",\n \"comparison_type\": \"values\",\n \"datasource\": \"10__table\",\n \"extra_form_data\": {},\n \"granularity_sqla\": \"ds\",\n \"groupby\": [\n \"AIRLINE\"\n ],\n \"label_colors\": {},\n \"left_margin\": \"auto\",\n \"limit\": 500,\n \"line_interpolation\": \"linear\",\n \"metrics\": [\n {\n \"aggregate\": null,\n \"column\": null,\n \"expressionType\": \"SQL\",\n \"hasCustomLabel\": false,\n \"isNew\": false,\n \"label\": \"AVG(COALESCE(\\\"AIRLINE_DELAY\\\",0))\",\n \"optionName\": \"metric_7f2c9v9wh7o_rkdrxg4i2pk\",\n \"sqlExpression\": \"AVG(COALESCE(\\\"AIRLINE_DELAY\\\",0))\"\n }\n ],\n \"order_desc\": false,\n \"rich_tooltip\": true,\n \"rolling_type\": \"None\",\n \"row_limit\": null,\n \"show_bar_value\": false,\n \"show_brush\": \"auto\",\n \"show_controls\": false,\n \"show_legend\": true,\n \"slice_id\": 465,\n \"time_grain_sqla\": null,\n \"time_range\": \"No filter\",\n \"time_range_endpoints\": [\n \"inclusive\",\n \"exclusive\"\n ],\n \"timeseries_limit_metric\": [],\n \"url_params\": {},\n \"viz_type\": \"bar\",\n \"x_axis_format\": \"%m/%d/%Y\",\n \"x_axis_label\": \"Day\",\n \"x_ticks_layout\": \"auto\",\n \"y_axis_bounds\": [\n null,\n null\n ],\n \"y_axis_format\": \"SMART_NUMBER\",\n \"y_axis_label\": \"Average Delay (mins) by Airline\"\n}" }'

Notice that no UUID is returned in the response (example): { "id": 139, "result": { "datasource_id": 10, "datasource_type": "table", "description": "Test", "params": "{\n \"adhoc_filters\": [],\n \"annotation_layers\": [],\n \"bar_stacked\": false,\n \"bottom_margin\": \"auto\",\n \"color_scheme\": \"supersetColors\",\n \"comparison_type\": \"values\",\n \"datasource\": \"10__table\",\n \"extra_form_data\": {},\n \"granularity_sqla\": \"ds\",\n \"groupby\": [\n \"AIRLINE\"\n ],\n \"label_colors\": {},\n \"left_margin\": \"auto\",\n \"limit\": 500,\n \"line_interpolation\": \"linear\",\n \"metrics\": [\n {\n \"aggregate\": null,\n \"column\": null,\n \"expressionType\": \"SQL\",\n \"hasCustomLabel\": false,\n \"isNew\": false,\n \"label\": \"AVG(COALESCE(\\\"AIRLINE_DELAY\\\",0))\",\n \"optionName\": \"metric_7f2c9v9wh7o_rkdrxg4i2pk\",\n \"sqlExpression\": \"AVG(COALESCE(\\\"AIRLINE_DELAY\\\",0))\"\n }\n ],\n \"order_desc\": false,\n \"rich_tooltip\": true,\n \"rolling_type\": \"None\",\n \"row_limit\": null,\n \"show_bar_value\": false,\n \"show_brush\": \"auto\",\n \"show_controls\": false,\n \"show_legend\": true,\n \"slice_id\": 465,\n \"time_grain_sqla\": null,\n \"time_range\": \"No filter\",\n \"time_range_endpoints\": [\n \"inclusive\",\n \"exclusive\"\n ],\n \"timeseries_limit_metric\": [],\n \"url_params\": {},\n \"viz_type\": \"bar\",\n \"x_axis_format\": \"%m/%d/%Y\",\n \"x_axis_label\": \"Day\",\n \"x_ticks_layout\": \"auto\",\n \"y_axis_bounds\": [\n null,\n null\n ],\n \"y_axis_format\": \"SMART_NUMBER\",\n \"y_axis_label\": \"Average Delay (mins) by Airline\"\n}", "slice_name": "Test", "viz_type": "bar" } }

Nor is it in the GET /chart/{pk}:

From above response: CHART_ID=139

curl -s -H 'Authorization: Bearer '$TOKEN'' -H 'accept: application/json' 'http://'$SUPERSET_HOST'/api/v1/chart/'$CHART_ID | jq .

{ "description_columns": {}, "id": 139, "label_columns": { "cache_timeout": "Cache Timeout", "dashboards.dashboard_title": "Dashboards Dashboard Title", "dashboards.id": "Dashboards Id", "description": "Description", "owners.first_name": "Owners First Name", "owners.id": "Owners Id", "owners.last_name": "Owners Last Name", "owners.username": "Owners Username", "params": "Params", "slice_name": "Slice Name", "viz_type": "Viz Type" }, "result": { "cache_timeout": null, "dashboards": [], "description": "Test", "owners": [ { "first_name": "Superset", "id": 1, "last_name": "Admin", "username": "admin" } ], "params": "{\n \"adhoc_filters\": [],\n \"annotation_layers\": [],\n \"bar_stacked\": false,\n \"bottom_margin\": \"auto\",\n \"color_scheme\": \"supersetColors\",\n \"comparison_type\": \"values\",\n \"datasource\": \"10__table\",\n \"extra_form_data\": {},\n \"granularity_sqla\": \"ds\",\n \"groupby\": [\n \"AIRLINE\"\n ],\n \"label_colors\": {},\n \"left_margin\": \"auto\",\n \"limit\": 500,\n \"line_interpolation\": \"linear\",\n \"metrics\": [\n {\n \"aggregate\": null,\n \"column\": null,\n \"expressionType\": \"SQL\",\n \"hasCustomLabel\": false,\n \"isNew\": false,\n \"label\": \"AVG(COALESCE(\\\"AIRLINE_DELAY\\\",0))\",\n \"optionName\": \"metric_7f2c9v9wh7o_rkdrxg4i2pk\",\n \"sqlExpression\": \"AVG(COALESCE(\\\"AIRLINE_DELAY\\\",0))\"\n }\n ],\n \"order_desc\": false,\n \"rich_tooltip\": true,\n \"rolling_type\": \"None\",\n \"row_limit\": null,\n \"show_bar_value\": false,\n \"show_brush\": \"auto\",\n \"show_controls\": false,\n \"show_legend\": true,\n \"slice_id\": 465,\n \"time_grain_sqla\": null,\n \"time_range\": \"No filter\",\n \"time_range_endpoints\": [\n \"inclusive\",\n \"exclusive\"\n ],\n \"timeseries_limit_metric\": [],\n \"url_params\": {},\n \"viz_type\": \"bar\",\n \"x_axis_format\": \"%m/%d/%Y\",\n \"x_axis_label\": \"Day\",\n \"x_ticks_layout\": \"auto\",\n \"y_axis_bounds\": [\n null,\n null\n ],\n \"y_axis_format\": \"SMART_NUMBER\",\n \"y_axis_label\": \"Average Delay (mins) by Airline\"\n}", "slice_name": "Test", "viz_type": "bar" }, "show_columns": [ "cache_timeout", "dashboards.dashboard_title", "dashboards.id", "description", "owners.first_name", "owners.id", "owners.last_name", "owners.username", "params", "slice_name", "viz_type" ], "show_title": "Show Slice" }

Environment

Checklist

Make sure to follow these steps before submitting your issue - thank you!

Additional context

Related issue:

15457 Creating a dashboard with API does not result in a functioning dashboard

hitzelc commented 2 years ago

Maybe a little too late, but I had a similar problem. A quick-and-dirty fix is to edit the charts/api.py file as follows: https://gist.github.com/hitzelc/10ad912bd246d4358728a8407ac2c842

You can see the addition in line 291. Now chart creation via a POST to the /chart/ endpoint will return the uuid associated with the chart.

The way I use this is as follows:

Note: the position JSON is kind of a pain...when you create a dashboard via API is has no position JSON at all, even after you add charts to it. You have to manually save/edit any dashboard to have a position JSON associated with it. So I recommend you make your dashboards by hand with the charts you want, and then export that chart and steal that position JSON as a starting point (assuming your goal is to automate dashboard creation moving forward).

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. For admin, please label this issue .pinned to prevent stale bot from closing the issue.

anied commented 2 years ago

I would recommend against closing this ticket-- this is still an issue I am facing and it seems exceedingly onerous to figure out how to access the dashboard ID and do so right now.

rusackas commented 7 months ago

It's been another year and a half, and the import/export code has changed quite a bit since then. Closing this as stale since it's been silent for so long, and we're trying to steer toward a more actionable Issues backlog. If people are still encountering this in current versions (currently 3.x) please open a new Issue with renewed context, or a PR to address the problem. Thanks for understanding.

salimnoma commented 3 months ago

This really seems like an important issue so it would be a good idea to keep it open. uuids are not exposed in the API which makes it almost impossible to really control dashboards from the API. So perhaps it should be included?