class RecombeeApiClient::RecombeeClient

Client for sending requests to Recombee recommender system

Constants

BATCH_MAX_SIZE
USER_AGENT

Public Class Methods

new(account, token, protocol = 'https', options = {}) click to toggle source
  • account -> Name of your account at Recombee

  • token -> Secret token obtained from Recombee for signing requests

  • protocol -> Default protocol for sending requests. Possible values: 'http', 'https'.

# File lib/recombee_api_client.rb, line 27
def initialize(account, token, protocol = 'https', options = {})
  @account = account
  @token = token
  @protocol = protocol
  @base_uri = ENV['RAPI_URI'] if ENV.key? 'RAPI_URI'
  @base_uri||=  options[:base_uri]
  @base_uri||= 'rapi.recombee.com'
end

Public Instance Methods

send(request) click to toggle source
  • request -> ApiRequest to be sent to Recombee recommender

# File lib/recombee_api_client.rb, line 38
def send(request)

  return send_multipart_batch(request) if request.kind_of? Batch and request.requests.size > BATCH_MAX_SIZE

  timeout = request.timeout / 1000
  uri = process_request_uri(request)
  uri = sign_url(uri)
  protocol = request.ensure_https ? 'https' : @protocol
  uri = protocol + '://' + @base_uri + uri
  # puts uri
  begin
    case request.method
    when :put
      put(request, uri, timeout)
    when :get
      get(request, uri, timeout)
    when :post
      post(request, uri, timeout)
    when :delete
      delete(request, uri, timeout)
    end
  rescue Timeout::Error
    fail ApiTimeout.new(request)
  end
end

Private Instance Methods

check_errors(response, request) click to toggle source
# File lib/recombee_api_client.rb, line 99
def check_errors(response, request)
  status_code = response.code
  return if status_code == 200 || status_code == 201
  fail ResponseError.new(request, status_code, response.body)
end
delete(request, uri, timeout) click to toggle source
# File lib/recombee_api_client.rb, line 93
def delete(request, uri, timeout)
  response = self.class.delete(uri, timeout: timeout, headers: USER_AGENT)
  check_errors(response, request)
  response.body
end
format_query_parameter_value(value) click to toggle source
# File lib/recombee_api_client.rb, line 127
def format_query_parameter_value(value)
  return CGI::escape("#{value}") unless value.kind_of?(Array)
  value.map{|v| CGI::escape("#{v}")}.join(',')
end
get(request, uri, timeout) click to toggle source
# File lib/recombee_api_client.rb, line 74
def get(request, uri, timeout)
  response = self.class.get(uri, timeout: timeout, headers: USER_AGENT)
  check_errors(response, request)
  JSON.parse(response.body)
end
hmac_sign(uri, time) click to toggle source
# File lib/recombee_api_client.rb, line 147
def hmac_sign(uri, time)
  url = uri + time
  digest = OpenSSL::Digest.new('sha1')
  OpenSSL::HMAC.hexdigest(digest, @token, url)
end
hmac_time(uri) click to toggle source
# File lib/recombee_api_client.rb, line 142
def hmac_time(uri)
  res = (uri.include? '?') ? '&' : '?'
  res << "hmac_timestamp=#{Time.now.utc.to_i}"
end
post(request, uri, timeout) click to toggle source
# File lib/recombee_api_client.rb, line 80
def post(request, uri, timeout)
  # pass arguments in body
  response = self.class.post(uri, body: request.body_parameters.to_json, 
                    headers: { 'Content-Type' => 'application/json' }.merge(USER_AGENT),
                    timeout: timeout)
  check_errors(response, request)
  begin
    return JSON.parse(response.body)
  rescue JSON::ParserError
    return response.body
  end
end
process_request_uri(request) click to toggle source
# File lib/recombee_api_client.rb, line 111
def process_request_uri(request)
  uri = request.path
  uri.slice! ('/{databaseId}/')
  uri += query_parameters_to_url(request)
  uri
end
put(request, uri, timeout) click to toggle source
# File lib/recombee_api_client.rb, line 66
def put(request, uri, timeout)
  response = self.class.put(uri, body: request.body_parameters.to_json, 
                    headers: { 'Content-Type' => 'application/json' }.merge(USER_AGENT),
                    timeout: timeout)
  check_errors(response, request)
  response.body
end
query_parameters_to_url(req) click to toggle source
# File lib/recombee_api_client.rb, line 118
def query_parameters_to_url(req)
  ps = ''
  req.query_parameters.each do |name, val|
    ps += (ps.include? '?') ? '&' : '?'
    ps += "#{name}=#{format_query_parameter_value(val)}"
  end
  ps
end
send_multipart_batch(request) click to toggle source
# File lib/recombee_api_client.rb, line 105
def send_multipart_batch(request)
  requests_parts = request.requests.each_slice(BATCH_MAX_SIZE)
  responses = requests_parts.map {|rqs| Batch.new(rqs)}.map{|batch| send(batch)}
  responses.inject([]){|result,resp| result + resp}
end
sign_url(req_part) click to toggle source

Sign request with HMAC, request URI must be exacly the same We have 30s to complete request with this token

# File lib/recombee_api_client.rb, line 134
def sign_url(req_part)
  uri = "/#{@account}/#{req_part}"
  time = hmac_time(uri)
  sign = hmac_sign(uri, time)
  res = uri + time + "&hmac_sign=#{sign}"
  res
end