Skip to content

Commit

Permalink
Support setting the region of your DB. Added Update / Delete More Ite…
Browse files Browse the repository at this point in the history
…ms endpoints.

Breaking changes:
RecombeeClient.initialize: protocol parameter (HTTP/HTTPS) moved to options hash.
Removed deprecated endpoints Item Based Recommendation and User Based Recommendation.
  • Loading branch information
OndraFiedler committed Apr 20, 2022
1 parent 31255d7 commit 12b77c9
Show file tree
Hide file tree
Showing 21 changed files with 224 additions and 377 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Or install it yourself as:
require 'recombee_api_client'
include RecombeeApiClient

client = RecombeeClient('--my-database-id--', '--db-private-token--')
client = RecombeeClient('--my-database-id--', '--db-private-token--', {:region => 'us-west'})

# Generate some random purchases of items by users
NUM = 100
Expand Down Expand Up @@ -76,7 +76,7 @@ include RecombeeApiClient
NUM = 100
PROBABILITY_PURCHASED = 0.1

client = RecombeeClient('--my-database-id--', '--db-private-token--')
client = RecombeeClient('--my-database-id--', '--db-private-token--', {:region => 'ap-se'})
client.send(ResetDatabase.new) # Clear everything from the database (asynchronous)

# We will use computers as items in this example
Expand Down
55 changes: 40 additions & 15 deletions lib/recombee_api_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,16 @@ class RecombeeClient
include HTTParty

BATCH_MAX_SIZE = 10000
USER_AGENT = {'User-Agent' => 'recombee-ruby-api-client/3.2.0'}
USER_AGENT = {'User-Agent' => 'recombee-ruby-api-client/4.0.0'}

##
# - +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'.
def initialize(account, token, protocol = 'https', options = {})
def initialize(account, token, 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'
@protocol = options[:protocol] || 'https'
@base_uri = get_base_uri(options)
end

##
Expand All @@ -42,7 +39,7 @@ def send(request)
timeout = request.timeout / 1000
uri = process_request_uri(request)
uri = sign_url(uri)
protocol = request.ensure_https ? 'https' : @protocol
protocol = request.ensure_https ? 'https' : @protocol.to_s
uri = protocol + '://' + @base_uri + uri
# puts uri
begin
Expand All @@ -63,10 +60,33 @@ def send(request)

private

def get_regional_base_uri(region)
uri = {
'ap-se' => 'rapi-ap-se.recombee.com',
'ca-east' => 'rapi-ca-east.recombee.com',
'eu-west' => 'rapi-eu-west.recombee.com',
'us-west' => 'rapi-us-west.recombee.com'
}[region.to_s.gsub('_', '-').downcase]
raise ArgumentError.new("Region \"#{region}\" is unknown. You may need to update the version of the SDK.") if uri == nil
uri
end

def get_base_uri(options)
base_uri = ENV['RAPI_URI']
base_uri ||= options[:base_uri]

if options.key? :region
raise ArgumentError.new(':base_uri and :region cannot be specified at the same time') if base_uri
base_uri = get_regional_base_uri(options[:region])
end
base_uri||= 'rapi.recombee.com'
base_uri
end

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)
headers: { 'Content-Type' => 'application/json' }.merge(USER_AGENT),
timeout: timeout)
check_errors(response, request)
response.body
end
Expand All @@ -78,10 +98,9 @@ def get(request, uri, timeout)
end

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)
headers: { 'Content-Type' => 'application/json' }.merge(USER_AGENT),
timeout: timeout)
check_errors(response, request)
begin
return JSON.parse(response.body)
Expand All @@ -91,9 +110,15 @@ def post(request, uri, timeout)
end

def delete(request, uri, timeout)
response = self.class.delete(uri, timeout: timeout, headers: USER_AGENT)
response = self.class.delete(uri, body: request.body_parameters.to_json,
headers: { 'Content-Type' => 'application/json' }.merge(USER_AGENT),
timeout: timeout)
check_errors(response, request)
response.body
begin
return JSON.parse(response.body)
rescue JSON::ParserError
return response.body
end
end

