Skip to content

Commit f72eb11

Browse files
committed
Timestamp is now optional parameter when deleting an interaction. cascadeCreate and scenario parameters for recommendations.
1 parent 16d666c commit f72eb11

File tree

9 files changed

+112
-34
lines changed

9 files changed

+112
-34
lines changed

lib/recombee_api_client/api/delete_bookmark.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ class DeleteBookmark < ApiRequest
1717
# * *Required arguments*
1818
# - +user_id+ -> ID of the user who made the bookmark.
1919
# - +item_id+ -> ID of the item of which was bookmarked.
20-
# - +timestamp+ -> Unix timestamp of the bookmark.
2120
#
22-
def initialize(user_id, item_id, timestamp)
21+
# * *Optional arguments (given as hash optional)*
22+
# - +timestamp+ -> Unix timestamp of the bookmark. If the `timestamp` is omitted, then all the bookmarks with given `userId` and `itemId` are deleted.
23+
#
24+
def initialize(user_id, item_id, optional = {})
2325
@user_id = user_id
2426
@item_id = item_id
25-
@timestamp = timestamp
27+
@timestamp = optional['timestamp']
28+
@optional = optional
2629
@timeout = 1000
30+
@optional.each do |par, _|
31+
fail UnknownOptionalParameter.new(par) unless ["timestamp"].include? par
32+
end
2733
end
2834

2935
# HTTP method
@@ -43,7 +49,7 @@ def query_parameters
4349
params = {}
4450
params['userId'] = @user_id
4551
params['itemId'] = @item_id
46-
params['timestamp'] = @timestamp
52+
params['timestamp'] = @optional['timestamp'] if @optional['timestamp']
4753
params
4854
end
4955

@@ -54,7 +60,11 @@ def basic_path
5460

5561
# Relative path to the endpoint including query parameters
5662
def path
57-
p = "/{databaseId}/bookmarks/?userId=#{@user_id}&itemId=#{@item_id}&timestamp=#{@timestamp}"
63+
p = "/{databaseId}/bookmarks/?userId=#{@user_id}&itemId=#{@item_id}"
64+
if @optional.include? 'timestamp'
65+
p += (p.include? '?') ? '&' : '?'
66+
p += "timestamp=#{@optional['timestamp']}"
67+
end
5868
p
5969
end
6070
end

lib/recombee_api_client/api/delete_cart_addition.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ class DeleteCartAddition < ApiRequest
1717
# * *Required arguments*
1818
# - +user_id+ -> ID of the user who made the cart addition.
1919
# - +item_id+ -> ID of the item of which was added to cart.
20-
# - +timestamp+ -> Unix timestamp of the cart addition.
2120
#
22-
def initialize(user_id, item_id, timestamp)
21+
# * *Optional arguments (given as hash optional)*
22+
# - +timestamp+ -> Unix timestamp of the cart addition. If the `timestamp` is omitted, then all the cart additions with given `userId` and `itemId` are deleted.
23+
#
24+
def initialize(user_id, item_id, optional = {})
2325
@user_id = user_id
2426
@item_id = item_id
25-
@timestamp = timestamp
27+
@timestamp = optional['timestamp']
28+
@optional = optional
2629
@timeout = 1000
30+
@optional.each do |par, _|
31+
fail UnknownOptionalParameter.new(par) unless ["timestamp"].include? par
32+
end
2733
end
2834

2935
# HTTP method
@@ -43,7 +49,7 @@ def query_parameters
4349
params = {}
4450
params['userId'] = @user_id
4551
params['itemId'] = @item_id
46-
params['timestamp'] = @timestamp
52+
params['timestamp'] = @optional['timestamp'] if @optional['timestamp']
4753
params
4854
end
4955

@@ -54,7 +60,11 @@ def basic_path
5460

5561
# Relative path to the endpoint including query parameters
5662
def path
57-
p = "/{databaseId}/cartadditions/?userId=#{@user_id}&itemId=#{@item_id}&timestamp=#{@timestamp}"
63+
p = "/{databaseId}/cartadditions/?userId=#{@user_id}&itemId=#{@item_id}"
64+
if @optional.include? 'timestamp'
65+
p += (p.include? '?') ? '&' : '?'
66+
p += "timestamp=#{@optional['timestamp']}"
67+
end
5868
p
5969
end
6070
end

