Skip to content

Commit 3ad7396

Browse files
committed
Support returnProperties and includedProperties parameters of ListItems and ListUsers. Send User-Agent HTTP header.
1 parent 6732701 commit 3ad7396

33 files changed

+229
-89
lines changed

lib/recombee_api_client.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class RecombeeClient
1818
include HTTParty
1919

2020
BATCH_MAX_SIZE = 10000
21+
USER_AGENT = {'User-Agent' => 'recombee-ruby-api-client/1.4.0'}
2122

2223
##
2324
# - +account+ -> Name of your account at Recombee
@@ -63,21 +64,23 @@ def send(request)
6364
private
6465

6566
def put(request, uri, timeout)
66-
response = self.class.put(uri, timeout: timeout)
67+
response = self.class.put(uri, body: request.body_parameters.to_json,
68+
headers: { 'Content-Type' => 'application/json' }.merge(USER_AGENT),
69+
timeout: timeout)
6770
check_errors(response, request)
6871
response.body
6972
end
7073

7174
def get(request, uri, timeout)
72-
response = self.class.get(uri, timeout: timeout)
75+
response = self.class.get(uri, timeout: timeout, headers: USER_AGENT)
7376
check_errors(response, request)
7477
JSON.parse(response.body)
7578
end
7679

7780
def post(request, uri, timeout)
7881
# pass arguments in body
7982
response = self.class.post(uri, body: request.body_parameters.to_json,
80-
headers: { 'Content-Type' => 'application/json' },
83+
headers: { 'Content-Type' => 'application/json' }.merge(USER_AGENT),
8184
timeout: timeout)
8285
check_errors(response, request)
8386
begin
@@ -88,7 +91,7 @@ def post(request, uri, timeout)
8891
end
8992

9093
def delete(request, uri, timeout)
91-
response = self.class.delete(uri, timeout: timeout)
94+
response = self.class.delete(uri, timeout: timeout, headers: USER_AGENT)
9295
check_errors(response, request)
9396
response.body
9497
end

lib/recombee_api_client/api/add_bookmark.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ def body_parameters
4646
p = Hash.new
4747
p['userId'] = @user_id
4848
p['itemId'] = @item_id
49-
p['timestamp'] = @optional['timestamp'] if @optional['timestamp']
50-
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
49+
p['timestamp'] = @optional['timestamp'] if @optional.include? 'timestamp'
50+
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional.include? 'cascadeCreate'
5151
p
5252
end
5353

lib/recombee_api_client/api/add_cart_addition.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ def body_parameters
4646
p = Hash.new
4747
p['userId'] = @user_id
4848
p['itemId'] = @item_id
49-
p['timestamp'] = @optional['timestamp'] if @optional['timestamp']
50-
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
49+
p['timestamp'] = @optional['timestamp'] if @optional.include? 'timestamp'
50+
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional.include? 'cascadeCreate'
5151
p
5252
end
5353

lib/recombee_api_client/api/add_detail_view.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ def body_parameters
4848
p = Hash.new
4949
p['userId'] = @user_id
5050
p['itemId'] = @item_id
51-
p['timestamp'] = @optional['timestamp'] if @optional['timestamp']
52-
p['duration'] = @optional['duration'] if @optional['duration']
53-
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
51+
p['timestamp'] = @optional['timestamp'] if @optional.include? 'timestamp'
52+
p['duration'] = @optional['duration'] if @optional.include? 'duration'
53+
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional.include? 'cascadeCreate'
5454
p
5555
end
5656

lib/recombee_api_client/api/add_purchase.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ def body_parameters
4646
p = Hash.new
4747
p['userId'] = @user_id
4848
p['itemId'] = @item_id
49-
p['timestamp'] = @optional['timestamp'] if @optional['timestamp']
50-
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
49+
p['timestamp'] = @optional['timestamp'] if @optional.include? 'timestamp'
50+
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional.include? 'cascadeCreate'
5151
p
5252
end
5353

lib/recombee_api_client/api/add_rating.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ def body_parameters
4949
p['userId'] = @user_id
5050
p['itemId'] = @item_id
5151
p['rating'] = @rating
52-
p['timestamp'] = @optional['timestamp'] if @optional['timestamp']
53-
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
52+
p['timestamp'] = @optional['timestamp'] if @optional.include? 'timestamp'
53+
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional.include? 'cascadeCreate'
5454
p
5555
end
5656

lib/recombee_api_client/api/insert_to_group.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def body_parameters
4646
p = Hash.new
4747
p['itemType'] = @item_type
4848
p['itemId'] = @item_id
49-
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
49+
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional.include? 'cascadeCreate'
5050
p
5151
end
5252