def check_errors(response, request)
Expand Down
2 changes: 1 addition & 1 deletion lib/recombee_api_client/api/delete_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module RecombeeApiClient
#
#If there are any *purchases*, *ratings*, *bookmarks*, *cart additions* or *detail views* of the item present in the database, they will be deleted in cascade as well. Also, if the item is present in some *series*, it will be removed from all the *series* where present.
#
#If an item becomes obsolete/no longer available, it is often meaningful to keep it in the catalog (along with all the interaction data, which are very useful), and only exclude the item from recommendations. In such a case, use [ReQL filter](https://docs.recombee.com/reql.html) instead of deleting the item completely.
#If an item becomes obsolete/no longer available, it is meaningful to keep it in the catalog (along with all the interaction data, which are very useful), and **only exclude the item from recommendations**. In such a case, use [ReQL filter](https://docs.recombee.com/reql.html) instead of deleting the item completely.
#
class DeleteItem < ApiRequest
attr_reader :item_id
Expand Down
52 changes: 52 additions & 0 deletions lib/recombee_api_client/api/delete_more_items.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#
# This file is auto-generated, do not edit
#

module RecombeeApiClient
require_relative 'request'
require_relative '../errors'

##
#Delete all the items that pass the filter.
#
#If an item becomes obsolete/no longer available, it is meaningful to **keep it in the catalog** (along with all the interaction data, which are very useful), and **only exclude the item from recommendations**. In such a case, use [ReQL filter](https://docs.recombee.com/reql.html) instead of deleting the item completely.
class DeleteMoreItems < ApiRequest
attr_reader :filter
attr_accessor :timeout
attr_accessor :ensure_https

##
# * *Required arguments*
# - +filter+ -> A [ReQL](https://docs.recombee.com/reql.html) expression, which return `true` for the items that shall be updated.
#
def initialize(filter)
@filter = filter
@timeout = 1000
@ensure_https = false
end

# HTTP method
def method
:delete
end

# Values of body parameters as a Hash
def body_parameters
p = Hash.new
p['filter'] = @filter
p
end

# Values of query parameters as a Hash.
# name of parameter => value of the parameter
def query_parameters
params = {}
params
end

# Relative path to the endpoint
def path
"/{databaseId}/more-items/"
end
end
end
2 changes: 1 addition & 1 deletion lib/recombee_api_client/api/delete_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class DeleteUser < ApiRequest

##
# * *Required arguments*
# - +user_id+ -> ID of the user to be added.
# - +user_id+ -> ID of the user to be deleted.
#
def initialize(user_id)
@user_id = user_id
Expand Down
159 changes: 0 additions & 159 deletions lib/recombee_api_client/api/item_based_recommendation.rb

This file was deleted.

2 changes: 1 addition & 1 deletion lib/recombee_api_client/api/recommend_items_to_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class RecommendItemsToUser < ApiRequest
#
# - +minRelevance+ -> **Expert option** Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevance, and may return less than *count* items when there is not enough data to fulfill it.
#
# - +rotationRate+ -> **Expert option** If your users browse the system in real-time, it may easily happen that you wish to offer them recommendations multiple times. Here comes the question: how much should the recommendations change? Should they remain the same, or should they rotate? Recombee API allows you to control this per-request in backward fashion. You may penalize an item for being recommended in the near past. For the specific user, `rotationRate=1` means maximal rotation, `rotationRate=0` means absolutely no rotation. You may also use, for example `rotationRate=0.2` for only slight rotation of recommended items. Default: `0.1`.
# - +rotationRate+ -> **Expert option** If your users browse the system in real-time, it may easily happen that you wish to offer them recommendations multiple times. Here comes the question: how much should the recommendations change? Should they remain the same, or should they rotate? Recombee API allows you to control this per-request in backward fashion. You may penalize an item for being recommended in the near past. For the specific user, `rotationRate=1` means maximal rotation, `rotationRate=0` means absolutely no rotation. You may also use, for example `rotationRate=0.2` for only slight rotation of recommended items. Default: `0`.
#
# - +rotationTime+ -> **Expert option** Taking *rotationRate* into account, specifies how long time it takes to an item to recover from the penalization. For example, `rotationTime=7200.0` means that items recommended less than 2 hours ago are penalized. Default: `7200.0`.
#
Expand Down
Loading

0 comments on commit 12b77c9

Please sign in to comment.