power-bi 1.3.1 → 1.6.1

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: 1d25a34c3688310fb090dccae322ca49f7a48312246f3793b4e59cba25fd75a1
4
- data.tar.gz: 5edb3f13333c5319f44fdac97769d3b5ee2adbb59f03296ceb664bc729017e77
3
+ metadata.gz: ffdc95c611d1fc25b04ce01028a873ed5dc3b9a2d23d57129c439146c9fd7a02
4
+ data.tar.gz: 20a9328435110d6aaf8c26bb1ac5c622db65a9a1b137815e2546cccee7281033
5
5
  SHA512:
6
- metadata.gz: db57e4e5fb379b3cab50becc7060d19caf48cbcd366aa2231829c988ff448af01cf40ab9f189c8607b26bfaa8c96a8efd14df3d3337d1bbc257fc41315386637
7
- data.tar.gz: 390c4de1b57462be8817be336b35de6e24e488569cad47936d116efc922e382b804c71b16717bbe31fb38aa486e3a946ad69a9816055832da90507f2cf1a4678
6
+ metadata.gz: 9a3dca6fd7fe5cb3d15251b84d8de13d1613b8104b4638f52f5957b45de92628911d65b1b5495acd2dc674c026d4d59df8570e97ae84f93d0f928d89ce32c174
7
+ data.tar.gz: d0c1b426eb78530a3207eb1edb56e26a588c0fef9ccb28a9824a3af89e3ec7a1938ec613468179a413c0359d9d76d04d1101c0da8566d4bcbab3bd03921b35f7
data/README.md CHANGED
@@ -27,6 +27,16 @@ pbi = PowerBI::Tenant.new(->{token = get_token(client, token) ; token.token})
27
27
  * Rebind report to another dataset: `report.rebind(dataset)`
28
28
  * Export report to file: `report.export_to_file(filenam, format: 'PDF')`
29
29
 
30
+ ## Pages
31
+
32
+ * List pages in a report: `report.pages`
33
+
34
+ ## Users
35
+
36
+ * List users in a workspace: `workspace.pages`
37
+ * Delete a user from a workspace: `user.delete`
38
+ * Add a user to a workspace: `workspace.create(email_address, access_right: "Viewer")`
39
+
30
40
  ## Datasets
31
41
 
32
42
  * List datasets in a workspace: `workspace.datasets`
@@ -0,0 +1,30 @@
1
+ module PowerBI
2
+ class Page
3
+ attr_reader :display_name, :name, :order, :report
4
+
5
+ def initialize(tenant, data)
6
+ @name = data[:Name]
7
+ @display_name = data[:displayName]
8
+ @order = data[:order]
9
+ @report = data[:report]
10
+ @tenant = tenant
11
+ end
12
+ end
13
+
14
+ class PageArray < Array
15
+
16
+ def initialize(tenant, report)
17
+ super(tenant)
18
+ @report = report
19
+ end
20
+
21
+ def self.get_class
22
+ Page
23
+ end
24
+
25
+ def get_data
26
+ data = @tenant.get("/groups/#{@report.workspace.id}/reports/#{@report.id}/pages")[:value]
27
+ data.each { |d| d[:report] = @report }
28
+ end
29
+ end
30
+ end
@@ -1,6 +1,6 @@
1
1
  module PowerBI
2
2
  class Report
3
- attr_reader :name, :id, :report_type, :web_url, :embed_url, :is_from_pbix, :is_owned_by_me, :dataset_id, :workspace
3
+ attr_reader :name, :id, :report_type, :web_url, :embed_url, :is_from_pbix, :is_owned_by_me, :dataset_id, :workspace, :pages
4
4
 
5
5
  class ExportToFileError < PowerBI::Error ; end
6
6
 
@@ -15,6 +15,7 @@ module PowerBI
15
15
  @dataset_id = data[:datasetId]
16
16
  @workspace = data[:workspace]
17
17
  @tenant = tenant
18
+ @pages = PageArray.new(@tenant, self)
18
19
  end
19
20
 
20
21
  def clone(target_workspace, new_report_name)
@@ -2,10 +2,11 @@ module PowerBI
2
2
  class Tenant
3
3
  attr_reader :workspaces, :gateways
4
4
 
5
- def initialize(token_generator, retries: 5)
5
+ def initialize(token_generator, retries: 5, logger: nil)
6
6
  @token_generator = token_generator
7
7
  @workspaces = WorkspaceArray.new(self)
8
8
  @gateways = GatewayArray.new(self)
9
+ @logger = logger
9
10
 
10
11
  ## WHY RETRIES? ##
11
12
  # It is noticed that once in a while (~0.1% API calls), the Power BI server returns a 500 (internal server error) withou apparent reason, just retrying works :-)
@@ -18,11 +19,18 @@ module PowerBI
18
19
  interval: 0.2,
19
20
  interval_randomness: 0,
20
21
  backoff_factor: 4,
