strongmind-platform-sdk 3.9.5 → 3.10.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 +4 -4
- data/Gemfile +3 -0
- data/Gemfile.lock +20 -4
- data/lib/platform_sdk/canvas_api/client.rb +412 -0
- data/lib/platform_sdk/canvas_api.rb +14 -0
- data/lib/platform_sdk/version.rb +1 -1
- data/lib/platform_sdk.rb +2 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2255b872c20eeb033920fa418c2bb7986ca2d4857fc920a61f2d8fd64c9053b6
|
4
|
+
data.tar.gz: 884e3636bc8381f7f083a95875a6596e3f24f9b1152abb2c45ce0613b73dd305
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33b930fd8737f76287c5f781f61f27f766156019bbc9dcc4a0cd596dfe28499cb39cb99cd52c04405c8fa0e7fed068786ef47a847c09310174687ea7e2f35abf
|
7
|
+
data.tar.gz: 65e2ed64748ebe2b6c76fb9fa7262a31611384af3d2a2a0c035d1103936e994e24adefdd4409259bb3ae022a6b640ba37f2c0e029acd4516d2b26d94b320d8b5
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
strongmind-platform-sdk (3.
|
4
|
+
strongmind-platform-sdk (3.10.0)
|
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,15 +39,18 @@ 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.
|
46
|
-
aws-sdk-core (3.191.
|
48
|
+
aws-partitions (1.893.0)
|
49
|
+
aws-sdk-core (3.191.2)
|
47
50
|
aws-eventstream (~> 1, >= 1.3.0)
|
48
51
|
aws-partitions (~> 1, >= 1.651.0)
|
49
52
|
aws-sigv4 (~> 1.8)
|
53
|
+
base64
|
50
54
|
jmespath (~> 1, >= 1.6.1)
|
51
55
|
aws-sdk-secretsmanager (1.90.0)
|
52
56
|
aws-sdk-core (~> 3, >= 3.191.0)
|
@@ -55,9 +59,13 @@ GEM
|
|
55
59
|
aws-eventstream (~> 1, >= 1.0.2)
|
56
60
|
base64 (0.2.0)
|
57
61
|
bcrypt (3.1.20)
|
58
|
-
|
62
|
+
bigdecimal (3.1.6)
|
63
|
+
bindata (2.5.0)
|
59
64
|
builder (3.2.4)
|
60
65
|
concurrent-ruby (1.2.2)
|
66
|
+
crack (1.0.0)
|
67
|
+
bigdecimal
|
68
|
+
rexml
|
61
69
|
crass (1.0.6)
|
62
70
|
date (3.3.4)
|
63
71
|
devise (4.9.3)
|
@@ -85,6 +93,7 @@ GEM
|
|
85
93
|
faraday-retry (2.1.0)
|
86
94
|
faraday (~> 2.0)
|
87
95
|
ffi (1.15.5)
|
96
|
+
hashdiff (1.1.0)
|
88
97
|
hashie (5.0.0)
|
89
98
|
i18n (1.13.0)
|
90
99
|
concurrent-ruby (~> 1.0)
|
@@ -112,6 +121,7 @@ GEM
|
|
112
121
|
mini_mime (1.1.5)
|
113
122
|
mini_portile2 (2.8.5)
|
114
123
|
minitest (5.18.0)
|
124
|
+
multi_json (1.15.0)
|
115
125
|
net-imap (0.4.10)
|
116
126
|
date
|
117
127
|
net-protocol
|
@@ -247,6 +257,10 @@ GEM
|
|
247
257
|
activesupport
|
248
258
|
faraday (~> 2.0)
|
249
259
|
faraday-follow_redirects
|
260
|
+
webmock (3.22.0)
|
261
|
+
addressable (>= 2.8.0)
|
262
|
+
crack (>= 0.3.2)
|
263
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
250
264
|
zeitwerk (2.6.13)
|
251
265
|
|
252
266
|
PLATFORMS
|
@@ -261,12 +275,14 @@ DEPENDENCIES
|
|
261
275
|
faraday-retry
|
262
276
|
jwt (~> 1.5, >= 1.5.4)
|
263
277
|
learnosity-sdk (~> 0.2.2)
|
278
|
+
multi_json
|
264
279
|
rake (~> 13.0)
|
265
280
|
rspec (~> 3.6, >= 3.6.0)
|
266
281
|
rubocop
|
267
282
|
sentry-ruby
|
268
283
|
strongmind-oneroster-client (~> 2.0.3)
|
269
284
|
strongmind-platform-sdk!
|
285
|
+
webmock
|
270
286
|
|
271
287
|
BUNDLED WITH
|
272
288
|
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
|
data/lib/platform_sdk/version.rb
CHANGED
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.
|
4
|
+
version: 3.10.0
|
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-
|
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
|