strongmind-platform-sdk 3.9.5 → 3.10.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: 2b4fc00d20bef3777e4dcd73f70fc3e62dada68543055d9bb0cd163178eaca35
4
- data.tar.gz: 1a1cdfe41e25b06baee0682c6da24c05786962342a2cb90fe1e63172e368c9b8
3
+ metadata.gz: cf9bfdc1d3b87dbbefbe4b9e1b08d25b544ded0718d31d28d6224e976c4d440c
4
+ data.tar.gz: eb316b3acc88e86d6e5a326a2a0e8e6c4d50d8ff92cade77f8228b15e80d5940
5
5
  SHA512:
6
- metadata.gz: adbd7f3a16cf4eaa8e62969eeea2dc677b1ea26d5603e95989079405e86452c2a39ed76d8155596ba656fc95ea4e354aea84293da557ecbd493846887ce9c2d6
7
- data.tar.gz: f2af566a32ead069f0b33d7b8bb6a1784d995f5e4a912abce0a9eb6dc7b030976622ef5fe6893570493b5b3a588606a14a67279a10f6f5b7e57cd2b721f90ead
6
+ metadata.gz: 9ebfdbd2952f4455141f4addd23675245bd048fa9050c01586cd2d6b7ec66ba0348e9f52c9cf0867967712556cfd8b7b0ccc2a2756d02610497f7380206ca3de
7
+ data.tar.gz: cdc7fa6f4909e56ad84f271dbd8cb8826d941f6ffd51e256a682088400d4fae5f61a7305c6dd45323f1f05b62e69c5c2dca197941da0199e3e192f8bae13f57b
data/Gemfile CHANGED
@@ -14,7 +14,10 @@ gem "faraday"
14
14
  gem "faraday-retry"
15
15
  gem "jwt", "~> 1.5", ">= 1.5.4"
16
16
  gem "learnosity-sdk", "~> 0.2.2"
17
+ gem "multi_json"
17
18
  gem "rake", "~> 13.0"
18
19
  gem "rspec", "~> 3.6", ">= 3.6.0"
19
20
  gem "rubocop"
20
21
  gem 'sentry-ruby'
22
+ gem "webmock"
23
+
data/Gemfile.lock CHANGED
@@ -1,13 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- strongmind-platform-sdk (3.9.5)
4
+ strongmind-platform-sdk (3.10.1)
5
5
  aws-sdk-secretsmanager (~> 1.66)
6
6
  devise
7
7
  faraday (~> 2.5, >= 2.5.2)
8
8
  faraday-retry
9
9
  jwt
10
10
  learnosity-sdk (~> 0.2.2)
11
+ multi_json
11
12
  omniauth
12
13
  omniauth-rails_csrf_protection
13
14
  omniauth_openid_connect
@@ -38,12 +39,14 @@ GEM
38
39
  i18n (>= 1.6, < 2)
39
40
  minitest (>= 5.1)
40
41
  tzinfo (~> 2.0)
42
+ addressable (2.8.6)
43
+ public_suffix (>= 2.0.2, < 6.0)
41
44
  aes_key_wrap (1.1.0)
42
45
  ast (2.4.2)
43
46
  attr_required (1.0.2)
44
47
  aws-eventstream (1.3.0)
45
- aws-partitions (1.890.0)
46
- aws-sdk-core (3.191.1)
48
+ aws-partitions (1.894.0)
49
+ aws-sdk-core (3.191.3)
47
50
  aws-eventstream (~> 1, >= 1.3.0)
48
51
  aws-partitions (~> 1, >= 1.651.0)
49
52
  aws-sigv4 (~> 1.8)
@@ -55,9 +58,13 @@ GEM
55
58
  aws-eventstream (~> 1, >= 1.0.2)
56
59
  base64 (0.2.0)
57
60
  bcrypt (3.1.20)
58
- bindata (2.4.15)
61
+ bigdecimal (3.1.6)
62
+ bindata (2.5.0)
59
63
  builder (3.2.4)
60
64
  concurrent-ruby (1.2.2)
65
+ crack (1.0.0)
66
+ bigdecimal
67
+ rexml
61
68
  crass (1.0.6)
62
69
  date (3.3.4)
63
70
  devise (4.9.3)
@@ -85,6 +92,7 @@ GEM
85
92
  faraday-retry (2.1.0)
86
93
  faraday (~> 2.0)
87
94
  ffi (1.15.5)