lib/recombee_api_client/api/insert_to_series.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def body_parameters
4949
p['itemType'] = @item_type
5050
p['itemId'] = @item_id
5151
p['time'] = @time
52-
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
52+
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional.include? 'cascadeCreate'
5353
p
5454
end
5555

lib/recombee_api_client/api/item_based_recommendation.rb

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ module RecombeeApiClient
99
##
1010
#Recommends set of items that are somehow related to one given item, *X*. Typical scenario for using item-based recommendation is when user *A* is viewing *X*. Then you may display items to the user that he might be also interested in. Item-recommendation request gives you Top-N such items, optionally taking the target user *A* into account.
1111
#
12+
# It is also possible to use POST HTTP method (for example in case of very long ReQL filter) - query parameters then become body parameters.
13+
#
1214
class ItemBasedRecommendation < ApiRequest
13-
attr_reader :item_id, :count, :target_user_id, :user_impact, :filter, :booster, :allow_nonexistent, :cascade_create, :scenario, :return_properties, :included_properties, :diversity, :min_relevance, :rotation_rate, :rotation_time
15+
attr_reader :item_id, :count, :target_user_id, :user_impact, :filter, :booster, :allow_nonexistent, :cascade_create, :scenario, :return_properties, :included_properties, :diversity, :min_relevance, :rotation_rate, :rotation_time, :expert_settings
1416
attr_accessor :timeout
1517
attr_accessor :ensure_https
1618

1719
##
1820
# * *Required arguments*
19-
# - +item_id+ -> ID of the item recommendations for which are to be generated.
21+
# - +item_id+ -> ID of the item for which the recommendations are to be generated.
2022
# - +count+ -> Number of items to be recommended (N for the top-N recommendation).
2123
#
2224
# * *Optional arguments (given as hash optional)*
@@ -25,15 +27,18 @@ class ItemBasedRecommendation < ApiRequest
2527
#Specifying the *targetUserId* is beneficial because:
2628
#
2729
#* It makes the recommendations personalized
28-
#* Allows calculations of Actions and Conversions in the graphical user interface, as Recombee can pair the user who got recommendations and who afterwards viewed/purchased an item.
30+
#* Allows the calculation of Actions and Conversions in the graphical user interface,
31+
# as Recombee can pair the user who got recommendations and who afterwards viewed/purchased an item.
32+
#
33+
#For the above reasons, we encourage you to set the *targetUserId* even for anonymous/unregistered users (i.e. use their session ID).
2934
#
30-
# - +userImpact+ -> If *targetUserId* parameter is present, the recommendations are biased towards the user given. Using *userImpact*, you may control this bias. For an extreme case of `userImpact=0.0`, the interactions made by the user are not taken into account at all (with the exception of history-based blacklisting), for `userImpact=1.0`, you'll get user-based recommendation. The default value is `0.1`
35+
# - +userImpact+ -> If *targetUserId* parameter is present, the recommendations are biased towards the user given. Using *userImpact*, you may control this bias. For an extreme case of `userImpact=0.0`, the interactions made by the user are not taken into account at all (with the exception of history-based blacklisting), for `userImpact=1.0`, you'll get user-based recommendation. The default value is `0`.
3136
#
3237
# - +filter+ -> Boolean-returning [ReQL](https://docs.recombee.com/reql.html) expression which allows you to filter recommended items based on the values of their attributes.
3338
# - +booster+ -> Number-returning [ReQL](https://docs.recombee.com/reql.html) expression which allows you to boost recommendation rate of some items based on the values of their attributes.
3439
# - +allowNonexistent+ -> Instead of causing HTTP 404 error, returns some (non-personalized) recommendations if either item of given *itemId* or user of given *targetUserId* does not exist in the database. It creates neither of the missing entities in the database.
3540
# - +cascadeCreate+ -> If item of given *itemId* or user of given *targetUserId* doesn't exist in the database, it creates the missing enity/entities and returns some (non-personalized) recommendations. This allows for example rotations in the following recommendations for the user of given *targetUserId*, as the user will be already known to the system.
36-
# - +scenario+ -> Scenario defines a particular application of recommendations. It can be for example "homepage" or "cart". The AI which optimizes models in order to get the best results may optimize different scenarios separately, or even use different models in each of the scenarios.
41+
# - +scenario+ -> Scenario defines a particular application of recommendations. It can be for example "homepage", "cart" or "emailing". You can see each scenario in the UI separately, so you can check how well each application performs. The AI which optimizes models in order to get the best results may optimize different scenarios separately, or even use different models in each of the scenarios.
3742
# - +returnProperties+ -> With `returnProperties=true`, property values of the recommended items are returned along with their IDs in a JSON dictionary. The acquired property values can be used for easy displaying of the recommended items to the user.
3843
#
3944
#Example response:
@@ -80,7 +85,9 @@ class ItemBasedRecommendation < ApiRequest
8085
#
8186
# - +rotationRate+ -> **Expert option** If the *targetUserId* is provided: 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.
8287
#
83-
# - +rotationTime+ -> **Expert option** If the *targetUserId* is provided: Taking *rotationRate* into account, specifies how long time it takes to an item to fully recover from the penalization. For example, `rotationTime=7200.0` means that items recommended more than 2 hours ago are definitely not penalized anymore. Currently, the penalization is linear, so for `rotationTime=7200.0`, an item is still penalized by `0.5` to the user after 1 hour.
88+
# - +rotationTime+ -> **Expert option** If the *targetUserId* is provided: 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.
89+
#
90+
# - +expertSettings+ -> Dictionary of custom options.
8491
#
8592
#
8693
def initialize(item_id, count, optional = {})
@@ -99,43 +106,45 @@ def initialize(item_id, count, optional = {})
99106
@min_relevance = optional['minRelevance']
100107
@rotation_rate = optional['rotationRate']
101108
@rotation_time = optional['rotationTime']
109+
@expert_settings = optional['expertSettings']
102110
@optional = optional
103111
@timeout = 3000
104112
@ensure_https = false
105113
@optional.each do |par, _|
106-
fail UnknownOptionalParameter.new(par) unless ["targetUserId","userImpact","filter","booster","allowNonexistent","cascadeCreate","scenario","returnProperties","includedProperties","diversity","minRelevance","rotationRate","rotationTime"].include? par
114+
fail UnknownOptionalParameter.new(par) unless ["targetUserId","userImpact","filter","booster","allowNonexistent","cascadeCreate","scenario","returnProperties","includedProperties","diversity","minRelevance","rotationRate","rotationTime","expertSettings"].include? par
107115
end
108116
end
109117