lib/recombee_api_client/api/delete_detail_view.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ class DeleteDetailView < ApiRequest
1717
# * *Required arguments*
1818
# - +user_id+ -> ID of the user who made the detail view.
1919
# - +item_id+ -> ID of the item of which the details were viewed.
20-
# - +timestamp+ -> Unix timestamp of the detail view.
2120
#
22-
def initialize(user_id, item_id, timestamp)
21+
# * *Optional arguments (given as hash optional)*
22+
# - +timestamp+ -> Unix timestamp of the detail view. If the `timestamp` is omitted, then all the detail views with given `userId` and `itemId` are deleted.
23+
#
24+
def initialize(user_id, item_id, optional = {})
2325
@user_id = user_id
2426
@item_id = item_id
25-
@timestamp = timestamp
27+
@timestamp = optional['timestamp']
28+
@optional = optional
2629
@timeout = 1000
30+
@optional.each do |par, _|
31+
fail UnknownOptionalParameter.new(par) unless ["timestamp"].include? par
32+
end
2733
end
2834

2935
# HTTP method
@@ -43,7 +49,7 @@ def query_parameters
4349
params = {}
4450
params['userId'] = @user_id
4551
params['itemId'] = @item_id
46-
params['timestamp'] = @timestamp
52+
params['timestamp'] = @optional['timestamp'] if @optional['timestamp']
4753
params
4854
end
4955

@@ -54,7 +60,11 @@ def basic_path
5460

5561
# Relative path to the endpoint including query parameters
5662
def path
57-
p = "/{databaseId}/detailviews/?userId=#{@user_id}&itemId=#{@item_id}&timestamp=#{@timestamp}"
63+
p = "/{databaseId}/detailviews/?userId=#{@user_id}&itemId=#{@item_id}"
64+
if @optional.include? 'timestamp'
65+
p += (p.include? '?') ? '&' : '?'
66+
p += "timestamp=#{@optional['timestamp']}"
67+
end
5868
p
5969
end
6070
end

lib/recombee_api_client/api/delete_purchase.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ class DeletePurchase < ApiRequest
1717
# * *Required arguments*
1818
# - +user_id+ -> ID of the user who made the purchase.
1919
# - +item_id+ -> ID of the item of which was purchased.
20-
# - +timestamp+ -> Unix timestamp of the purchase.
2120
#
22-
def initialize(user_id, item_id, timestamp)
21+
# * *Optional arguments (given as hash optional)*
22+
# - +timestamp+ -> Unix timestamp of the purchase. If the `timestamp` is omitted, then all the purchases with given `userId` and `itemId` are deleted.
23+
#
24+
def initialize(user_id, item_id, optional = {})
2325
@user_id = user_id
2426
@item_id = item_id
25-
@timestamp = timestamp
27+
@timestamp = optional['timestamp']
28+
@optional = optional
2629
@timeout = 1000
30+
@optional.each do |par, _|
31+
fail UnknownOptionalParameter.new(par) unless ["timestamp"].include? par
32+
end
2733
end
2834

2935
# HTTP method
@@ -43,7 +49,7 @@ def query_parameters
4349
params = {}
4450
params['userId'] = @user_id
4551
params['itemId'] = @item_id
46-
params['timestamp'] = @timestamp
52+
params['timestamp'] = @optional['timestamp'] if @optional['timestamp']
4753
params
4854
end
4955

@@ -54,7 +60,11 @@ def basic_path
5460

5561
# Relative path to the endpoint including query parameters
5662
def path
57-
p = "/{databaseId}/purchases/?userId=#{@user_id}&itemId=#{@item_id}&timestamp=#{@timestamp}"
63+
p = "/{databaseId}/purchases/?userId=#{@user_id}&itemId=#{@item_id}"
64+
if @optional.include? 'timestamp'
65+
p += (p.include? '?') ? '&' : '?'
66+
p += "timestamp=#{@optional['timestamp']}"
67+
end
5868
p
5969
end
6070
end

lib/recombee_api_client/api/delete_rating.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ class DeleteRating < ApiRequest
1717
# * *Required arguments*
1818
# - +user_id+ -> ID of the user who rated the item.
1919
# - +item_id+ -> ID of the item which was rated.
20-
# - +timestamp+ -> Unix timestamp of the rating.
2120
#
22-
def initialize(user_id, item_id, timestamp)
21+
# * *Optional arguments (given as hash optional)*
22+
# - +timestamp+ -> Unix timestamp of the rating. If the `timestamp` is omitted, then all the ratings with given `userId` and `itemId` are deleted.
23+
#
24+
def initialize(user_id, item_id, optional = {})
2325
@user_id = user_id
2426
@item_id = item_id
25-
@timestamp = timestamp
27+
@timestamp = optional['timestamp']
28+
@optional = optional
2629
@timeout = 1000
30+
@optional.each do |par, _|
31+
fail UnknownOptionalParameter.new(par) unless ["timestamp"].include? par
32+
end
2733
end
2834

2935
# HTTP method
@@ -43,7 +49,7 @@ def query_parameters
4349
params = {}
4450
params['userId'] = @user_id
4551
params['itemId'] = @item_id
46-
params['timestamp'] = @timestamp
52+
params['timestamp'] = @optional['timestamp'] if @optional['timestamp']
4753
params
4854
end
4955