95
+ hashdiff (1.1.0)
88
96
  hashie (5.0.0)
89
97
  i18n (1.13.0)
90
98
  concurrent-ruby (~> 1.0)
@@ -112,6 +120,7 @@ GEM
112
120
  mini_mime (1.1.5)
113
121
  mini_portile2 (2.8.5)
114
122
  minitest (5.18.0)
123
+ multi_json (1.15.0)
115
124
  net-imap (0.4.10)
116
125
  date
117
126
  net-protocol
@@ -157,7 +166,7 @@ GEM
157
166
  ast (~> 2.4.1)
158
167
  public_suffix (5.0.4)
159
168
  racc (1.7.3)
160
- rack (2.2.8)
169
+ rack (2.2.8.1)
161
170
  rack-oauth2 (2.2.1)
162
171
  activesupport
163
172
  attr_required
@@ -247,6 +256,10 @@ GEM
247
256
  activesupport
248
257
  faraday (~> 2.0)
249
258
  faraday-follow_redirects
259
+ webmock (3.22.0)
260
+ addressable (>= 2.8.0)
261
+ crack (>= 0.3.2)
262
+ hashdiff (>= 0.4.0, < 2.0.0)
250
263
  zeitwerk (2.6.13)
251
264
 
252
265
  PLATFORMS
@@ -261,12 +274,14 @@ DEPENDENCIES
261
274
  faraday-retry
262
275
  jwt (~> 1.5, >= 1.5.4)
263
276
  learnosity-sdk (~> 0.2.2)
277
+ multi_json
264
278
  rake (~> 13.0)
265
279
  rspec (~> 3.6, >= 3.6.0)
266
280
  rubocop
267
281
  sentry-ruby
268
282
  strongmind-oneroster-client (~> 2.0.3)
269
283
  strongmind-platform-sdk!
284
+ webmock
270
285
 
271
286
  BUNDLED WITH
272
287
  2.3.16