21
- retry_block: -> (env, options, retries, exc) { puts "retrying...!! (@ #{Time.now.to_s}), exception: #{exc.to_s} ---- #{exc.message}" },
22
+ retry_block: -> (env, options, retries, exc) { self.log "retrying...!! exception: #{exc.to_s} ---- #{exc.message}, request URL: #{env.url}" },
22
23
  }
23
24
  end
24
25
 
26
+ def log(message, level: :info)
27
+ if @logger
28
+ @logger.send(level, message) # hence, the logger needs to implement the 'level' methods
29
+ end
30
+ end
31
+
25
32
  def get(url, params = {})
33
+ t0 = Time.now
26
34
  conn = Faraday.new do |f|
27
35
  f.request :retry, @retry_options
28
36
  end
@@ -35,12 +43,14 @@ module PowerBI
35
43
  unless [200, 202].include? response.status
36
44
  raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
37
45
  end
46
+ log "Calling (GET) #{url} - took #{((Time.now - t0) * 1000).to_i} ms"
38
47
  unless response.body.empty?
39
48
  JSON.parse(response.body, symbolize_names: true)
40
49
  end
41
50
  end
42
51
 
43
52
  def get_raw(url, params = {})
53
+ t0 = Time.now
44
54
  conn = Faraday.new do |f|
45
55
  f.request :retry, @retry_options
46
56
  end
@@ -49,6 +59,7 @@ module PowerBI
49
59
  req.headers['authorization'] = "Bearer #{token}"
50
60
  yield req if block_given?
51
61
  end
62
+ log "Calling (GET - raw) #{url} - took #{((Time.now - t0) * 1000).to_i} ms"
52
63
  unless [200, 202].include? response.status
53
64
  raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
54
65
  end
@@ -56,6 +67,7 @@ module PowerBI
56
67
  end
57
68
 
58
69
  def post(url, params = {})
70
+ t0 = Time.now
59
71
  conn = Faraday.new do |f|
60
72
  f.request :retry, @retry_options
61
73
  end
@@ -66,6 +78,7 @@ module PowerBI
66
78
  req.headers['authorization'] = "Bearer #{token}"
67
79
  yield req if block_given?
68
80
  end
81
+ log "Calling (POST) #{url} - took #{((Time.now - t0) * 1000).to_i} ms"
69
82
  unless [200, 201, 202].include? response.status
70
83
  raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
71
84
  end
@@ -75,6 +88,7 @@ module PowerBI
75
88
  end
76
89
 
77
90
  def patch(url, params = {})
91
+ t0 = Time.now
78
92
  conn = Faraday.new do |f|
79
93
  f.request :retry, @retry_options
80
94
  end
@@ -85,6 +99,7 @@ module PowerBI
85
99
  req.headers['authorization'] = "Bearer #{token}"
86
100
  yield req if block_given?
87
101
  end
102
+ log "Calling (PATCH) #{url} - took #{((Time.now - t0) * 1000).to_i} ms"
88
103
  unless [200, 202].include? response.status
89
104
  raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
90
105
  end
@@ -94,6 +109,7 @@ module PowerBI
94
109
  end
95
110
 
96
111
  def delete(url, params = {})
112
+ t0 = Time.now
97
113
  conn = Faraday.new do |f|
98
114
  f.request :retry, @retry_options
99
115
  end
@@ -103,6 +119,7 @@ module PowerBI
103
119
  req.headers['authorization'] = "Bearer #{token}"
104
120
  yield req if block_given?
105
121
  end
122
+ log "Calling (DELETE) #{url} - took #{((Time.now - t0) * 1000).to_i} ms"
106
123
  unless [200, 202].include? response.status
107
124
  raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
108
125
  end
@@ -112,6 +129,7 @@ module PowerBI
112
129
  end
113
130
 
114
131
  def post_file(url, file, params = {})
132
+ t0 = Time.now
115
133
  conn = Faraday.new do |f|
116
134
  f.request :multipart
117
135
  f.request :retry, @retry_options
@@ -124,6 +142,7 @@ module PowerBI
124
142
  req.body = {value: Faraday::UploadIO.new(file, 'application/octet-stream')}
125
143
  req.options.timeout = 120 # default is 60 seconds Net::ReadTimeout
126
144
  end
145
+ log "Calling (POST - file) #{url} - took #{((Time.now - t0) * 1000).to_i} ms"
127
146
  if response.status != 202
128
147
  raise APIError.new("Error calling Power BI API (status #{response.status}): #{response.body}")
129
148
  end