@@ -54,7 +60,11 @@ def basic_path
5460

5561
# Relative path to the endpoint including query parameters
5662
def path
57-
p = "/{databaseId}/ratings/?userId=#{@user_id}&itemId=#{@item_id}&timestamp=#{@timestamp}"
63+
p = "/{databaseId}/ratings/?userId=#{@user_id}&itemId=#{@item_id}"
64+
if @optional.include? 'timestamp'
65+
p += (p.include? '?') ? '&' : '?'
66+
p += "timestamp=#{@optional['timestamp']}"
67+
end
5868
p
5969
end
6070
end

lib/recombee_api_client/api/item_based_recommendation.rb

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module RecombeeApiClient
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
#
1212
class ItemBasedRecommendation < ApiRequest
13-
attr_reader :item_id, :count, :target_user_id, :user_impact, :filter, :booster, :allow_nonexistent, :diversity, :min_relevance, :rotation_rate, :rotation_time
13+
attr_reader :item_id, :count, :target_user_id, :user_impact, :filter, :booster, :allow_nonexistent, :cascade_create, :scenario, :diversity, :min_relevance, :rotation_rate, :rotation_time
1414
attr_accessor :timeout
1515

1616
##
@@ -24,7 +24,9 @@ class ItemBasedRecommendation < ApiRequest
2424
#
2525
# - +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.
2626
# - +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.
27-
# - +allowNonexistent+ -> If the user does not exist in the database, returns a list of non-personalized recommendations instead of causing HTTP 404 error.
27+
# - +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.
28+
# - +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.
29+
# - +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.
2830
# - +diversity+ -> **Expert option** Real number from [0.0, 1.0] which determines how much mutually dissimilar should the recommended items be. The default value is 0.0, i.e., no diversification. Value 1.0 means maximal diversification.
2931
#
3032
# - +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 qualit, and may return less than *count* items when there is not enough data to fulfill it.
@@ -42,14 +44,16 @@ def initialize(item_id, count, optional = {})
4244
@filter = optional['filter']
4345
@booster = optional['booster']
4446
@allow_nonexistent = optional['allowNonexistent']
47+
@cascade_create = optional['cascadeCreate']
48+
@scenario = optional['scenario']
4549
@diversity = optional['diversity']
4650
@min_relevance = optional['minRelevance']
4751
@rotation_rate = optional['rotationRate']
4852
@rotation_time = optional['rotationTime']
4953
@optional = optional
5054
@timeout = 3000
5155
@optional.each do |par, _|
52-
fail UnknownOptionalParameter.new(par) unless ["targetUserId","userImpact","filter","booster","allowNonexistent","diversity","minRelevance","rotationRate","rotationTime"].include? par
56+
fail UnknownOptionalParameter.new(par) unless ["targetUserId","userImpact","filter","booster","allowNonexistent","cascadeCreate","scenario","diversity","minRelevance","rotationRate","rotationTime"].include? par
5357
end
5458
end
5559