110118
# HTTP method
111119
def method
112-
:get
120+
:post
113121
end
114122

115123
# Values of body parameters as a Hash
116124
def body_parameters
117125
p = Hash.new
126+
p['count'] = @count
127+
p['targetUserId'] = @optional['targetUserId'] if @optional.include? 'targetUserId'
128+
p['userImpact'] = @optional['userImpact'] if @optional.include? 'userImpact'
129+
p['filter'] = @optional['filter'] if @optional.include? 'filter'
130+
p['booster'] = @optional['booster'] if @optional.include? 'booster'
131+
p['allowNonexistent'] = @optional['allowNonexistent'] if @optional.include? 'allowNonexistent'
132+
p['cascadeCreate'] = @optional['cascadeCreate'] if @optional.include? 'cascadeCreate'
133+
p['scenario'] = @optional['scenario'] if @optional.include? 'scenario'
134+
p['returnProperties'] = @optional['returnProperties'] if @optional.include? 'returnProperties'
135+
p['includedProperties'] = @optional['includedProperties'] if @optional.include? 'includedProperties'
136+
p['diversity'] = @optional['diversity'] if @optional.include? 'diversity'
137+
p['minRelevance'] = @optional['minRelevance'] if @optional.include? 'minRelevance'
138+
p['rotationRate'] = @optional['rotationRate'] if @optional.include? 'rotationRate'
139+
p['rotationTime'] = @optional['rotationTime'] if @optional.include? 'rotationTime'
140+
p['expertSettings'] = @optional['expertSettings'] if @optional.include? 'expertSettings'
118141
p
119142
end
120143

121144
# Values of query parameters as a Hash.
122145
# name of parameter => value of the parameter
123146
def query_parameters
124147
params = {}
125-
params['count'] = @count
126-
params['targetUserId'] = @optional['targetUserId'] if @optional['targetUserId']
127-
params['userImpact'] = @optional['userImpact'] if @optional['userImpact']
128-
params['filter'] = @optional['filter'] if @optional['filter']
129-
params['booster'] = @optional['booster'] if @optional['booster']
130-
params['allowNonexistent'] = @optional['allowNonexistent'] if @optional['allowNonexistent']
131-
params['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
132-
params['scenario'] = @optional['scenario'] if @optional['scenario']
133-
params['returnProperties'] = @optional['returnProperties'] if @optional['returnProperties']
134-
params['includedProperties'] = @optional['includedProperties'] if @optional['includedProperties']
135-
params['diversity'] = @optional['diversity'] if @optional['diversity']
136-
params['minRelevance'] = @optional['minRelevance'] if @optional['minRelevance']
137-
params['rotationRate'] = @optional['rotationRate'] if @optional['rotationRate']
138-
params['rotationTime'] = @optional['rotationTime'] if @optional['rotationTime']
139148
params
140149
end
141150

lib/recombee_api_client/api/list_groups.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class ListGroups < ApiRequest
1616
##
1717
#
1818
def initialize()
19-
@timeout = 30000
19+
@timeout = 239000
2020
@ensure_https = false
2121
end
2222

0 commit comments

Comments
 (0)