class BridgeAPI::Client
Constants
- ACCOUNT_PATH
- ADMIN_PATH
- AFFILIATED_SUBACCOUNTS
- API_PATH
- API_VERSION
- AUTHOR_PATH
- BATCH_PATH
- CLONE_OBJECTS_PATH
- COURSE_TEMPLATE_PATH
- CUSTOM_FIELD_PATH
- DATA_DUMP_DOWNLOAD_PATH
- DATA_DUMP_PATH
- DUE_DATE_PATH
- ENROLLMENT_PATH
- GROUPS_PATH
- LEARNERS_PATH
- LEARNER_ENROLLMENTS
- LEARNER_ITEMS_PATH
- LEARNER_PATH
- LIVE_COURSES_PATH
- LTI_TOOLS_PATH
- MANAGER_PATH
- NEW_TEMPORARY_USERS
- PROGRAM_ENROLLMENT_PATH
- PROGRAM_PATH
- PUBLISH_PATH
- RESET_PATH
- RESTORE_PATH
- RESULT_MAPPING
- ROLE_PATH
- SESSIONS_PATH
- SUB_ACCOUNT_PATH
- SUPPORT_PATH
- USER_PATH
- WEB_CONFERENCE_PATH
Public Class Methods
Source
# File lib/bridge_api/client.rb, line 58 def initialize(options = {}, &block) if BridgeAPI.enforce_rate_limits && has_token_pool?(options) options = initialize_from_token_pool(options) end super end
Calls superclass method
Public Instance Methods
Source
# File lib/bridge_api/client.rb, line 143 def apply_rate_limits(response) limit = response.headers['x-rate-limit-remaining'] return if limit.nil? BridgeAPI.logger.debug("BRIDGE RATE LIMIT REMAINING: #{limit} for key #{config[:api_key]}") self.limit_remaining = limit.to_i end
Source
# File lib/bridge_api/client.rb, line 78 def convert_tokens(config) return config unless config.has_key?(:api_tokens) return config unless config[:api_tokens].is_a?(Array) config[:api_keys] ||= {} config[:api_tokens].each do |token| decoded_token_array = Base64.strict_decode64(token).split(':') config[:api_keys][decoded_token_array[0]] = decoded_token_array[1] end config.delete(:api_tokens) config end
Source
# File lib/bridge_api/client.rb, line 127 def enforce_rate_limits return unless rate_limit_reached? rotate_token! if rate_limit_reached? sleep_time = rand(BridgeAPI.max_sleep_seconds) sleep_time = BridgeAPI.min_sleep_seconds if sleep_time < BridgeAPI.min_sleep_seconds BridgeAPI.logger.debug("Rate limit reached sleeping for #{sleep_time}") sleep(sleep_time) end end
Source
# File lib/bridge_api/client.rb, line 111 def get_next_key(keys, current_key) keys.delete(current_key) usable_key = keys.find do |key| limit = rate_limit(key) current_key_limit = limit.present? ? limit.fetch('current') : 0 BridgeAPI.beginning_rate_limit - current_key_limit > BridgeAPI.rate_limit_threshold end usable_key || keys[rand(keys.length)] end
Source
# File lib/bridge_api/client.rb, line 73 def has_token_pool?(config) config[:api_keys].is_a?(Hash) && config[:api_keys].keys.count >= 1 || config[:api_tokens].is_a?(Array) && config[:api_tokens].count >= 1 end
Source
# File lib/bridge_api/client.rb, line 90 def initialize_from_token_pool(config) config = convert_tokens(config) creds = config[:api_keys].first config[:api_key] ||= creds[0] config[:api_secret] ||= creds[1] config end
Source
# File lib/bridge_api/client.rb, line 151 def limit_remaining if using_master_rate_limit? limit = rate_limit(config[:api_key]) if limit.nil? set_rate_limit(config[:api_key], 0) limit = { current: 0 }.with_indifferent_access end limit['current'] else BridgeAPI.rate_limits[config[:api_key]] end end
Source
# File lib/bridge_api/client.rb, line 164 def limit_remaining=(value) if using_master_rate_limit? set_rate_limit(config[:api_key], value) else BridgeAPI.rate_limits[config[:api_key]] = value end refresh_stale_tokens end
Source
# File lib/bridge_api/client.rb, line 179 def rate_limit(key) BridgeAPI.master_mutex.synchronize do PaulWalker::RateLimit.get(key, key) end end
Source
# File lib/bridge_api/client.rb, line 121 def rate_limit_reached? return false unless BridgeAPI.enforce_rate_limits && limit_remaining.present? limit_remaining < BridgeAPI.rate_limit_threshold end
Source
# File lib/bridge_api/client.rb, line 185 def refresh_stale_tokens return unless using_master_rate_limit? return unless config[:api_keys].present? api_keys = config[:api_keys].keys api_keys.delete(config[:api_key]) api_keys.each do |key| limit = rate_limit(key) next unless limit.present? if limit['timestamp'].present? && DateTime.parse(limit['timestamp']) < 1.minute.ago BridgeAPI.logger.debug("Refreshing: #{key}") set_rate_limit(key, 0) end end end
Source
# File lib/bridge_api/client.rb, line 66 def request(method, &block) enforce_rate_limits if rate_limit_reached? response = connection.send(method, &block) apply_rate_limits(response) ApiArray.process_response(response, self, RESULT_MAPPING) end
Override Footrest request for ApiArray
support
Source
# File lib/bridge_api/client.rb, line 99 def rotate_token! return unless config[:api_keys].present? old_api_key = config[:api_key] keys = config[:api_keys].keys return if keys.count <= 1 key = get_next_key(keys, config[:api_key]) config[:api_key] = key config[:api_secret] = config[:api_keys][key] set_connection(config) BridgeAPI.logger.debug("ROTATED TO KEY: #{config[:api_key]}") end
rotates to the next token in the pool (by order in which they were provided)
Source
# File lib/bridge_api/client.rb, line 200 def set_connection(config) config[:logger] = config[:logging] if config[:logging] @connection = Faraday.new(url: config[:prefix]) do |faraday| faraday.request :multipart faraday.request :url_encoded if config[:logger] == true faraday.response :logger elsif config[:logger] faraday.use Faraday::Response::Logger, config[:logger] end faraday.use Footrest::FollowRedirects, limit: 5 unless config[:follow_redirects] == false faraday.adapter Faraday.default_adapter faraday.use Footrest::ParseJson, content_type: /\bjson$/ faraday.use Footrest::RaiseFootrestErrors faraday.use Footrest::Pagination faraday.headers[:accept] = 'application/json' faraday.headers[:user_agent] = 'Footrest' if config[:api_key] && config[:api_secret] faraday.headers[:authorization] = 'Basic ' + Base64.strict_encode64("#{config[:api_key]}:#{config[:api_secret]}") elsif config[:token] faraday.headers[:authorization] = "Bearer #{config[:token]}" else raise 'No api authorization provided' end end end
Source
# File lib/bridge_api/client.rb, line 173 def set_rate_limit(key, limit) BridgeAPI.master_mutex.synchronize do PaulWalker::RateLimit.add(key, key, limit, BridgeAPI.beginning_rate_limit) end end
Source
# File lib/bridge_api/client.rb, line 139 def using_master_rate_limit? config[:master_rate_limit].present? || BridgeAPI.master_rate_limit.present? end