@@ -74,6 +78,8 @@ def query_parameters
7478
params['filter'] = @optional['filter'] if @optional['filter']
7579
params['booster'] = @optional['booster'] if @optional['booster']
7680
params['allowNonexistent'] = @optional['allowNonexistent'] if @optional['allowNonexistent']
81+
params['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
82+
params['scenario'] = @optional['scenario'] if @optional['scenario']
7783
params['diversity'] = @optional['diversity'] if @optional['diversity']
7884
params['minRelevance'] = @optional['minRelevance'] if @optional['minRelevance']
7985
params['rotationRate'] = @optional['rotationRate'] if @optional['rotationRate']
@@ -109,6 +115,14 @@ def path
109115
p += (p.include? '?') ? '&' : '?'
110116
p += "allowNonexistent=#{@optional['allowNonexistent']}"
111117
end
118+
if @optional.include? 'cascadeCreate'
119+
p += (p.include? '?') ? '&' : '?'
120+
p += "cascadeCreate=#{@optional['cascadeCreate']}"
121+
end
122+
if @optional.include? 'scenario'
123+
p += (p.include? '?') ? '&' : '?'
124+
p += "scenario=#{@optional['scenario']}"
125+
end
112126
if @optional.include? 'diversity'
113127
p += (p.include? '?') ? '&' : '?'
114128
p += "diversity=#{@optional['diversity']}"

lib/recombee_api_client/api/reset_database.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class ResetDatabase < ApiRequest
1616
##
1717
#
1818
def initialize()
19-
@timeout = 3000
19+
@timeout = 5000
2020
end
2121

2222
# HTTP method

lib/recombee_api_client/api/user_based_recommendation.rb

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module RecombeeApiClient
1010
#Based on user's past interactions (purchases, ratings, etc.) with the items, recommends top-N items that are most likely to be of high value for a given user.
1111
#
1212
class UserBasedRecommendation < ApiRequest
13-
attr_reader :user_id, :count, :filter, :booster, :allow_nonexistent, :diversity, :min_relevance, :rotation_rate, :rotation_time
13+
attr_reader :user_id, :count, :filter, :booster, :allow_nonexistent, :cascade_create, :scenario, :diversity, :min_relevance, :rotation_rate, :rotation_time
1414
attr_accessor :timeout
1515

1616
##
@@ -21,7 +21,9 @@ class UserBasedRecommendation < ApiRequest
2121
# * *Optional arguments (given as hash optional)*
2222
# - +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.
2323
# - +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.
24-
# - +allowNonexistent+ -> If the user does not exist in the database, returns a list of non-personalized recommendations instead of causing HTTP 404 error.
24+
# - +allowNonexistent+ -> If the user does not exist in the database, returns a list of non-personalized recommendations instead of causing HTTP 404 error. It doesn't create the user in the database.
25+
# - +cascadeCreate+ -> If the user does not exist in the database, returns a list of non-personalized recommendations and creates the user in the database. This allows for example rotations in the following recommendations for that user, as the user will be already known to the system.
26+
# - +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.
2527
# - +diversity+ -> **Expert option** Real number from [0.0, 1.0] which determines how much mutually dissimilar should the recommended items be. The default value is 0.0, i.e., no diversification. Value 1.0 means maximal diversification.
2628
#
2729
# - +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 qualit, and may return less than *count* items when there is not enough data to fulfill it.
@@ -37,14 +39,16 @@ def initialize(user_id, count, optional = {})
3739
@filter = optional['filter']
3840
@booster = optional['booster']
3941
@allow_nonexistent = optional['allowNonexistent']
42+
@cascade_create = optional['cascadeCreate']
43+
@scenario = optional['scenario']
4044
@diversity = optional['diversity']
4145
@min_relevance = optional['minRelevance']
4246
@rotation_rate = optional['rotationRate']
4347
@rotation_time = optional['rotationTime']
4448
@optional = optional
4549
@timeout = 3000
4650
@optional.each do |par, _|
47-
fail UnknownOptionalParameter.new(par) unless ["filter","booster","allowNonexistent","diversity","minRelevance","rotationRate","rotationTime"].include? par
51+
fail UnknownOptionalParameter.new(par) unless ["filter","booster","allowNonexistent","cascadeCreate","scenario","diversity","minRelevance","rotationRate","rotationTime"].include? par
4852
end
4953
end
5054

@@ -67,6 +71,8 @@ def query_parameters
6771
params['filter'] = @optional['filter'] if @optional['filter']
6872
params['booster'] = @optional['booster'] if @optional['booster']
6973
params['allowNonexistent'] = @optional['allowNonexistent'] if @optional['allowNonexistent']
74+
params['cascadeCreate'] = @optional['cascadeCreate'] if @optional['cascadeCreate']
75+
params['scenario'] = @optional['scenario'] if @optional['scenario']
7076
params['diversity'] = @optional['diversity'] if @optional['diversity']
7177
params['minRelevance'] = @optional['minRelevance'] if @optional['minRelevance']
7278
params['rotationRate'] = @optional['rotationRate'] if @optional['rotationRate']
@@ -94,6 +100,14 @@ def path
94100
p += (p.include? '?') ? '&' : '?'
95101
p += "allowNonexistent=#{@optional['allowNonexistent']}"
96102
end
103+
if @optional.include? 'cascadeCreate'
104+
p += (p.include? '?') ? '&' : '?'
105+
p += "cascadeCreate=#{@optional['cascadeCreate']}"
106+
end
107+
if @optional.include? 'scenario'
108+
p += (p.include? '?') ? '&' : '?'
109+
p += "scenario=#{@optional['scenario']}"
110+
end
97111
if @optional.include? 'diversity'
98112
p += (p.include? '?') ? '&' : '?'
99113
p += "diversity=#{@optional['diversity']}"

spec/api/delete_interaction.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
include_context 'set interactions'
77

88
it 'does not fail with existing entity id' do
9-
delete_req = described_class.new('user', 'item', 0)
9+
delete_req = described_class.new('user', 'item', 'timestamp' => 0)
1010
expect { @client.send(delete_req) }.not_to raise_exception
1111
end
1212

1313
it 'really deletes the interaction' do
14-
delete_req = described_class.new('user', 'item', 0)
14+
delete_req = described_class.new('user', 'item')
1515
expect { @client.send(delete_req) }.not_to raise_exception
1616
expect { @client.send(delete_req) }.to raise_exception { |exception|
1717
expect(exception).to be_a(RecombeeApiClient::ResponseError)

0 commit comments

Comments
 (0)