superset 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.buildkite/pipeline.yml +16 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +13 -0
  5. data/CHANGELOG.md +48 -0
  6. data/Dockerfile +17 -0
  7. data/LICENSE +21 -0
  8. data/README.md +205 -0
  9. data/Rakefile +12 -0
  10. data/doc/duplicate_dashboards.md +214 -0
  11. data/doc/setting_up_personal_api_credentials.md +127 -0
  12. data/docker-compose.override.yml +10 -0
  13. data/docker-compose.yml +8 -0
  14. data/env.sample +9 -0
  15. data/lib/loggers/duplicate_dashboard_logger.rb +15 -0
  16. data/lib/superset/authenticator.rb +55 -0
  17. data/lib/superset/chart/bulk_delete.rb +40 -0
  18. data/lib/superset/chart/delete.rb +30 -0
  19. data/lib/superset/chart/get.rb +56 -0
  20. data/lib/superset/chart/list.rb +59 -0
  21. data/lib/superset/chart/update_dataset.rb +90 -0
  22. data/lib/superset/client.rb +53 -0
  23. data/lib/superset/credential/api_user.rb +25 -0
  24. data/lib/superset/credential/embedded_user.rb +25 -0
  25. data/lib/superset/dashboard/bulk_delete.rb +42 -0
  26. data/lib/superset/dashboard/bulk_delete_cascade.rb +52 -0
  27. data/lib/superset/dashboard/charts/list.rb +47 -0
  28. data/lib/superset/dashboard/compare.rb +94 -0
  29. data/lib/superset/dashboard/copy.rb +78 -0
  30. data/lib/superset/dashboard/datasets/list.rb +74 -0
  31. data/lib/superset/dashboard/delete.rb +42 -0
  32. data/lib/superset/dashboard/embedded/get.rb +56 -0
  33. data/lib/superset/dashboard/embedded/put.rb +35 -0
  34. data/lib/superset/dashboard/export.rb +98 -0
  35. data/lib/superset/dashboard/get.rb +51 -0
  36. data/lib/superset/dashboard/info.rb +17 -0
  37. data/lib/superset/dashboard/list.rb +99 -0
  38. data/lib/superset/dashboard/put.rb +37 -0
  39. data/lib/superset/dashboard/warm_up_cache.rb +42 -0
  40. data/lib/superset/database/get.rb +30 -0
  41. data/lib/superset/database/get_schemas.rb +25 -0
  42. data/lib/superset/database/list.rb +51 -0
  43. data/lib/superset/dataset/bulk_delete.rb +41 -0
  44. data/lib/superset/dataset/create.rb +62 -0
  45. data/lib/superset/dataset/delete.rb +30 -0
  46. data/lib/superset/dataset/duplicate.rb +62 -0
  47. data/lib/superset/dataset/get.rb +56 -0
  48. data/lib/superset/dataset/list.rb +41 -0
  49. data/lib/superset/dataset/update_query.rb +56 -0
  50. data/lib/superset/dataset/update_schema.rb +120 -0
  51. data/lib/superset/dataset/warm_up_cache.rb +41 -0
  52. data/lib/superset/display.rb +42 -0
  53. data/lib/superset/enumerations/object_type.rb +11 -0
  54. data/lib/superset/file_utilities.rb +19 -0
  55. data/lib/superset/guest_token.rb +69 -0
  56. data/lib/superset/logger.rb +20 -0
  57. data/lib/superset/request.rb +62 -0
  58. data/lib/superset/route_info.rb +34 -0
  59. data/lib/superset/security/permissions_resources/list.rb +22 -0
  60. data/lib/superset/security/role/create.rb +25 -0
  61. data/lib/superset/security/role/get.rb +32 -0
  62. data/lib/superset/security/role/list.rb +45 -0
  63. data/lib/superset/security/role/permission/create.rb +35 -0
  64. data/lib/superset/security/role/permission/get.rb +37 -0
  65. data/lib/superset/security/user/create.rb +49 -0
  66. data/lib/superset/security/user/get.rb +27 -0
  67. data/lib/superset/security/user/list.rb +42 -0
  68. data/lib/superset/services/duplicate_dashboard.rb +298 -0
  69. data/lib/superset/sqllab/execute.rb +52 -0
  70. data/lib/superset/tag/add_to_object.rb +46 -0
  71. data/lib/superset/tag/get.rb +30 -0
  72. data/lib/superset/tag/list.rb +37 -0
  73. data/lib/superset/version.rb +5 -0
  74. data/lib/superset.rb +17 -0
  75. data/log/README.md +4 -0
  76. data/superset.gemspec +55 -0
  77. 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
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
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,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -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
+