@@ -0,0 +1,412 @@
1
+ # frozen_string_literal: true
2
+ require "faraday"
3
+
4
+ module PlatformSdk
5
+ module CanvasApiWrapper
6
+ # DataPipeline::Client
7
+ class Client
8
+ attr_reader :host, :token, :connection
9
+
10
+ PAGE_SIZE = 10
11
+
12
+ # @param domain [String]
13
+ # @param token [String]
14
+ def initialize(domain:, token:)
15
+ @host = "https://#{domain}"
16
+ @token = token
17
+ @connection = Faraday.new(url: host, headers: { 'Authorization' => "Bearer #{token}" })
18
+ end
19
+
20
+ # @param course_id [Integer]
21
+ # @returns [Array]
22
+ def course_modules(course_id:)
23
+ response = @connection.get("/api/v1/courses/#{course_id}/modules")
24
+ handle_rate_limiting response
25
+ if success?(response.status)
26
+ paginated_items headers: response.headers, initial_response: response.body
27
+ else
28
+ result = MultiJson.load response.body, symbolize_keys: true
29
+ error_messages = ''
30
+ result[:errors].each do |error|
31
+ error_messages << "#{error[:message]} "
32
+ end
33
+ raise "Error getting course modules: #{error_messages}"
34
+ end
35
+ end
36
+
37
+ # @param course_id [Integer]
38
+ # @param module_id [Integer]
39
+ # @returns [Array]
40
+ def module_items(course_id:, module_id:)
41
+ response = @connection.get("/api/v1/courses/#{course_id}/modules/#{module_id}/items?per_page=#{PAGE_SIZE}")
42
+ handle_rate_limiting response
43
+ if success?(response.status)
44
+ paginated_items headers: response.headers, initial_response: response.body
45
+ else
46
+ result = MultiJson.load response.body, symbolize_keys: true
47
+ error_messages = ''
48
+ result[:errors].each do |error|
49
+ error_messages << "#{error[:message]} "
50
+ end
51
+ raise "Error getting module items: #{error_messages}"
52
+ end
53
+ end
54
+
55
+ # @param course_id [Integer]
56
+ # @param module_id [Integer]
57
+ # @param user_id [Integer]
58
+ # @returns [Array]
59
+ def user_module_items(course_id:, module_id:, user_id:)
60
+ uri = "/api/v1/courses/#{course_id}/modules/#{module_id}/items?as_user_id=#{user_id}&per_page=#{PAGE_SIZE}"
61
+ response = @connection.get(uri)
62
+ handle_rate_limiting response
63
+ if success?(response.status)
64
+ paginated_items headers: response.headers, initial_response: response.body
65
+ else
66
+ result = MultiJson.load response.body, symbolize_keys: true
67
+ error_messages = ''
68
+ result[:errors].each do |error|
69
+ error_messages << "#{error[:message]} "
70
+ end
71
+ raise "Error getting module items: #{error_messages}"
72
+ end
73
+ end
74
+
75
+ # @param course_id [Integer]
76
+ # @param module_id [Integer]
77
+ # @returns [Array]
78
+ def assignments(course_id:, module_id:)
79
+ response = @connection.get("/api/v1/courses/#{course_id}/modules/#{module_id}/items?per_page=#{PAGE_SIZE}")
80
+ handle_rate_limiting response
81
+ if success?(response.status)
82
+ assignments = paginated_items headers: response.headers, initial_response: response.body
83
+ assignments.select { |item| item[:type] == 'Assignment' }
84
+ else
85
+ result = MultiJson.load response.body, symbolize_keys: true
86
+ error_messages = ''
87
+ result[:errors].each do |error|
88
+ error_messages << "#{error[:message]} "
89
+ end
90
+ raise "Error getting assignments: #{error_messages}"
91
+ end
92
+ end
93
+
94
+ # @param course_id [Integer]
95
+ def assignment(course_id:, assignment_id:)
96
+ uri = "api/v1/courses/#{course_id}/assignments/#{assignment_id}"
97
+ response = @connection.get(uri)
98
+ handle_rate_limiting response
99
+ if success?(response.status)
100
+ MultiJson.load response.body, symbolize_keys: true
101
+ else
102
+ result = MultiJson.load response.body, symbolize_keys: true
103
+ error_messages = ''
104
+ result[:errors].each do |error|
105
+ error_messages << "#{error[:message]} "
106
+ end
107
+ raise "Error getting quiz submissions#{error_messages}"
108
+ end
109
+ end
110
+
111
+ # @param course_id [Integer]
112
+ # @param module_id [Integer]
113
+ # @param module_item_id [Integer]
114
+ def module_item(course_id:, module_id:, module_item_id:)
115
+ response = @connection.get("/api/v1/courses/#{course_id}/modules/#{module_id}/items/#{module_item_id}")
116
+ handle_rate_limiting response
117
+ if success?(response.status)
118
+ MultiJson.load response.body, symbolize_keys: true
119
+ else
120
+ result = MultiJson.load response.body, symbolize_keys: true
121
+ error_messages = ''
122
+ result[:errors].each do |error|
123
+ error_messages << "#{error[:message]} "
124
+ end
125
+ raise "Error getting module item: #{error_messages}"
126
+ end
127
+ end
128
+
129
+ def user_module_item(course_id:, module_id:, module_item_id:, user_id:)
130
+ response = @connection.get("/api/v1/courses/#{course_id}/modules/#{module_id}/items/#{module_item_id}?as_user_id=#{user_id}")
131
+ handle_rate_limiting response
132
+ if success?(response.status)
133
+ MultiJson.load response.body, symbolize_keys: true
134
+ else
135
+ result = MultiJson.load response.body, symbolize_keys: true
136
+ error_messages = ''
137
+ result[:errors].each do |error|
138
+ error_messages << "#{error[:message]} "
139
+ end
140
+ raise "Error getting module item: #{error_messages}"
141
+ end
142
+ end
143
+
144
+ # @param course_id [Integer]
145
+ # @param assignment_id [Integer]
146
+ def submissions(course_id:, assignment_id:)
147
+ response = @connection.get("/api/v1/courses/#{course_id}/assignments/#{assignment_id}/submissions/")
148
+ handle_rate_limiting response
149
+ if success?(response.status)
150
+ paginated_items headers: response.headers, initial_response: response.body
151
+ else
152
+ result = MultiJson.load response.body, symbolize_keys: true
153
+ error_messages = ''
154
+ result[:errors].each do |error|
155
+ error_messages << "#{error[:message]} "
156
+ end
157
+ raise "Error getting submissions: #{error_messages}"
158
+ end
159
+ end
160
+
161
+ def update_submission_excused(course_id:, assignment_id:, user_id:)
162
+ uri = "/api/v1/courses/#{course_id}/assignments/#{assignment_id}/submissions/#{user_id}"
163
+ response = @connection.put(uri) do |req|
164
+ req.headers["Content-Type"] = "application/json"
165
+ req.body = {
166
+ submission: {
167
+ excuse: true
168
+ }
169
+ }.to_json
170
+ end
171
+ handle_rate_limiting response
172
+ if success?(response.status)
173
+ MultiJson.load response.body, symbolize_keys: true
174
+ else
175
+ result = MultiJson.load response.body, symbolize_keys: true
176
+ error_messages = ''
177
+ result[:errors].each do |error|
178
+ error_messages << "#{error[:message]} "
179
+ end
180
+ raise "Error update submissions to excused: #{error_messages}"
181
+ end
182
+ end
183
+
184
+ def update_submission_excused_with_comment(course_id:, assignment_id:, user_id:, comment:)
185
+ uri = "/api/v1/courses/#{course_id}/assignments/#{assignment_id}/submissions/#{user_id}"
186
+ response = @connection.put(uri) do |req|
187
+ req.headers['Content-Type'] = 'application/json'
188
+ req.body = {
189
+ 'comment': {
190
+ 'text_comment': comment
191
+ },
192
+ 'submission': {
193
+ 'excuse': true
194
+ }
195
+ }.to_json
196
+ end
197
+ if success?(response.status)
198
+ MultiJson.load response.body, symbolize_keys: true
199
+ else
200
+ result = MultiJson.load response.body, symbolize_keys: true
201
+ error_messages = ''
202
+ result[:errors].each do |error|
203
+ error_messages << "#{error[:message]} "
204
+ end
205
+ raise "Error update submissions to excused: #{error_messages}"
206
+ end
207
+ end
208
+
209
+ # @param course_id [Integer]
210
+ def course_students(course_id:)
211
+ uri = "/api/v1/courses/#{course_id}/users?per_page=#{PAGE_SIZE}"
212
+ params = { 'enrollment_type[]' => 'student' }
213
+ response = @connection.get(uri, params)
214
+ handle_rate_limiting response
215
+ if success?(response.status)
216
+ paginated_items headers: response.headers, initial_response: response.body
217
+ else
218
+ result = MultiJson.load response.body, symbolize_keys: true
219
+ error_messages = ''
220
+ result[:errors].each do |error|
221
+ error_messages << "#{error[:message]} "
222
+ end
223
+ raise "Error getting course students: #{error_messages}"
224
+ end
225
+ end
226
+
227
+ # @param course_id [Integer]
228
+ # @param quiz_id [Integer]
229
+ def quiz(course_id:, quiz_id:)
230
+ uri = "/api/v1/courses/#{course_id}/quizzes/#{quiz_id}"
231
+ response = @connection.get(uri)
232
+ handle_rate_limiting response
233
+ if success?(response.status)
234
+ MultiJson.load response.body, symbolize_keys: true
235
+ else
236
+ result = MultiJson.load response.body, symbolize_keys: true
237
+ error_messages = ''
238
+ result[:errors].each do |error|
239
+ error_messages << "#{error[:message]} "
240
+ end
241
+ raise "Error getting quiz: #{error_messages}"
242
+ end
243
+ end
244
+
245
+ # @param course_id [Integer]
246
+ # @param quiz_id [Integer]
247
+ # @param user_id [Integer]
248
+ # @return [Array]
249
+ def quiz_submissions(course_id:, quiz_id:, user_id:)
250
+ uri = "api/v1/courses/#{course_id}/quizzes/#{quiz_id}/submissions?user=#{user_id}&per_page=#{PAGE_SIZE}"
251
+ response = @connection.get(uri)
252
+ handle_rate_limiting response
253
+ if success?(response.status)
254
+ paginated_items headers: response.headers, initial_response: response.body
255
+ else
256
+ result = MultiJson.load response.body, symbolize_keys: true
257
+ error_messages = ''
258
+ result[:errors].each do |error|
259
+ error_messages << "#{error[:message]} "
260
+ end
261
+ raise "Error getting quiz submissions#{error_messages}"
262
+ end
263
+ end
264
+
265
+ # @param course_id [Integer]
266
+ # @param quiz_id [Integer]
267
+ # @param user_id [Integer]
268
+ def post_create_quiz_submission(course_id:, quiz_id:, user_id:)
269
+ uri = "api/v1/courses/#{course_id}/quizzes/#{quiz_id}/submissions?as_user_id=#{user_id}"
270
+ response = @connection.post(uri)
271
+ handle_rate_limiting response
272
+ if success?(response.status)
273
+ MultiJson.load response.body, symbolize_keys: true
274
+ else
275
+ result = MultiJson.load response.body, symbolize_keys: true
276
+ message = 'Error creating quiz submission'
277
+ if response.status == 403
278
+ raise "#{message}: #{result[:message]}"
279
+ end
280
+ if result[:errors]
281
+ raise parse_response_errors message:, result:
282
+ end
283
+ end
284
+ end
285
+
286
+ # @param course_id [Integer]
287
+ # @param quiz_id [Integer]
288
+ # @param submission_id [Integer]
289
+ # @param attempt [Integer]
290
+ # @param validation_token [String]
291
+ # @return [Hash]
292
+ def post_complete_quiz_submission(course_id:, quiz_id:, submission_id:, attempt:, validation_token:)
293
+ uri = "api/v1/courses/#{course_id}/quizzes/#{quiz_id}/submissions/#{submission_id}/complete"
294
+ response = @connection.post(uri) do |req|
295
+ req.headers['Content-Type'] = 'application/json'
296
+ req.body = { attempt:, validation_token: }.to_json
297
+ end
298
+ handle_rate_limiting response
299
+ if success?(response.status)
300
+ MultiJson.load response.body, symbolize_keys: true
301
+ else
302
+ result = MultiJson.load response.body, symbolize_keys: true
303
+ message = 'Error completing quiz submission'
304
+ if response.status == 403
305
+ raise "#{message}: #{result[:message]}"
306
+ end
307
+ if result[:errors]
308
+ raise parse_response_errors message:, result:
309
+ end
310
+ end
311
+ end
312
+
313
+ # @param course_id [Integer]
314
+ # @param module_id [Integer]
315
+ # @param module_item_id [Integer]
316
+ # @param user_id [Integer]
317
+ # @return nil
318
+ def post_mark_module_item_read(course_id:, module_id:, module_item_id:, user_id:)
319
+ uri = "api/v1/courses/#{course_id}/modules/#{module_id}/items/#{module_item_id}/mark_read?as_user_id=#{user_id}"
320
+ response = @connection.post(uri)
321
+ handle_rate_limiting response
322
+ if success?(response.status)
323
+ MultiJson.load response.body, symbolize_keys: true
324
+ else
325
+ result = MultiJson.load response.body, symbolize_keys: true
326
+ message = 'Error marking module items read'
327
+ if response.status == 403
328
+ raise "#{message}: #{result[:message]}"
329
+ end
330
+ if result[:errors]
331
+ raise parse_response_errors message:, result:
332
+ end
333
+ end
334
+ end
335
+
336
+ def post_discussion_topic_entry(course_id:, topic_id:, user_id:, message:)
337
+ uri = "api/v1/courses/#{course_id}/discussion_topics/#{topic_id}/entries?as_user_id=#{user_id}"
338
+ response = @connection.post(uri) do |req|
339
+ req.headers['Content-Type'] = 'application/json'
340
+ req.body = { 'message': message.to_s }.to_json
341
+ end
342
+ handle_rate_limiting response
343
+ if success?(response.status)
344
+ MultiJson.load response.body, symbolize_keys: true
345
+ else
346
+ result = MultiJson.load response.body, symbolize_keys: true
347
+ error_messages = ''
348
+ result[:errors]&.each do |error|
349
+ error_messages << "#{error[:message]} "
350
+ end
351
+ raise "Error posting a reply: #{error_messages}"
352
+ end
353
+ end
354
+
355
+ private
356
+
357
+ # @param headers [Faraday::Utils::Headers]
358
+ # @return [Array]
359
+ def paginated_items(headers:, initial_response:)
360
+ pages = page_links(headers:)
361
+ items = []
362
+ items.append MultiJson.load(initial_response, symbolize_keys: true)
363
+ while pages[:current] != pages[:last]
364
+ response = @connection.get(pages[:next][:url])
365
+ handle_rate_limiting response
366
+ pages = page_links(headers: response.headers)
367
+ items.append MultiJson.load(response.body, symbolize_keys: true)
368
+ end
369
+ items.flatten
370
+ end
371
+
372
+ # @param headers [Faraday::Utils::Headers]
373
+ # @return [Hash]
374
+ def page_links(headers:)
375
+ parts = headers[:link].split(',')
376
+ parts.map do |part, _|
377
+ section = part.split(';')
378
+ name = section[1][/rel="(.*)"/, 1].to_sym
379
+ url = section[0][/<(.*)>/, 1]
380
+ [name, { url: }]
381
+ end.to_h
382
+ end
383
+
384
+ # @param response_code [Integer]
385
+ # @return [Boolean]
386
+ def success?(response_code)
387
+ !!(response_code.to_s =~ /2[0-9]/)
388
+ end
389
+
390
+ # @param message [String]
391
+ # @param result [Hash]
392
+ # @return [String]
393
+ def parse_response_errors(message:, result:)
394
+ error_messages = ''
395
+ result[:errors].each do |error|
396
+ error_messages << "#{error[:message]} "
397
+ end
398
+ "#{message}: {#{error_messages}"
399
+ end
400
+
401
+ def handle_rate_limiting(response)
402
+ remaining_requests = response.headers["X-Rate-Limit-Remaining"].to_i
403
+ reset_time = response.headers["X-Rate-Limit-Reset"].to_i
404
+
405
+ return unless remaining_requests.zero?
406
+
407
+ sleep_time = [reset_time - Time.now.to_i, 0].max + 1
408
+ sleep(sleep_time)
409
+ end
410
+ end
411
+ end
412
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "faraday/net_http"
5
+ require "faraday/retry"
6
+ require "platform_sdk/canvas_api/client"
7
+
8
+ module PlatformSdk
9
+ module CanvasApiWrapper
10
+ class Error < StandardError; end
11
+
12
+
13
+ end
14
+ end
@@ -65,10 +65,16 @@ module PlatformSdk
65
65
  Time.at(JWT.decode(jwt, nil, false)[0]["exp"])