@@ -0,0 +1,48 @@
1
+ module PowerBI
2
+ class User
3
+ attr_reader :email_address, :group_user_access_right, :display_name, :identifier, :principal_type
4
+
5
+ def initialize(tenant, data)
6
+ @email_address = data[:emailAddress]
7
+ @group_user_access_right = data[:groupUserAccessRight]
8
+ @display_name = data[:displayName]
9
+ @identifier = data[:identifier]
10
+ @principal_type = data[:principalType]
11
+ @workspace = data[:workspace]
12
+ @tenant = tenant
13
+ end
14
+
15
+ def delete
16
+ @tenant.delete("/groups/#{@workspace.id}/users/#{@email_address}")
17
+ @workspace.users.reload
18
+ end
19
+
20
+ end
21
+
22
+ class UserArray < Array
23
+
24
+ def initialize(tenant, workspace)
25
+ super(tenant)
26
+ @workspace = workspace
27
+ end
28
+
29
+ def self.get_class
30
+ User
31
+ end
32
+
33
+ def create(email_address, access_right: "Viewer")
34
+ @tenant.post("/groups/#{@workspace.id}/users") do |req|
35
+ req.body = {
36
+ emailAddress: email_address,
37
+ groupUserAccessRight: access_right
38
+ }.to_json
39
+ end
40
+ self.reload
41
+ end
42
+
43
+ def get_data
44
+ data = @tenant.get("/groups/#{@workspace.id}/users")[:value]
45
+ data.each { |d| d[:workspace] = @workspace }
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,6 @@
1
1
  module PowerBI
2
2
  class Workspace
3
- attr_reader :name, :is_read_only, :is_on_dedicated_capacity, :id, :reports, :datasets
3
+ attr_reader :name, :is_read_only, :is_on_dedicated_capacity, :id, :reports, :datasets, :users
4
4
 
5
5
  class UploadError < PowerBI::Error ; end
6
6
 
@@ -12,6 +12,7 @@ module PowerBI
12
12
  @tenant = tenant
13
13
  @reports = ReportArray.new(@tenant, self)
14
14
  @datasets = DatasetArray.new(@tenant, self)
15
+ @users = UserArray.new(@tenant, self)
15
16
  end
16
17
 
17
18
  def upload_pbix(file, dataset_name, timeout: 30)
@@ -22,13 +23,13 @@ module PowerBI
22
23
  status_history = ''
23
24
  old_status = ''
24
25
  while !success
25
- sleep 0.1
26
+ sleep 0.5
26
27
  iterations += 1
27
- raise UploadError.new("Upload did not succeed after #{timeout} seconds. Status history:#{status_history}") if iterations > (10 * timeout)
28
+ raise UploadError.new("Upload did not succeed after #{timeout} seconds. Status history:#{status_history}") if iterations > (2 * timeout)
28
29
  new_status = @tenant.get("/groups/#{@id}/imports/#{import_id}")[:importState].to_s
29
30
  success = (new_status == "Succeeded")
30
31
  if new_status != old_status
31
- status_history += "\nStatus change after #{iterations/10.0}s: '#{old_status}' --> '#{new_status}'"
32
+ status_history += "\nStatus change after #{iterations/2}s: '#{old_status}' --> '#{new_status}'"
32
33
  old_status = new_status
33
34
  end
34
35
  end
@@ -43,17 +44,6 @@ module PowerBI
43
44
  true
44
45
  end
45
46
 
46
- # TODO LATER: the 'Viewer' acces right is currently not settable throught the API. Fix that later
47
- def add_user(email_address, access_right = 'Member')
48
- @tenant.post("/groups/#{id}/users") do |req|
49
- req.body = {
50
- emailAddress: email_address,
51
- groupUserAccessRight: access_right
52
- }.to_json
53
- end
54
- true
55
- end
56
-
57
47
  end
58
48
 
59
49
  class WorkspaceArray < Array
data/lib/power-bi.rb CHANGED
@@ -20,3 +20,5 @@ require_relative "power-bi/parameter"
20
20
  require_relative "power-bi/refresh"
21
21
  require_relative "power-bi/gateway"
22
22
  require_relative "power-bi/gateway_datasource"
23
+ require_relative "power-bi/page"
24
+ require_relative "power-bi/user"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: power-bi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lode Cools
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-11 00:00:00.000000000 Z
11
+ date: 2021-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -38,6 +38,48 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: oauth2
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
41
83
  description: Ruby wrapper for the Power BI API
42
84
  email: lode.cools1@gmail.com
43
85
  executables: []
@@ -52,10 +94,12 @@ files:
52
94
  - lib/power-bi/datasource.rb
53
95
  - lib/power-bi/gateway.rb
54
96
  - lib/power-bi/gateway_datasource.rb
97
+ - lib/power-bi/page.rb
55
98
  - lib/power-bi/parameter.rb
56
99
  - lib/power-bi/refresh.rb
57
100
  - lib/power-bi/report.rb
58
101
  - lib/power-bi/tenant.rb
102
+ - lib/power-bi/user.rb
59
103
  - lib/power-bi/workspace.rb
60
104
  homepage: https://github.com/piloos/power-bi
61
105
  licenses:
@@ -76,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
120
  - !ruby/object:Gem::Version
77
121
  version: '0'
78
122
  requirements: []
79
- rubygems_version: 3.1.4
123
+ rubygems_version: 3.1.6
80
124
  signing_key:
81
125
  specification_version: 4
82
126
  summary: Ruby wrapper for the Power BI API