power-bi 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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