66
66
  end
67
67
 
68
- def refresh_token(jwt:, refresh_token:)
68
+ def refresh_token_if_expired(jwt:, refresh_token:)
69
69
  raise ArgumentError if refresh_token.nil? || jwt.nil?
70
70
  return unless token_expired?(jwt)
71
71
 
72
+ refresh_token(refresh_token)
73
+ end
74
+
75
+ def refresh_token(refresh_token)
76
+ raise ArgumentError if refresh_token.nil?
77
+
72
78
  response = @conn.post("/connect/token", request_body(
73
79
  grant_type: "refresh_token", refresh_token:))
74
80
  response.body.transform_keys!(&:to_sym)
@@ -77,7 +83,7 @@ module PlatformSdk
77
83
  def refresh_session(session: {})
78
84
  raise ArgumentError if session[:access_token].nil? || session[:refresh_token].nil?
79
85
 
80
- refreshed_tokens = refresh_token(jwt: session[:access_token], refresh_token: session[:refresh_token])
86
+ refreshed_tokens = refresh_token_if_expired(jwt: session[:access_token], refresh_token: session[:refresh_token])
81
87
 
82
88
  return if refreshed_tokens.nil?
83
89
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PlatformSdk
4
- VERSION = "3.9.5"
4
+ VERSION = "3.10.1"
5
5
  end
