superset 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.buildkite/pipeline.yml +16 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/CHANGELOG.md +48 -0
- data/Dockerfile +17 -0
- data/LICENSE +21 -0
- data/README.md +205 -0
- data/Rakefile +12 -0
- data/doc/duplicate_dashboards.md +214 -0
- data/doc/setting_up_personal_api_credentials.md +127 -0
- data/docker-compose.override.yml +10 -0
- data/docker-compose.yml +8 -0
- data/env.sample +9 -0
- data/lib/loggers/duplicate_dashboard_logger.rb +15 -0
- data/lib/superset/authenticator.rb +55 -0
- data/lib/superset/chart/bulk_delete.rb +40 -0
- data/lib/superset/chart/delete.rb +30 -0
- data/lib/superset/chart/get.rb +56 -0
- data/lib/superset/chart/list.rb +59 -0
- data/lib/superset/chart/update_dataset.rb +90 -0
- data/lib/superset/client.rb +53 -0
- data/lib/superset/credential/api_user.rb +25 -0
- data/lib/superset/credential/embedded_user.rb +25 -0
- data/lib/superset/dashboard/bulk_delete.rb +42 -0
- data/lib/superset/dashboard/bulk_delete_cascade.rb +52 -0
- data/lib/superset/dashboard/charts/list.rb +47 -0
- data/lib/superset/dashboard/compare.rb +94 -0
- data/lib/superset/dashboard/copy.rb +78 -0
- data/lib/superset/dashboard/datasets/list.rb +74 -0
- data/lib/superset/dashboard/delete.rb +42 -0
- data/lib/superset/dashboard/embedded/get.rb +56 -0
- data/lib/superset/dashboard/embedded/put.rb +35 -0
- data/lib/superset/dashboard/export.rb +98 -0
- data/lib/superset/dashboard/get.rb +51 -0
- data/lib/superset/dashboard/info.rb +17 -0
- data/lib/superset/dashboard/list.rb +99 -0
- data/lib/superset/dashboard/put.rb +37 -0
- data/lib/superset/dashboard/warm_up_cache.rb +42 -0
- data/lib/superset/database/get.rb +30 -0
- data/lib/superset/database/get_schemas.rb +25 -0
- data/lib/superset/database/list.rb +51 -0
- data/lib/superset/dataset/bulk_delete.rb +41 -0
- data/lib/superset/dataset/create.rb +62 -0
- data/lib/superset/dataset/delete.rb +30 -0
- data/lib/superset/dataset/duplicate.rb +62 -0
- data/lib/superset/dataset/get.rb +56 -0
- data/lib/superset/dataset/list.rb +41 -0
- data/lib/superset/dataset/update_query.rb +56 -0
- data/lib/superset/dataset/update_schema.rb +120 -0
- data/lib/superset/dataset/warm_up_cache.rb +41 -0
- data/lib/superset/display.rb +42 -0
- data/lib/superset/enumerations/object_type.rb +11 -0
- data/lib/superset/file_utilities.rb +19 -0
- data/lib/superset/guest_token.rb +69 -0
- data/lib/superset/logger.rb +20 -0
- data/lib/superset/request.rb +62 -0
- data/lib/superset/route_info.rb +34 -0
- data/lib/superset/security/permissions_resources/list.rb +22 -0
- data/lib/superset/security/role/create.rb +25 -0
- data/lib/superset/security/role/get.rb +32 -0
- data/lib/superset/security/role/list.rb +45 -0
- data/lib/superset/security/role/permission/create.rb +35 -0
- data/lib/superset/security/role/permission/get.rb +37 -0
- data/lib/superset/security/user/create.rb +49 -0
- data/lib/superset/security/user/get.rb +27 -0
- data/lib/superset/security/user/list.rb +42 -0
- data/lib/superset/services/duplicate_dashboard.rb +298 -0
- data/lib/superset/sqllab/execute.rb +52 -0
- data/lib/superset/tag/add_to_object.rb +46 -0
- data/lib/superset/tag/get.rb +30 -0
- data/lib/superset/tag/list.rb +37 -0
- data/lib/superset/version.rb +5 -0
- data/lib/superset.rb +17 -0
- data/log/README.md +4 -0
- data/superset.gemspec +55 -0
- metadata +300 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 16bb352b533737ed4faed7d5b4360c850619d60b7997b12638019681a8b36bfd
|
4
|
+
data.tar.gz: e7dd50138ea34bd23969a61bf6f69f7eb98cc6174f67abdb05fdb9ba4eb60197
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ed7199d606cb33b4f30e79d6816ccd2d00c63061c88d630b8e9b538e540cbf4ae3ea50bfccf3acb8ba7e6d92ba09e51871a58b0ea3a84cbfc37d16641923d737
|
7
|
+
data.tar.gz: 50e1ed97a6fb3b698136c313b0384755f42eecf6b171aa7a02021919e59fc9d2bed6991fb03129d8f37a47df6ca4d825b542fe8d36b1410d1bbd284570014e01
|
@@ -0,0 +1,16 @@
|
|
1
|
+
steps:
|
2
|
+
- label: ":rspec:"
|
3
|
+
command: bin/setup && bundle exec rspec
|
4
|
+
plugins:
|
5
|
+
docker-compose#v3.0.3:
|
6
|
+
run: app
|
7
|
+
volumes:
|
8
|
+
- ./coverage:/app/coverage
|
9
|
+
- ./log:/app/log
|
10
|
+
timeout: 10
|
11
|
+
agents:
|
12
|
+
queue: docker-heavy
|
13
|
+
artifact_paths:
|
14
|
+
- "coverage/.resultset*.json"
|
15
|
+
- "log/*.log"
|
16
|
+
- "log/*.xml"
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
## Change Log
|
2
|
+
|
3
|
+
## 0.1.6 - 2024-07-10
|
4
|
+
|
5
|
+
* added a class **WarmUpCache** to hit the 'api/v1/dataset/warm_up_cache' endpoint to warm up the cache of all the datasets for a particular dashaboard being passed to the class - https://github.com/rdytech/superset-client/pull/28
|
6
|
+
|
7
|
+
## 0.1.5 - 2024-05-10
|
8
|
+
|
9
|
+
* add multi config for multi env creds https://github.com/rdytech/superset-client/pull/22
|
10
|
+
* add endpoint for sqllab/execute https://github.com/rdytech/superset-client/pull/22
|
11
|
+
* add endpoint for database/list https://github.com/rdytech/superset-client/pull/22
|
12
|
+
* add delete cascade endpoint by @jbat in https://github.com/rdytech/superset-client/pull/21
|
13
|
+
|
14
|
+
## 0.1.4 - 2024-05-01
|
15
|
+
|
16
|
+
* Filter dashboards by array of tags by @jbat in https://github.com/rdytech/superset-client/pull/20
|
17
|
+
* adds endpoints for Delete of dashboards, charts, datasets @jbat in https://github.com/rdytech/superset-client/pull/20
|
18
|
+
* adds endpoints for BulkDelete of dashboards, charts, datasets @jbat in https://github.com/rdytech/superset-client/pull/20
|
19
|
+
|
20
|
+
## 0.1.3 - 2024-04-23
|
21
|
+
|
22
|
+
* duplicate dashboard should also create embedded setting by @jbat in https://github.com/rdytech/superset-client/pull/14
|
23
|
+
* Validate and duplicate filters to new dashboard by @vidishaweddy-readytech in https://github.com/rdytech/superset-client/pull/17
|
24
|
+
* duplicate cross filters by @jbat in https://github.com/rdytech/superset-client/pull/18
|
25
|
+
|
26
|
+
## 0.1.2 - 2024-03-22
|
27
|
+
|
28
|
+
* adds export endpoint
|
29
|
+
|
30
|
+
## 0.1.1 - 2024-03-14
|
31
|
+
|
32
|
+
* superset pipeline part 1 with supported endpoints by @jbat in https://github.com/rdytech/superset-client/pull/4
|
33
|
+
* API update chart to new dataset by @hanpeic in https://github.com/rdytech/superset-client/pull/5
|
34
|
+
* Adds DuplicateDashboard class and fixes by @jbat in https://github.com/rdytech/superset-client/pull/6
|
35
|
+
* Update Docs by @jbat in https://github.com/rdytech/superset-client/pull/7
|
36
|
+
* update cred docs by @jbat in https://github.com/rdytech/superset-client/pull/8
|
37
|
+
* more updates to DuplicateDashboard, extra endpoints by @jbat in https://github.com/rdytech/superset-client/pull/9
|
38
|
+
|
39
|
+
## 0.1.0 - 2023-12-12
|
40
|
+
|
41
|
+
- add base classes for credentials, authentication, client, request
|
42
|
+
- add dashboard endpoints
|
43
|
+
- add security/user endpoints
|
44
|
+
- add security/role endpoints
|
45
|
+
- add security/role/permission endpoints
|
46
|
+
|
47
|
+
|
48
|
+
|
data/Dockerfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# 1: Use ruby 2.7 as base:
|
2
|
+
FROM ruby:2.7
|
3
|
+
|
4
|
+
RUN apt-get update && \
|
5
|
+
apt-get install -y --no-install-recommends \
|
6
|
+
build-essential
|
7
|
+
|
8
|
+
ENV BUNDLER_VERSION='2.4.22'
|
9
|
+
RUN gem install bundler -v ${BUNDLER_VERSION}
|
10
|
+
|
11
|
+
# 2: We'll set the application path as the working directory
|
12
|
+
WORKDIR /app
|
13
|
+
|
14
|
+
# 3: We'll add the app's binaries path to $PATH:
|
15
|
+
ENV PATH=$PATH:/app/bin
|
16
|
+
|
17
|
+
ENV BUNDLE_GITHUB__HTTPS=true BUNDLE_MAJOR_DEPRECATIONS=true
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2023 Jonathon Batson, ReadyTech
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
# Superset Client
|
2
|
+
|
3
|
+
[![Build status](https://badge.buildkite.com/fc7ee4a03e119a5d859472865fc0bdc9a6e46d51b7f5b8cd62.svg)](https://buildkite.com/jobready/superset-client)
|
4
|
+
|
5
|
+
The Repo is `superset-client` with the ruby gem named `superset`
|
6
|
+
|
7
|
+
All ruby classes are namespaced under `Superset::`
|
8
|
+
|
9
|
+
# Installation
|
10
|
+
|
11
|
+
## Docker Setup
|
12
|
+
|
13
|
+
Build, bundle and open a ruby console
|
14
|
+
|
15
|
+
```
|
16
|
+
docker-compose build
|
17
|
+
docker-compose run --rm app bundle install
|
18
|
+
docker-compose run --rm app bin/console
|
19
|
+
```
|
20
|
+
|
21
|
+
Run specs
|
22
|
+
|
23
|
+
```
|
24
|
+
docker-compose run --rm app rspec
|
25
|
+
# or
|
26
|
+
docker-compose run --rm app bash # then run 'bundle exec rspec' from the container.
|
27
|
+
```
|
28
|
+
|
29
|
+
## Local setup or including in a Ruby/Rails app
|
30
|
+
|
31
|
+
Add to your Gemfile `gem 'superset'`
|
32
|
+
And then execute: `bundle install`
|
33
|
+
Or install it yourself as `gem install superset`
|
34
|
+
|
35
|
+
## Setup API Credentials
|
36
|
+
|
37
|
+
Follow this doc setup your users API creds [setting_up_personal_api_credentials](https://github.com/rdytech/superset-client/tree/develop/doc/setting_up_personal_api_credentials.md)
|
38
|
+
|
39
|
+
Short version is .. copy the `env.sample` to `.env` and add edit values where applicable. Opening a console with `bin/console` will then auto load the `.env` file.
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
Experiment with the API calls directly by open a pry console using `bin/console`
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
### API calls
|
49
|
+
|
50
|
+
Quickstart examples
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
Superset::Database::List.call
|
54
|
+
Superset::Database::GetSchemas.new(1).list # get schemas for database 1
|
55
|
+
|
56
|
+
Superset::Dashboard::List.call
|
57
|
+
Superset::Dashboard::List.new(title_contains: 'Sales').list
|
58
|
+
|
59
|
+
Superset::Dashboard::BulkDelete.new(dashboard_ids: [1,2,3]).perform # Dashboards only ( leaves all charts, datasets in place)
|
60
|
+
Superset::Dashboard::BulkDeleteCascade.new(dashboard_ids: [1,2,3]).perform # Dashboards and related charts and datasets.
|
61
|
+
|
62
|
+
Superset::Sqllab::Execute.new(database_id: 1, schema: 'public', query: 'select count(*) from birth_names').perform
|
63
|
+
|
64
|
+
Superset::Dashboard::Export.new(dashboard_id: 1, destination_path: '/tmp').perform
|
65
|
+
|
66
|
+
Superset::RouteInfo.new(route: 'dashboard/_info').perform # Get info on an API endpoint .. handy for getting available filters
|
67
|
+
Superset::RouteInfo.new(route: 'chart/_info').filters # OR just get the filters for an endpoint
|
68
|
+
|
69
|
+
superset_class_list # helper method to list all classes under Superset::
|
70
|
+
|
71
|
+
```
|
72
|
+
|
73
|
+
### Duplicating Dashboards
|
74
|
+
|
75
|
+
Primary motivation behind this library was to use the Superset API to duplicate dashboards, charts, datasets across multiple database connections.
|
76
|
+
See examples in [Duplicate Dashboards](https://github.com/rdytech/superset-client/tree/develop/doc/duplicate_dashboards.md)
|
77
|
+
|
78
|
+
### API Examples with results
|
79
|
+
|
80
|
+
Generally classes follow the convention/path of the Superset API strucuture as per the swagger docs.
|
81
|
+
|
82
|
+
ref https://superset.apache.org/docs/api/
|
83
|
+
|
84
|
+
Limited support for filters is available on some list pages, primarily through param `title_contains`.
|
85
|
+
Pagination is supported via `page_num` param.
|
86
|
+
|
87
|
+
Primary methods across majority of api calls are
|
88
|
+
- response : the full API response
|
89
|
+
- result : just the result attribute array
|
90
|
+
- list : displays a formatted output to console, handy for quick investigation of objects
|
91
|
+
- call : is a class method to list on Get and List requests
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
# List all Databases
|
95
|
+
Superset::Database::List.call
|
96
|
+
# DEBUG -- : Happi: GET https://your-superset-host/api/v1/database/?q=(page:0,page_size:100), {}
|
97
|
+
+----+------------------------------------+------------+------------------+
|
98
|
+
| Superset::Database::List |
|
99
|
+
+----+------------------------------------+------------+------------------+
|
100
|
+
| Id | Database name | Backend | Expose in sqllab |
|
101
|
+
+----+------------------------------------+------------+------------------+
|
102
|
+
| 1 | examples | postgresql | true |
|
103
|
+
+----+------------------------------------+------------+------------------+
|
104
|
+
|
105
|
+
# List database schemas for Database 1
|
106
|
+
Superset::Database::GetSchemas.new(1).list
|
107
|
+
# DEBUG -- : Happi: GET https://your-superset-host/api/v1/database/1/schemas/, {}
|
108
|
+
=> ["information_schema", "public"]
|
109
|
+
|
110
|
+
# List dashboards
|
111
|
+
Superset::Dashboard::List.call
|
112
|
+
# PAGE_SIZE is set to 100, so get the second set of 100 dashboards with
|
113
|
+
Superset::Dashboard::List.new(page_num: 1).list
|
114
|
+
# OR filter by title
|
115
|
+
Superset::Dashboard::List.new(title_contains: 'Sales').list
|
116
|
+
# DEBUG -- : Happi: GET https://your-superset-host/api/v1/dashboard/?q=(filters:!((col:dashboard_title,opr:ct,value:'Sales')),page:0,page_size:100), {}
|
117
|
+
|
118
|
+
+-----+------------------------------+-----------+--------------------------------------------------------------------+
|
119
|
+
| Superset::Dashboard::List |
|
120
|
+
+-----+------------------------------+-----------+--------------------------------------------------------------------+
|
121
|
+
| Id | Dashboard title | Status | Url |
|
122
|
+
+-----+------------------------------+-----------+--------------------------------------------------------------------+
|
123
|
+
| 6 | Video Game Sales | published | https://your-superset-host/superset/dashboard/6/ |
|
124
|
+
| 8 | Sales Dashboard | published | https://your-superset-host/superset/dashboard/8/ |
|
125
|
+
+-----+------------------------------+-----------+--------------------------------------------------------------------+
|
126
|
+
|
127
|
+
|
128
|
+
Superset::Dashboard::Get.call(1) # same as Superset::Dashboard::Get.new(1).list
|
129
|
+
+----------------------------+
|
130
|
+
| World Banks Data |
|
131
|
+
+----------------------------+
|
132
|
+
| Charts |
|
133
|
+
+----------------------------+
|
134
|
+
| % Rural |
|
135
|
+
| Region Filter |
|
136
|
+
| Life Expectancy VS Rural % |
|
137
|
+
| Box plot |
|
138
|
+
| Most Populated Countries |
|
139
|
+
| Worlds Population |
|
140
|
+
| Worlds Pop Growth |
|
141
|
+
| Rural Breakdown |
|
142
|
+
| Treemap |
|
143
|
+
| Growth Rate |
|
144
|
+
+----------------------------+
|
145
|
+
|
146
|
+
|
147
|
+
```
|
148
|
+
## Optional Credential setup for Embedded User
|
149
|
+
|
150
|
+
Primary usage is for api calls and/or for guest token retrieval when setting up applications to use the superset embedded dashboard workflow.
|
151
|
+
|
152
|
+
The Superset API users fall into 2 categories
|
153
|
+
- a user for general api calls to endpoints for Dashboards, Datasets, Charts, Users, Roles etc.
|
154
|
+
ref `Superset::Credential::ApiUser`
|
155
|
+
which pulls credentials from `ENV['SUPERSET_API_USERNAME']` and `ENV['SUPERSET_API_PASSWORD']`
|
156
|
+
|
157
|
+
- a user for guest token api call to use when embedding dashboards in a host application.
|
158
|
+
ref `Superset::Credential::EmbeddedUser`
|
159
|
+
which pulls credentials from `ENV['SUPERSET_EMBEDDED_USERNAME']` and `ENV['SUPERSET_EMBEDDED_PASSWORD']`
|
160
|
+
|
161
|
+
|
162
|
+
### Fetch a Guest Token for Embedded user
|
163
|
+
|
164
|
+
Assuming you have setup your Dashboard in Superset to be embedded and that your creds are setup in
|
165
|
+
`ENV['SUPERSET_EMBEDDED_USERNAME']` and `ENV['SUPERSET_EMBEDDED_PASSWORD']`
|
166
|
+
|
167
|
+
```
|
168
|
+
Superset::GuestToken.new(embedded_dashboard_id: '15').guest_token
|
169
|
+
=> "eyJ0eXAiOi............VV4mrMfsvg"
|
170
|
+
```
|
171
|
+
|
172
|
+
## Releasing a new version
|
173
|
+
|
174
|
+
On develop branch make sure to update `Superset::VERSION` and `CHANGELOG.md` with the new version number and changes.
|
175
|
+
Build the new version and upload to gemfury.
|
176
|
+
|
177
|
+
`gem build superset.gemspec`
|
178
|
+
|
179
|
+
### Publishing to RubyGems
|
180
|
+
|
181
|
+
WIP .. direction is for this gem to be made public
|
182
|
+
|
183
|
+
### ReadyTech private Gemfury repo
|
184
|
+
|
185
|
+
ReadyTech hosts its own private gemfury remote repo.
|
186
|
+
|
187
|
+
Get the latest develop into master
|
188
|
+
|
189
|
+
git checkout master
|
190
|
+
git pull
|
191
|
+
git fetch
|
192
|
+
git merge origin/develop
|
193
|
+
|
194
|
+
Tag the version and push to github
|
195
|
+
|
196
|
+
git tag -a -m "Version 0.1.0" v0.1.0
|
197
|
+
git push origin master --tags
|
198
|
+
|
199
|
+
Push to gemfury or upload the build manually in the gemfury site.
|
200
|
+
|
201
|
+
git push fury master
|
202
|
+
|
203
|
+
## License
|
204
|
+
|
205
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
# Duplicating Dashboards to a new database or schema
|
2
|
+
|
3
|
+
The problem!
|
4
|
+
|
5
|
+
Given a multi tenant configuration where clients databases are logically separate dbs and or schemas all configured in Superset,
|
6
|
+
copying or duplicating an existing Superset dashboard to a new database is a fairly laborious operation with many manual steps.
|
7
|
+
|
8
|
+
Usually run in the Superset GUI something like :
|
9
|
+
- Create Dashboard (template)
|
10
|
+
- Duplicate the template in GUI with Edit->Save As (duplicate charts checked)
|
11
|
+
- Duplicate all Datasets from template, Edit each and point to the new target database
|
12
|
+
- Edit all the new charts created and link them to the new datasets.
|
13
|
+
- Setup the embedded settings for new dashboard
|
14
|
+
- Add new tags for the new dashboard
|
15
|
+
|
16
|
+
Give the need for multiple clients, 10s or 100s, or 1000s, this quickly becomes a laborious and time consuming feat.
|
17
|
+
|
18
|
+
Superset API to the rescue.
|
19
|
+
|
20
|
+
Note .. requires setup of your [superset environment credentials](https://github.com/rdytech/superset-client/blob/develop/doc/setting_up_personal_api_credentials.md)
|
21
|
+
|
22
|
+
## The Solution
|
23
|
+
|
24
|
+
Essentially we perform the same points above but all via the Superset API.
|
25
|
+
|
26
|
+
The examples video game dashboard was adjusted to have only 1 chart.
|
27
|
+
Output is new new_dashboard_id and url. Logs provided in `log/superset-client.log`
|
28
|
+
|
29
|
+
Given you have a dashboard created, ie `source_dashboard_id`
|
30
|
+
and you know your `target_schema`
|
31
|
+
as well as your `target_database_id`
|
32
|
+
then you could go ahead and run something like this.
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
Superset::Services::DuplicateDashboard.new(
|
38
|
+
source_dashboard_id: 90,
|
39
|
+
target_schema: 'public',
|
40
|
+
target_database_id: 2
|
41
|
+
).perform
|
42
|
+
|
43
|
+
=> {:new_dashboard_id=>401, :new_dashboard_url=>"https://your-superset-host/superset/dashboard/401/", :published=>false}
|
44
|
+
|
45
|
+
# logfile shows the steps taken
|
46
|
+
|
47
|
+
# cat log/superset-client.log
|
48
|
+
# INFO -- : >>>>>>>>>>>>>>>>> Starting DuplicateDashboard Service <<<<<<<<<<<<<<<<<<<<<<
|
49
|
+
# INFO -- : Source Dashboard URL: https://your-superset-host/superset/dashboard/90/
|
50
|
+
# INFO -- : Duplicating dashboard 90 into Target Schema: public in database 2
|
51
|
+
# INFO -- : Copy Dashboard/Charts Completed - New Dashboard ID: 401
|
52
|
+
# INFO -- : Duplicating Source Dataset examples.video_game_sales with id 11
|
53
|
+
# INFO -- : Finished. Duplicate Dataset Name video_game_sales-example_two with id 542
|
54
|
+
# INFO -- : Validating Dataset ID: 542 schema update to public on Database: 2
|
55
|
+
# INFO -- : Successfully updated dataset schema to public on Database: 2
|
56
|
+
# INFO -- : Updating Charts to point to New Datasets and updating Dashboard json_metadata ...
|
57
|
+
# INFO -- : Update Chart 55752 to new dataset_id 542
|
58
|
+
# INFO -- : Updated new Dashboard json_metadata charts with new dataset ids
|
59
|
+
# INFO -- : Duplication Successful. New Dashboard URL: https://your-superset-host/superset/dashboard/401/
|
60
|
+
# INFO -- : >>>>>>>>>>>>>>>>> Finished DuplicateDashboard Service <<<<<<<<<<<<<<<<<<<<<<
|
61
|
+
|
62
|
+
```
|
63
|
+
|
64
|
+
## Other options for embedded workflow and tags
|
65
|
+
|
66
|
+
If your using the embedded dashboards you can also provied attributes for
|
67
|
+
- allowed domains for embeded dashboard settings
|
68
|
+
- database tags for ease of searching
|
69
|
+
- option to publish
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
Superset::Services::DuplicateDashboard.new(
|
73
|
+
source_dashboard_id: 37,
|
74
|
+
target_schema: 'public',
|
75
|
+
target_database_id: 2,
|
76
|
+
allowed_domains: ["https://wylee-coyote-domain/"],
|
77
|
+
tags: ["product:acme_fu", "client:wylee_coyote", "embedded"],
|
78
|
+
publish: true
|
79
|
+
).perform
|
80
|
+
```
|
81
|
+
|
82
|
+
### What is my Database ID ?
|
83
|
+
|
84
|
+
``` ruby
|
85
|
+
# list your available databases with
|
86
|
+
Superset::Database::List.call
|
87
|
+
|
88
|
+
# DEBUG -- : Happi: GET https://your-superset-host/api/v1/database/?q=(page:0,page_size:100), {}
|
89
|
+
+----+------------------------------------+------------+------------------+
|
90
|
+
| Superset::Database::List |
|
91
|
+
+----+------------------------------------+------------+------------------+
|
92
|
+
| Id | Database name | Backend | Expose in sqllab |
|
93
|
+
+----+------------------------------------+------------+------------------+
|
94
|
+
| 1 | examples | postgresql | true |
|
95
|
+
| 2 | examples_two | postgresql | true |
|
96
|
+
+----+------------------------------------+------------+------------------+
|
97
|
+
|
98
|
+
# optionally provide a title filter
|
99
|
+
Superset::Database::List.new(title_contains: 'examples_two').list
|
100
|
+
|
101
|
+
# DEBUG -- : Happi: GET https://your-superset-host/api/v1/database/?q=(filters:!((col:database_name,opr:ct,value:'examples')),page:0,page_size:100), {}
|
102
|
+
+----+------------------------------------+------------+------------------+
|
103
|
+
| Superset::Database::List |
|
104
|
+
+----+------------------------------------+------------+------------------+
|
105
|
+
| Id | Database name | Backend | Expose in sqllab |
|
106
|
+
+----+------------------------------------+------------+------------------+
|
107
|
+
| 2 | examples_two | postgresql | true |
|
108
|
+
+----+------------------------------------+------------+------------------+
|
109
|
+
|
110
|
+
```
|
111
|
+
|
112
|
+
### What Dashboards do I have access to ?
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
# list dashboard with
|
116
|
+
Superset::Dashboard::List.call
|
117
|
+
# DEBUG -- : Happi: GET https://your-superset-host/api/v1/dashboard/?q=(page:0,page_size:100), {}
|
118
|
+
+-----+------------------------------------------------------+-----------+--------------------------------------------------------------------+
|
119
|
+
| Superset::Dashboard::List |
|
120
|
+
+-----+------------------------------------------------------+-----------+--------------------------------------------------------------------+
|
121
|
+
| Id | Dashboard title | Status | Url |
|
122
|
+
+-----+------------------------------------------------------+-----------+--------------------------------------------------------------------+
|
123
|
+
| 20 | Baby Names | draft | https://your-superset-host/superset/dashboard/20/ |
|
124
|
+
| 6 | Video Game Sales | published | https://your-superset-host/superset/dashboard/6/ |
|
125
|
+
| 5 | COVID Vaccine Dashboard | published | https://your-superset-host/superset/dashboard/5/ |
|
126
|
+
| 9 | Superset Project Slack Dashboard | published | https://your-superset-host/superset/dashboard/9/ |
|
127
|
+
+-----+------------------------------------------------------+-----------+--------------------------------------------------------------------+
|
128
|
+
|
129
|
+
# or filter by title
|
130
|
+
Superset::Dashboard::List.new(title_contains: 'video').list
|
131
|
+
# DEBUG -- : Happi: GET https://your-superset-host/api/v1/dashboard/?q=(filters:!((col:dashboard_title,opr:ct,value:'video')),page:0,page_size:100), {}
|
132
|
+
+----+------------------+-----------+------------------------------------------------------------------+
|
133
|
+
| Superset::Dashboard::List |
|
134
|
+
+----+------------------+-----------+------------------------------------------------------------------+
|
135
|
+
| Id | Dashboard title | Status | Url |
|
136
|
+
+----+------------------+-----------+------------------------------------------------------------------+
|
137
|
+
| 6 | Video Game Sales | published | https://your-superset-host/superset/dashboard/6/ |
|
138
|
+
+----+------------------+-----------+------------------------------------------------------------------+
|
139
|
+
|
140
|
+
```
|
141
|
+
|
142
|
+
### Replicate a Dashboard across all schemas
|
143
|
+
|
144
|
+
With a bit of ruby ...
|
145
|
+
|
146
|
+
Duplicate dashboard across all schemas in acme pools 1,2,3.
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
acme_dbs = Superset::Database::List.new(title_contains: 'acme').rows
|
150
|
+
=> [["7", "acme-pool1", "postgresql", "true"],
|
151
|
+
["8", "acme-pool2", "postgresql", "true"],
|
152
|
+
["9", "acme-pool3", "postgresql", "true"]]
|
153
|
+
|
154
|
+
ignore_system_tables = ['information_schema', 'shared_extensions'] # postgres system schemas
|
155
|
+
|
156
|
+
db_with_schemas = acme_dbs.map do |db_conn|
|
157
|
+
Superset::Database::GetSchemas.new(db_conn[0]).list.map do |schema|
|
158
|
+
{ database_id: db_conn[0], schema: schema, database_name: db_conn[1] } unless ignore_system_tables.include?(schema)
|
159
|
+
end.compact
|
160
|
+
end.flatten
|
161
|
+
|
162
|
+
=>[{:database_id=>"7", :schema=>"client1", :database_name=>"acme-pool1"},
|
163
|
+
{:database_id=>"7", :schema=>"client2", :database_name=>"acme-pool1"},
|
164
|
+
{:database_id=>"7", :schema=>"client3", :database_name=>"acme-pool1"},
|
165
|
+
{:database_id=>"8", :schema=>"client4", :database_name=>"acme-pool1"},
|
166
|
+
{:database_id=>"8", :schema=>"client5", :database_name=>"acme-pool2"},
|
167
|
+
{:database_id=>"8", :schema=>"client6", :database_name=>"acme-pool2"},
|
168
|
+
{:database_id=>"9", :schema=>"client7", :database_name=>"acme-pool3"},
|
169
|
+
{:database_id=>"9", :schema=>"client8", :database_name=>"acme-pool3"},
|
170
|
+
{:database_id=>"9", :schema=>"client9", :database_name=>"acme-pool3"},
|
171
|
+
{:database_id=>"9", :schema=>"client10", :database_name=>"acme-pool3"}]
|
172
|
+
|
173
|
+
db_with_schemas.each do |conn|
|
174
|
+
Superset::Services::DuplicateDashboard.new(
|
175
|
+
source_dashboard_id: 90,
|
176
|
+
target_schema: conn[:schema],
|
177
|
+
target_database_id: conn[:database_id]
|
178
|
+
).perform
|
179
|
+
end
|
180
|
+
|
181
|
+
```
|
182
|
+
|
183
|
+
## TODO / ISSUES
|
184
|
+
|
185
|
+
### Handling Change
|
186
|
+
|
187
|
+
Dashboards are an ever evolving animal and they are expected to change.
|
188
|
+
|
189
|
+
This raises the question, given I have a template dashboard and I have X number of replicas of that dashboard
|
190
|
+
how do I make a change to the template and get the change updated to each of the replicas?
|
191
|
+
|
192
|
+
Current direction is to separate these "changes" in to 2 categories.
|
193
|
+
|
194
|
+
- Firstly: minor chages to a Dataset query that will not result in breaking a chart.
|
195
|
+
ie .. adjusting the logic of the query but not the output attributes.
|
196
|
+
- Secondly: ... everything else.
|
197
|
+
ie .. editing/adding charts, formating the dashboard, updating the datasets with new attributes for new charts
|
198
|
+
|
199
|
+
For the first case, the Superset API can easily locate each Dashboards Dataset and update the query with the changes.
|
200
|
+
This is a fairly simple procedure.
|
201
|
+
|
202
|
+
For the second case, currently we can see no easy/clear direction forward.
|
203
|
+
Very happy to have others with more experience in Superset pose suggestions.
|
204
|
+
|
205
|
+
Putting it simply, the current thinking is to delete all the replica dashboards and recreate them.
|
206
|
+
|
207
|
+
### Bringing the Duplicate Dashboard process into Superset core
|
208
|
+
|
209
|
+
(WIP) The goal would be to have the DuplicateDashboard process as a part of the core superset codebase.
|
210
|
+
|
211
|
+
To that end this Superset Improvement Proposal (SIP) .. is a starting point.
|
212
|
+
|
213
|
+
{add SIP request here}
|
214
|
+
|