bridge_api 0.1.34 → 0.1.35

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
  SHA1:
3
- metadata.gz: f7f7fcc7455da9e499a9871e101189b7ea3b0c23
4
- data.tar.gz: 750551323fc36f2bcf00e5e598669a08fbc5e3c3
3
+ metadata.gz: 4a41802c8c2826165bac75b6823b387e790d352a
4
+ data.tar.gz: 0f39093c175f81d1b7bc083806e60d698ff19383
5
5
  SHA512:
6
- metadata.gz: 433c03fcac14ac9d7bbbc57ed8529e692eeac165c4ec4b3eddedb0c13131a173b8b4cf69df4687b411efb9a44dd5465b233bfe6180358ef1ef8165a8a9156430
7
- data.tar.gz: 7b89243ad24cc1a64ca94ba6417ff71fb6d017b0c077ceaa9f0c868de92500ddc77b81d1c77899c181465b59665dad9c5c48984d3f872074af8be15643b9cb09
6
+ metadata.gz: 9277801e0dd1ed753a207bd6897b45a1029ab0a726668ef9dac3b74be5755d3c011d6af48fd57bce706ca8addbba6fd444d21d648c7b9f111776bf40a1b2657f
7
+ data.tar.gz: 40f2dd4bfe666f316e34528d82a2c504373c131e5f605bf7bd08a7e9bfd5611f619503cb2e2d73c9fe5cd641dd0155edd23ef3c394034893ba3ab970012cb74e
data/.byebug_history ADDED
@@ -0,0 +1,33 @@
1
+ step 200000000
2
+ exit
3
+ (BridgeAPI.rate_limit_min - current_limit)
4
+ ((BridgeAPI.rate_limit_min - current_limit) / 5)
5
+ ((BridgeAPI.rate_limit_min - current_limit) / 5).ceil
6
+ step 200000000
7
+ ((BridgeAPI.rate_limit_min - current_limit) / 5).ceil
8
+ ((BridgeAPI.rate_limit_min - current_limit) / 5)
9
+ step 20000000
10
+ exit
11
+ config
12
+ step 20000000
13
+ step 20000000\
14
+ step 20000000
15
+ exit
16
+ current_limit
17
+ step 20000000
18
+ n
19
+ step 20000000
20
+ n
21
+ exit
22
+ BridgeAPI.methods
23
+ self.class.parent
24
+ self.class.superclass
25
+ self.class.base
26
+ self.class.super
27
+ self.class
28
+ self.methods
29
+ self.class::enforce_rate_limits
30
+ self.class::@enforce_rate_limits
31
+ self.class::enforce_rate_limits
32
+ self.class.methods
33
+ self.class
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bridge_api (0.1.31)
4
+ bridge_api (0.1.35)
5
5
  faraday (~> 0.9.0)
6
6
  faraday_middleware (~> 0.9.0)
7
7
  footrest (>= 0.5.1)
8
+ logging (>= 2.2.2)
8
9
 
9
10
  GEM
10
11
  remote: https://rubygems.org/
@@ -34,8 +35,13 @@ GEM
34
35
  i18n (1.0.1)
35
36
  concurrent-ruby (~> 1.0)
36
37
  link_header (0.0.8)
38
+ little-plugger (1.1.4)
39
+ logging (2.2.2)
40
+ little-plugger (~> 1.1)
41
+ multi_json (~> 1.10)
37
42
  method_source (0.9.0)
38
43
  minitest (5.11.3)
44
+ multi_json (1.13.1)
39
45
  multipart-post (2.0.0)
40
46
  pry (0.11.3)
41
47
  coderay (~> 1.1.0)
data/bridge_api.gemspec CHANGED
@@ -30,4 +30,5 @@ Gem::Specification.new do |gem|
30
30
  gem.add_dependency 'faraday', '~> 0.9.0'
31
31
  gem.add_dependency 'faraday_middleware', '~> 0.9.0'
32
32
  gem.add_dependency 'footrest', '>= 0.5.1'
33
+ gem.add_dependency 'logging', '>= 2.2.2'
33
34
  end
data/lib/bridge_api.rb CHANGED
@@ -1,2 +1,40 @@
1
1
  require 'bridge_api/version'
2
2
  require 'bridge_api/client'
3
+
4
+ module BridgeAPI
5
+ class << self
6
+ require 'logging'
7
+ attr_writer :enforce_rate_limits, :rate_limit_min, :rate_limits, :max_sleep_seconds, :min_sleep_seconds, :logger
8
+
9
+ def configure
10
+ yield self if block_given?
11
+ end
12
+
13
+ def enforce_rate_limits
14
+ @enforce_rate_limits ||= false
15
+ end
16
+
17
+ def rate_limit_min
18
+ @rate_limit_min ||= 30
19
+ end
20
+
21
+ def rate_limits
22
+ @rate_limits ||= {}
23
+ end
24
+
25
+ def max_sleep_seconds
26
+ @max_sleep_seconds ||= 60
27
+ end
28
+
29
+ def logger
30
+ return @logger if defined? @logger
31
+ @logger = Logging.logger(STDOUT)
32
+ @logger.level = :debug
33
+ @logger
34
+ end
35
+
36
+ def min_sleep_seconds
37
+ @min_sleep_seconds ||= 5
38
+ end
39
+ end
40
+ end
@@ -9,6 +9,10 @@ require 'base64'
9
9
 
10
10
  module BridgeAPI
11
11
  class Client < Footrest::Client
12
+ require 'bridge_api/api_array'
13
+
14
+ attr_accessor :rate_limit_remaining
15
+
12
16
  DATA_DUMP_DOWNLOAD_PATH = '/data_dumps/download'.freeze
