power-bi 0.0.0 → 0.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 775da73d3b4bd60238d697acb445bff20f5326c312f09103dcd1588470c1be3b
4
- data.tar.gz: 61d0ca711744223fb780b1e28918865773aae2f6e1077ce6fc11c05b8c460d4f
3
+ metadata.gz: 97631e0f44964ce0b4d23675e5a023ff203456d7881fea9a2f425441ac4ede8c
4
+ data.tar.gz: 86c3f858e9c34ec5bebd67659f803a60d2303037ddb9f7ffd9e2eb3af13624eb
5
5
  SHA512:
6
- metadata.gz: dbe587141c379fafcdbc27efb1aff73b26cdf54aa6c8d66afc96d1542c9cf161014cef8fd3c1a2ffba67c9316f8159055a527e4d42d1d7d6b0bb02fa95aeb1a6
7
- data.tar.gz: 6817a28f27dcf77f022877996b61ff25030bcef8ccfabf256ee67769a53fb449cc6858891fa8c3496e21f625bf0a20d751172ccebf912e94ffcf96fc5a54bc99
6
+ metadata.gz: c07b1a99e33190aa95e9cc4f4131a2cf9a7f875d2143b806e9e01fe0e1af1866dbd8785aea00f2d46765237431822d5814ff563c13cc9d4bc86ded7173b68798
7
+ data.tar.gz: dc17f34a6ba983869a2e2e48ee90de87a8c2f1f55982e40fa1f323e6e83e6e71cf119b32fdb2a2a0c658d89adb4933b5d89649eef1435e50b0233d2e95254c70
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Lode Cools
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.
@@ -0,0 +1,33 @@
1
+ module PowerBI
2
+
3
+ class Array
4
+
5
+ def initialize(tenant)
6
+ @fulfilled = false
7
+ @content = nil
8
+ @tenant = tenant
9
+ end
10
+
11
+ def reload
12
+ @fulfilled = false
13
+ @content = nil
14
+ self
15
+ end
16
+
17
+ private
18
+
19
+ def get_content
20
+ unless @fulfilled
21
+ klass = self.class.get_class
22
+ @content = get_data.map { |d| klass.new(@tenant, d)}
23
+ @fulfilled = true
24
+ end
25
+ @content
26
+ end
27
+
28
+ def method_missing(method, *args, &block)
29
+ get_content.send(method, *args, &block)
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,61 @@
1
+ module PowerBI
2
+ class Dataset
3
+ attr_reader :id, :name, :add_rows_API_enabled, :configured_by, :is_refreshable, :is_effective_identity_required,
4
+ :is_effective_identity_roles_required, :is_on_prem_gateway_required, :target_storage_mode, :workspace, :datasources,
5
+ :parameters
6
+
7
+ def initialize(tenant, data)
8
+ @id = data[:id]
9
+ @name = data[:name]
10
+ @add_rows_API_enabled = data[:addRowsAPIEnabled]
11
+ @configured_by = data[:configuredBy]
12
+ @is_refreshable = data[:isRefreshable]
13
+ @is_effective_identity_required = data[:isEffectiveIdentityRequired]
14
+ @is_effective_identity_roles_required = data[:isEffectiveIdentityRolesRequired]
15
+ @is_on_prem_gateway_required = data[:isOnPremGatewayRequired]
16
+ @target_storage_mode = data[:targetStorageMode]
17
+ @workspace = data[:workspace]
18
+ @tenant = tenant
19
+ @datasources = DatasourceArray.new(@tenant, self)
20
+ @parameters = ParameterArray.new(@tenant, self)
21
+ end
22
+
23
+ def update_parameter(name, value)
24
+ @tenant.post("/groups/#{workspace.id}/datasets/#{id}/Default.UpdateParameters") do |req|
25
+ req.body = {
26
+ updateDetails: [{name: name, newValue: value.to_s}]
27
+ }.to_json
28
+ end
29
+ @parameters.reload
30
+ true
31
+ end
32
+
33
+
34
+ def refresh
35
+ @tenant.post("/groups/#{workspace.id}/datasets/#{id}/refreshes") do |req|
36
+ req.body = {
37
+ notifyOption: "NoNotification"
38
+ }.to_json
39
+ end
40
+ true
41
+ end
42
+
43
+ end
44
+
45
+ class DatasetArray < Array
46
+
47
+ def initialize(tenant, workspace)
48
+ super(tenant)
49
+ @workspace = workspace
50
+ end
51
+
52
+ def self.get_class
53
+ Dataset
54
+ end
55
+
56
+ def get_data
57
+ data = @tenant.get("/groups/#{@workspace.id}/datasets")[:value]
58
+ data.each { |d| d[:workspace] = @workspace }
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,30 @@
1
+ module PowerBI
2
+ class Datasource
3
+ attr_reader :gateway_id, :datasource_id, :datasource_type, :connection_details
4
+
5
+ def initialize(tenant, data)
6
+ @gateway_id = data[:gatewayId]
7
+ @datasource_type = data[:datasourceType]
8
+ @connection_details = data[:connectionDetails]
9
+ @datasource_id = data[:datasourceId]
10
+ @tenant = tenant
11
+ end
12
+
13
+ end
14
+
15
+ class DatasourceArray < Array
16
+
17
+ def initialize(tenant, dataset)
18
+ super(tenant)
19
+ @dataset = dataset
20
+ end
21
+
22
+ def self.get_class
23
+ Datasource
24
+ end
25
+
26
+ def get_data
27
+ @tenant.get("/groups/#{@dataset.workspace.id}/datasets/#{@dataset.id}/datasources")[:value]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ module PowerBI
2
+ class Parameter
3
+ attr_reader :name, :type, :is_required, :current_value
4
+
5
+ def initialize(tenant, data)
6
+ @name = data[:name]
7
+ @type = data[:type]
8
+ @is_required = data[:isRequired]
9
+ @current_value = data[:currentValue]
10
+ end
11
+
12
+ end
13
+
14
+ class ParameterArray < Array
15
+
16
+ def initialize(tenant, dataset)
17
+ super(tenant)
18
+ @dataset = dataset
19
+ end
20
+
21
+ def self.get_class
22
+ Parameter
23
+ end
24
+
25
+ def get_data
26
+ @tenant.get("/groups/#{@dataset.workspace.id}/datasets/#{@dataset.id}/parameters")[:value]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,48 @@
1
+ module PowerBI
2
+ class Report
3
+ attr_reader :name, :id, :report_type, :web_url, :embed_url, :is_from_pbix, :is_owned_by_me, :dataset_id, :workspace
4
+
5
+ def initialize(tenant, data)
6
+ @id = data[:id]
7
+ @report_type = data[:reportType]
8
+ @name = data[:name]
9
+ @web_url = data[:webUrl]
10
+ @embed_url = data[:embedUrl]
11
+ @is_from_pbix = data[:isFromPbix]
12
+ @is_owned_by_me = data[:isOwnedByMe]
13
+ @dataset_id = data[:datasetId]
14
+ @workspace = data[:workspace]
15
+ @tenant = tenant
16
+ end
17
+
18
+ def clone(target_workspace, new_report_name)
19
+ data = @tenant.post("/reports/#{@id}/Clone") do |req|
20
+ req.body = {
21
+ name: new_report_name,
22
+ targetWorkspaceId: target_workspace.id
23
+ }.to_json
24
+ end
25
+ target_workspace.reports.reload
26
+ data[:workspace] = target_workspace
27
+ Report.new(@tenant, data)
28
+ end
29
+
30
+ end
31
+
32
+ class ReportArray < Array
33
+
34
+ def initialize(tenant, workspace)
35
+ super(tenant)
36
+ @workspace = workspace
37
+ end
38
+
39
+ def self.get_class
40
+ Report
41
+ end
42
+
43
+ def get_data
44
+ data = @tenant.get("/groups/#{@workspace.id}/reports")[:value]
45
+ data.each { |d| d[:workspace] = @workspace }
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,65 @@
1
+ module PowerBI
2
+ class Tenant
3
+ attr_reader :workspaces
4
+
5
+ def initialize(token_generator)
6
+ @token_generator = token_generator
7
+ @workspaces = WorkspaceArray.new(self)
8
+ end
9
+
10
+ def get(url, params = {})
11
+ response = Faraday.get(PowerBI::BASE_URL + url) do |req|
12
+ req.params = params
13
+ req.headers['Accept'] = 'application/json'
14
+ req.headers['authorization'] = "Bearer #{token}"
15
+ yield req if block_given?
16
+ end
17
+ if response.status != 200
18
+ raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
19
+ end
20
+ unless response.body.empty?
21
+ JSON.parse(response.body, symbolize_names: true)
22
+ end
23
+ end
24
+
25
+ def post(url, params = {})
26
+ response = Faraday.post(PowerBI::BASE_URL + url) do |req|
27
+ req.params = params
28
+ req.headers['Accept'] = 'application/json'
29
+ req.headers['Content-Type'] = 'application/json'
30
+ req.headers['authorization'] = "Bearer #{token}"
31
+ yield req if block_given?
32
+ end
33
+ unless [200, 202].include? response.status
34
+ raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
35
+ end
36
+ unless response.body.empty?
37
+ JSON.parse(response.body, symbolize_names: true)
38
+ end
39
+ end
40
+
41
+ def post_file(url, file, params = {})
42
+ conn = Faraday.new do |f|
43
+ f.request :multipart
44
+ end
45
+ response = conn.post(PowerBI::BASE_URL + url) do |req|
46
+ req.params = params
47
+ req.headers['Accept'] = 'application/json'
48
+ req.headers['Content-Type'] = 'multipart/form-data'
49
+ req.headers['authorization'] = "Bearer #{token}"
50
+ req.body = {value: Faraday::UploadIO.new(file, 'application/octet-stream')}
51
+ end
52
+ if response.status != 202
53
+ raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
54
+ end
55
+ JSON.parse(response.body, symbolize_names: true)
56
+ end
57
+
58
+ private
59
+
60
+ def token
61
+ @token_generator.call
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,53 @@
1
+ module PowerBI
2
+ class Workspace
3
+ attr_reader :name, :is_read_only, :is_on_dedicated_capacity, :id, :reports, :datasets
4
+
5
+ class UploadError < PowerBI::Error ; end
6
+
7
+ def initialize(tenant, data)
8
+ @id = data[:id]
9
+ @is_read_only = data[:isReadOnly]
10
+ @is_on_dedicated_capacity = data[:isOnDedicatedCapacity]
11
+ @name = data[:name]
12
+ @tenant = tenant
13
+ @reports = ReportArray.new(@tenant, self)
14
+ @datasets = DatasetArray.new(@tenant, self)
15
+ end
16
+
17
+ def upload_pbix(file, dataset_name)
18
+ data = @tenant.post_file("/groups/#{@id}/imports", file, {datasetDisplayName: dataset_name})
19
+ import_id = data[:id]
20
+ success = false
21
+ iterations = 0
22
+ while !success
23
+ sleep 0.1
24
+ iterations += 1
25
+ raise UploadError if iterations > 300 # 30 seconds
26
+ status = @tenant.get("/groups/#{@id}/imports/#{import_id}")
27
+ success = (status[:importState] == "Succeeded")
28
+ end
29
+ @reports.reload
30
+ @datasets.reload
31
+ true
32
+ end
33
+
34
+ end
35
+
36
+ class WorkspaceArray < Array
37
+ def self.get_class
38
+ Workspace
39
+ end
40
+
41
+ def create(name)
42
+ data = @tenant.post("/groups", {workspaceV2: 'True'}) do |req|
43
+ req.body = {name: name}.to_json
44
+ end
45
+ self.reload
46
+ Workspace.new(@tenant, data)
47
+ end
48
+
49
+ def get_data
50
+ @tenant.get("/groups")[:value]
51
+ end
52
+ end
53
+ end
data/lib/power-bi.rb CHANGED
@@ -1,5 +1,18 @@
1
- class PowerBi
2
- def self.hi
3
- puts "Hello Power BI world!"
4
- end
5
- end
1
+ require 'pry' # TODO remove in final product
2
+ require 'faraday'
3
+ require 'json'
4
+
5
+ module PowerBI
6
+ BASE_URL = 'https://api.powerbi.com/v1.0/myorg'
7
+
8
+ class Error < StandardError ; end
9
+ class APIError < Error ; end
10
+ end
11
+
12
+ require_relative "power-bi/tenant"
13
+ require_relative "power-bi/array"
14
+ require_relative "power-bi/workspace"
15
+ require_relative "power-bi/report"
16
+ require_relative "power-bi/dataset"
17
+ require_relative "power-bi/datasource"
18
+ require_relative "power-bi/parameter"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: power-bi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lode Cools
@@ -9,15 +9,51 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2020-01-27 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Ruby wrapper for the Power BI API
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: webmock
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ description: Ruby wrapper for the Power BI API - Currently supports workspaces
14
42
  email: lode.cools1@gmail.com
15
43
  executables: []
16
44
  extensions: []
17
45
  extra_rdoc_files: []
18
46
  files:
47
+ - LICENSE
19
48
  - README.md
20
49
  - lib/power-bi.rb
50
+ - lib/power-bi/array.rb
51
+ - lib/power-bi/dataset.rb
52
+ - lib/power-bi/datasource.rb
53
+ - lib/power-bi/parameter.rb
54
+ - lib/power-bi/report.rb
55
+ - lib/power-bi/tenant.rb
56
+ - lib/power-bi/workspace.rb
21
57
  homepage: https://github.com/piloos/power-bi
22
58
  licenses:
23
59
  - MIT