data/lib/platform_sdk.rb CHANGED
@@ -11,6 +11,8 @@ require "platform_sdk/data_pipeline"
11
11
  require "platform_sdk/pencil_spaces"
12
12
  require "platform_sdk/edfi"
13
13
  require "platform_sdk/sentry"
14
+ require "platform_sdk/learnosity_api"
15
+ require "platform_sdk/canvas_api"
14
16
 
15
17
  module PlatformSdk
16
18
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strongmind-platform-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.5
4
+ version: 3.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Platform Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-13 00:00:00.000000000 Z
11
+ date: 2024-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -184,6 +184,20 @@ dependencies:
184
184
  - - ">="
185
185
  - !ruby/object:Gem::Version
186
186
  version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ name: multi_json
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ type: :runtime
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
187
201
  description: Includes a wrapper for the swagger generated OneRoster management clients
188
202
  email:
189
203
  - horseshoes@strongmind.com
@@ -214,6 +228,8 @@ files:
214
228
  - lib/platform_sdk.rb
215
229
  - lib/platform_sdk/aws.rb
216
230
  - lib/platform_sdk/aws/secrets_manager_client.rb
231
+ - lib/platform_sdk/canvas_api.rb
232
+ - lib/platform_sdk/canvas_api/client.rb
217
233
  - lib/platform_sdk/data_pipeline.rb
218
234
  - lib/platform_sdk/data_pipeline/data_pipeline_client.rb
219
235
  - lib/platform_sdk/edfi.rb