13
17
  DATA_DUMP_PATH = '/data_dumps'.freeze
14
18
  COURSE_TEMPLATE_PATH = '/course_templates'.freeze
@@ -26,16 +30,14 @@ module BridgeAPI
26
30
  SUB_ACCOUNT_PATH = '/sub_accounts'.freeze
27
31
  SUPPORT_PATH = '/support'.freeze
28
32
  ACCOUNT_PATH = '/accounts'.freeze
29
- CLONE_OBJECTS_PATH = '/clone_objects'
33
+ CLONE_OBJECTS_PATH = '/clone_objects'.freeze
30
34
  API_VERSION = 1
31
35
  API_PATH = '/api'.freeze
32
36
  ROLE_PATH = '/roles'.freeze
33
- AFFILIATED_SUBACCOUNTS = '/affiliated_sub_accounts'
34
- BATCH_PATH = '/batch'
37
+ AFFILIATED_SUBACCOUNTS = '/affiliated_sub_accounts'.freeze
38
+ BATCH_PATH = '/batch'.freeze
35
39
  RESULT_MAPPING = {}
36
40
 
37
- require 'bridge_api/api_array'
38
-
39
41
  Dir[File.dirname(__FILE__) + '/client/*.rb'].each do |file|
40
42
  require file
41
43
  include const_get(File.basename(file).gsub('.rb', '').split('_').map(&:capitalize).join('').to_s)
@@ -43,7 +45,35 @@ module BridgeAPI
43
45
 
44
46
  # Override Footrest request for ApiArray support
45
47
  def request(method, &block)
46
- ApiArray.process_response(connection.send(method, &block), self, RESULT_MAPPING)
48
+ enforce_rate_limits
49
+ response = connection.send(method, &block)
50
+ apply_rate_limits(response)
51
+ ApiArray.process_response(response, self, RESULT_MAPPING)
52
+ end
53
+
54
+ def enforce_rate_limits
55
+ return unless BridgeAPI.enforce_rate_limits && current_limit
56
+ return unless current_limit < BridgeAPI::rate_limit_min
57
+ tts = ((BridgeAPI.rate_limit_min - current_limit) / 5).ceil
58
+ tts = BridgeAPI.min_sleep_seconds if tts < BridgeAPI.min_sleep_seconds
59
+ tts = BridgeAPI.max_sleep_seconds if tts > BridgeAPI.max_sleep_seconds
60
+ message = "Bridge API rate limit minimum #{BridgeAPI.rate_limit_min} reached for key: '#{config[:api_key]}'. "\
61
+ "Sleeping for #{tts} second(s) to catch up ~zzZZ~. "\
62
+ "Limit Remaining: #{current_limit}"
63
+ BridgeAPI.logger.debug(message)
64
+ sleep(tts)
65
+ end
66
+
67
+ def apply_rate_limits(response)
68
+ self.current_limit = response.headers['x-rate-limit-remaining'].to_i
69
+ end
70
+
71
+ def current_limit
72
+ BridgeAPI.rate_limits[config[:api_key]]
73
+ end
74
+
75
+ def current_limit=(value)
76
+ BridgeAPI.rate_limits[config[:api_key]] = value
47
77
  end
48
78
 
49
79
  def set_connection(config)
@@ -1,3 +1,3 @@
1
1
  module BridgeAPI
2
- VERSION = '0.1.34'.freeze unless defined?(BridgeAPI::VERSION)
2
+ VERSION = '0.1.35'.freeze unless defined?(BridgeAPI::VERSION)
3
3
  end
@@ -21,4 +21,11 @@ describe BridgeAPI::Client do
21
21
  users = client.get_all_users
22
22
  expect(users.linked['custom_fields'][0]['id']).to(eq('1'))
23
23
  end
24
+
25
+ it 'should enforce rate limits' do
26
+ client = BridgeAPI::Client.new(prefix: 'https://www.fake.com', api_key: 'fake_token', api_secret: 'fake_secret')
27
+ BridgeAPI.enforce_rate_limits = true
28
+ users = client.get_all_users
29
+ users = client.get_all_users
30
+ end
24
31
  end
@@ -61,6 +61,7 @@ class FakeBridge < Sinatra::Base
61
61
  ## Users
62
62
 
63
63
  get %r{/api/author/users$} do
64
+ response.headers['x-rate-limit-remaining'] = 29
64
65
  get_json_data 200, 'users.json'
65
66
  end
66
67
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridge_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.34
4
+ version: 0.1.35
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jay Shaffer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-25 00:00:00.000000000 Z
11
+ date: 2018-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -176,6 +176,20 @@ dependencies:
176
176
  - - ">="
177
177
  - !ruby/object:Gem::Version
178
178
  version: 0.5.1
179
+ - !ruby/object:Gem::Dependency
180
+ name: logging
181
+ requirement: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: 2.2.2
186
+ type: :runtime
187
+ prerelease: false
188
+ version_requirements: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: 2.2.2
179
193
  description: Ruby gem for interacting with the bridge API
180
194
  email:
181
195
  - jshaffer@instructure.com
@@ -183,6 +197,7 @@ executables: []
183
197
  extensions: []
184
198
  extra_rdoc_files: []
185
199
  files:
200
+ - ".byebug_history"
186
201
  - ".gitignore"
187
202
  - Dockerfile
188
203
  - Gemfile
@@ -321,3 +336,4 @@ test_files:
321
336
  - spec/fixtures/users.json
322
337
  - spec/support/fake_bridge.rb
323
338
  - spec/test_helper.rb
339
+ has_rdoc: